web-dev-qa-db-ja.com

CSSフレックスラップイベントを検出する方法

アイテムが入ったフレックスコンテナがあります。フレックスラップイベントを検出する方法ラッピングされた要素にいくつかの新しいcssを適用したい。純粋なcssでラップイベントを検出することは不可能だと思います。しかし、それは非常に強力な機能です!要素が新しい行/行に折り返されると、メディアクエリによってこのブレークポイントイベントを「キャッチ」しようとすることができます。しかし、これはひどいアプローチです。スクリプトで検出することもできますが、あまり良くありません。

Look at the picture

私は非常に驚いていますが、単純な$( "#element")。resize()は、適切なcssを子要素に適用するためにflexコンテナの高さまたは幅の変化を検出するために機能しません。笑。

Jqueryコードのこの例のみが機能することがわかりました jquery event listen on position changed

しかし、それでもひどく。

39
mr.boris

これが解決策の1つです。確認する必要がある他の落とし穴やエッジケースがあるかもしれません。

基本的な考え方は、フレックスitemsをループし、その前の兄弟に対してtopの位置をテストすることです。 topの値が大きい場合(ページのさらに下側)、アイテムはラップされています。

関数detectWrapは、ラップされたDOM要素の配列を返し、必要に応じてスタイル設定に使用できます。

この関数をwindow.resizeとともに使用して、ウィンドウのサイズが変更されたときに折り返しを検出できます。 StackOverflowコードウィンドウはサイズを変更しないため、ここでは機能しません。

以下は CodePen で、画面のサイズ変更に対応しています。

var detectWrap = function(className) {
  
  var wrappedItems = [];
  var prevItem = {};
  var currItem = {};
  var items = document.getElementsByClassName(className);

  for (var i = 0; i < items.length; i++) {
    currItem = items[i].getBoundingClientRect();
    if (prevItem && prevItem.top < currItem.top) {
      wrappedItems.Push(items[i]);
    }
    prevItem = currItem;
  };
  
  return wrappedItems;

}

window.onload = function(event){
  var wrappedItems = detectWrap('item');
  for (var k = 0; k < wrappedItems.length; k++) {
    wrappedItems[k].className = "wrapped";
  }
};
div  {
  display: flex;
  flex-wrap: wrap;
}

div > div {
  flex-grow: 1;
  flex-shrink: 1;
  justify-content: center;
  background-color: #222222;
  padding: 20px 0px;
  color: #FFFFFF;
  font-family: Arial;
  min-width: 300px;
}

div.wrapped {
  background-color: red;
}
<div>
  <div class="item">A</div>
  <div class="item">B</div>
  <div class="item">C</div>
</div>
16
Brett DeWoody

この目的のためにjQueryのスニペットを少し改善しました。

wrapped();

$(window).resize(function() {
   wrapped();
});

function wrapped() {
    var offset_top_prev;

    $('.flex-item').each(function() {
       var offset_top = $(this).offset().top;

      if (offset_top > offset_top_prev) {
         $(this).addClass('wrapped');
      } else if (offset_top == offset_top_prev) {
         $(this).removeClass('wrapped');
      }

      offset_top_prev = offset_top;
   });
}
6
mr.boris

<li>flexに設定された表示を持つ<ul>にラップされているかどうかを判断する際に、同様のアプローチを使用しています。

ul = document.querySelectorAll('.list');

function wrapped(ul) {

    // loops over all found lists on the page - HTML Collection
    for (var i=0; i<ul.length; i++) {

        //Children gets all the list items as another HTML Collection
        li = ul[i].children;

        for (var j=0; j<li.length; j++) {
            // offsetTop will get the vertical distance of the li from the ul.
            // if > 0 it has been wrapped.
            loc = li[j].offsetTop;
            if (loc > 0) {
                li[j].className = 'wrapped';
            } else {
                li[j].className = 'unwrapped';
            }
        }
    }
}
2
sansSpoon