こんにちは。きんくまです。
年度末です。3月が終わってしまいます。
みなさまいかがお過ごしでしょうか。
今回は「Vue.jsでもjQuery jScrollPaneプラグインを使いたい。」です。
Vue.jsなど最近のコンポーネント思考のライブラリは、htmlの現在のDOMの状態をJS内部に別で管理していて、データの変更があり、DOMを更新する必要が出てきたときに、差分だけを更新するような仕組みになっているようです。(Virtual DOM)
このときjQueryで独自にDOMをいじると、このVirtual DOMと衝突しちゃうからおかしなことになってしまうというわけです。
なのでjQueryをVue.jsの中で使うときは、DOMの生成はしない方が良いです。
DOMのプロパティを読みとる分には問題ないと思う。たぶん。
あと、影響ない範囲だったら多少のstyleの設定ぐらいはできます。
ただこれはどうしても解決しなきゃいけない場合だけで、基本的には :class でバインディングした方が安全だと思います。
それで本題です。
jScrollPaneというjQueryのプラグインがあります。
>> jScrollPane – cross browser styleable scrollbars with jQuery and CSS
コンテンツがあふれたら、スクロールバーを作って管理してくれるやつです。
これをVue.jsでも使いたいです。
手元のソースだと v2.0.20 でした。
このプラグインは、表示コンテナとコンテンツ部分の間に独自にDOMを生成します。
これだとVue.js的にはプラグインがはさんだDOMのことを知らないので、コンテンツの更新がかかるとおかしなことになってしまいます。
独自生成するところを、JSから取り除いて、手動でVue.jsのhtml部分につけてあげればうまくいきそうです。
JSの修正
オリジナルのソースだと、こんな感じにappend()とかしている部分です。
pane = $('<div class="jspPane" />').css('padding', originalPadding).append(elem.children()); container = $('<div class="jspContainer" />') .css({ 'width': paneWidth + 'px', 'height': paneHeight + 'px' } ).append(pane).appendTo(elem);
これをこんな感じにします。
pane = elem.find('.jspPane').css('padding', originalPadding); container = elem.find('.jspContainer').css({ 'width': paneWidth + 'px', 'height': paneHeight + 'px' });
htmlの修正
html部分がもともとこんな感じになっていたとします。
.container は overflow: hidden を設定する外枠部分で、 .contents が実際にスクロールする部分だと思ってください。
<div class="container"> <div class="contents"> ここにコンテンツが入る </div> </div>
これを下のような感じにしておきます。さきほどJSでDOMの生成してたところを削除したのですが、それをhtml側に手動でつけています。
<div class="container"> <div class="jspContainer"> <div class="jspPane"> <div class="contents"> ここにコンテンツが入る </div> </div> </div> </div>
こうしておくと、Vue.js側も特に問題なく動きました。
実際には、この他にプラグインでスクロールバーのDOMの生成が行われるのですが、コンテンツ部分のDOMとは親子関係が違うところに(隣に)入ります。なので、別にそこは気にしなくても大丈夫そうです。
jQueryのプラグインは便利なものもあるのですが、Virtual DOMとは相性が悪いです。
ただ実際の案件的には使った方が工数的にも短縮できて便利なものもあると思うので、その辺のバランスを見て使ってみるのが良いかと思いました。
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ