woshidan's blog

あいとゆうきとITと、とっておきの話。

クリックしたら吹き出しが出てくる、JavaScriptのライブラリを書きたかった

仕事でてきとうなライブラリを使おうとしたら、秒速でJavaScript警察の先輩に補導されて反省したので(たしか所要時間76秒)、反省を活かしてライブラリを作ってみようと思いました。

てきとうに使おうとしていたライブラリ

http://osvaldas.info/elegant-css-and-jquery-tooltip-responsive-mobile-friendly

よした方がよいこと、もっと良くできること

  • varを使わずに変数宣言しない
  • use strict使わないのよそう
  • 解放されていないイベントリスナがある
  • 外部で使わない変数を外部で宣言しておく必要は無い
  • ツールチップは同時に1つしか設置しないとは限らないため、同じid要素が複数存在する可能性のあるコーディングは好ましくない
    • 一回表示に使用したテンプレートは、再利用できるようなら、非表示にする度に削除するのではなく、透明にして取っておく方がよい
      • テンプレートキャッシュみたいな

参考に出来そうな事

  • 親要素などの関係をhtmlに作りたくないが、特定の要素からの相対位置で表示させたい場合の手法について
    • body要素等の末尾や先頭等に追加してから、表示したい要素の位置、表示したい要素の親要素の位置、画面幅等を元にleft, top等のプロパティ値を指定してから表示させる
      • faceboxなどはhtmlの先頭に要素を追加して、画面サイズと要素サイズを元にleftの属性値などを設定してから表示させている模様
  • 吹き出しのとんがりをcssで表現しようとした場合、:after :before 疑似要素を使う事で表現できる
    • よくある手法らしい
  • classNameなどのプロパティを受け取って、動作用以外のクラスを追加できるようにしておくと、デザイナーさんに装飾用にはこのクラスをいじってください、という風に渡しやすくてよい
    • その手法が取られていたのは、tipsyだったかもだけど...
    • できたら、動作に必要な装飾の部分以外は普通にクラスに書いておけるように、動作させたい部分を包むようにしておけば良いのかもしれないが...
      • 自分としては、クラス要素に動作指定をかいておくのが楽な気がしてしまう
        • その辺はおかわり案件っぽい

他に調べて分かった事

jquery-uiにも調べたらtooltip.jsがあった。タップではなくて、ホバーっぽいけれど。

とりあえず、そちらはグリグリ手動でカスタムオプション書いてみたら、アイコンも足せるよ、という感じの記事があったりしたので、こちらは簡単にアイコンを足せるよ、 という風にしてみます。

次から提案するときはjquery-ui一通り見た方がいいですね。直しどころもそうですが、 あらかじめ、templateをプロパティとして持ってるとか、どこにどの要素を持たせてるとかの参考に出来そうなので......。

要件を決めてみる

  • タップ(クリック)したらツールチップが出てくる
  • <a>タグでツールチップを設置したい要素を包むようにする
  • 基本となる<div>要素はjavascriptのライブラリ側で持っておく
  • 吹き出しの△をどこに表示するかを設定するようにする
    • △が上下左右のどこか
    • 吹き出しに枠線をつけるか
    • 吹き出しのどこに画像を表示するか(右/左)
  • 吹き出しの△の位置の設定と一緒に、吹き出しのデフォルトの位置も決定するようにする
  • 装飾用のクラスをclassNameのようなプロパティで指定して追加できるようにする
  • iconのサイズはデフォルトは固定サイズ
  • iconのプロパティを指定しなかった場合はアイコン無しで表示する

やってみた

終わらなかった(え).

どちらかというと着手が遅いのが多いので、反省が多い。

成果物。

https://gist.github.com/woshidan/24aba7e583fed7b3c7c6

できたこと

  • タップ(クリック)したらツールチップが出てくる
  • <a>タグでツールチップを設置したい要素を包むようにする
  • 基本となる<div>要素はjavascriptのライブラリ側で持っておく
  • 吹き出しの△を下に表示する
  • 吹き出しの△の位置の設定と一緒に、吹き出しのデフォルトの位置も決定するようにする
    • 固定値のみ
  • iconのサイズはデフォルトは固定サイズ
  • iconのプロパティを指定しなかった場合はアイコン無しで表示する

実装してて思った事

  • 私のGoogle先生は公式ドキュメントを上げてくれない気がする
  • after/before疑似要素を使って、吹き出しの△の部分を表示したりする事がある
  • その際、borderの角っこの部分を利用する
    • ただ、after/before疑似要素はブラウザの側で補完される擬似的なインライン要素であってでDOM要素ではない
    • 動的にプロパティを変換できない
      • 書けない事は無いので、動的に幅とかをいじりたかったらインライン要素を一緒に並べておけば良いのだと思う
  • 複数要素に一括でイベントリスナをつけたいときは、要素を調べる範囲を指定するための親要素を指定する必要があるっぽい
  • 見えなくても、display: noneでなければ挿入されたdivは膨らんでしまう
    • 吹き出しのdivを1つずつ縦横0に縮めたりしてたけど、display: inlineでよかったんや...
    • divが膨らむと相対位置を測って吹き出し置く時の位置がことごとくずれるので困る
      • 表示しているときに微妙にふくれるのも嫌なので、最初は上の探索用親要素に吹き出しのdivを突っ込んでいたが、bodyの末尾に置くようにした
      • ポップアップ用のdivの置き場所、bodyの末尾や先頭が割と多い気がする
  • 属性値でDOM要素を取得に書き慣れた
  • データとあんまり絡みの無いDOM要素ってどうやって整理したら良いのかちょっとよく分からない
    • MVCフレームワーク = データがあって、それと効率よく連携させたい部分を扱うものが多い
    • こういう個別の動作要素はまた違っていて、いままで管理したデータを効率よく表示って言う意味でJS書いたことはあっても、画面動かすぞーって言うのは少ないので標準的な扱い方が分からない
    • JavaScriptは画面を汚すもの、的な気持ちが少し分かったけど、これとそれ(Reactが流行ったりする方面)の流れは別のような...
    • とりあえず、jQUeryUIみたいな感じに仕上げたかった...
      • おかわり案件
  • jQueryUIを一通り眺めよう...
    • たぶん、一番安心して真似して良いお手本の1つだと思う

色の変更がライブラリもどきからできなかったり、上下左右の別や、吹き出し枠線の実装ができなかったので、来週おかわりしたい。

少しテストも書けたら良いな。