【jQueryプラグイン】slickでsetPositionが効かない一因と対応策

Web関連情報・技術

当サイトにはプロモーション・広告が含まれています。

jQuery プラグインのslickは、簡単にスライダーが表示できてとても便利であるが、先日仕事でslickを使った際にちょっとしたトラブルが発生した。

##slickイベント「setPosition」とは

タブやモーダルなど、ページ読み込み時に非表示になっているコンテンツ内でslickをそのまま使うと高さが取得されずにheight: 0pxとなり、領域が潰れて表示されないという問題がある。

この問題を回避するために、slickはsetPositionというイベントを用意している。setPositionは、位置やサイズが変更された時に再取得を行うイベントである。

/* タブをクリックした際に発火
  .tab クリックするタブ
  .slider 対象のスライダー */
$(".tab").on("click", function () {
  $(".slider").slick("setPosition");
});

このイベントによって、タブ切り替えで非表示コンテンツが表示になった時も、要素の高さが取得できるようになる。

しかし、slick対象にsetPositionを指定したにもかかわらず、なぜか効かないという状況が発生した。slickスライダーを含むコンテンツをタブ切り替えすると、コンテンツ内には何も表示されずコンテンツ高さが本来よりも大きくなるという現象だった。

焦って「slick setPosition 効かない」で検索してみても、setPositionイベントを追加するだけで無事解決!(上記の3行を添えて)みたいな記事しかヒットしない。まるで、「setPositionで解決しない」状況が存在しないかのようだ。

とはいえ、setPositionで解決できない状況が実際に目の前で起こっていた。

setPositionが効かない状況および現象

状況と現象を整理すると以下になる。

状況:タブコンテンツとslickする要素の関係が親と曾孫
現象:タブを切り替えると非表示だったコンテンツの高さが大きくなる

当初は、タブコンテンツとslickする要素が親-子ではなく親-曾孫と、階層が深くなっているためにsetPositionが効かないのではないかと疑った。しかし、コンテンツの高さが潰れるどころか逆に大きくなっている点が、単なる「setPosition 効かない」問題ではないように思えた。

setPositionが効かない原因

slickが適用されているスライダー要素をchromeデベロッパーツールで確認すると、CSSのプロパティにdisplay: flex; flex-wrap:wrap;が付与されていた。

flexで折り返しの横並びにしたリストを、そのままslickのスライドコンテンツとして突っ込んでいたため、このようなCSSプロパティが付いていたのだった。

flexとslickの干渉…?flexによる何らかの影響(何?)で、スライダーに謎の余白が生じていたようである。

こうしてflexに対する疑惑が深まったため、スライダー要素からflexプロパティを取り除いた上でsetPositionを適用すると、タブ切り替えで非表示コンテンツが表示されるようになった。無事解決したのはよかったが、それまでに4~5時間ほど費やすことになった。

補足1

slick.cssに記述されている.slick-slider(slick要素に付与されるclass)のプロパティは以下のようになっている。

.slick-slider {
    position: relative;
    display: block;
    box-sizing: border-box;
    ...
}

このdisplay: block;display: flex;に上書きされることで影響が出たと考えられる。ただ、flexのどのような特性が影響してsetPositionが効かないのかは解明できていない。

補足2

display:flex;を付与したスライダー(Sample #1)と付与しないスライダー(Sample #2)、それぞれにsetPositionを適用したサンプルを作成してみた。

Sample #1は、スライダーの高さが取れない「従来の」setPositionが効かない現象で、仕事で遭遇した「コンテンツの高さが大きくなる」現象は再現できなかった。何か別の要因が関わっていたのかもしれない。

まとめ

とりあえず、slickさせる要素にflex関係のCSSプロパティが付いていたら直ちに取りましょう。いや、flex をかけたコンテンツをそのままスライダーにぶち込むにするのは止しましょうと言うべきか。

ネットで解決方法を探っても見つからなかったのは、今までそういう無茶なことをする人が居なかったからでしょうか。

☕コーヒーをおごる

Buy Me A Coffee

このブログについて

コーディングやWeb関連技術の記事と、買い物など日々のメモから成り立っています。 →少しだけ詳しく

広告