bugfix> javascript > 投稿

使っています grid-template-columns: repeat(auto-fit, 250px) グリッドアイテムを保持する 250px 幅は広いですが、画面の幅に応じて行アイテムの数を自動的に調整します。アイテムにカーソルを合わせると、兄弟のスペースを少し取って拡大し、兄弟が縮小するようにします。沿って console.log() 、見つけた nextElementSibling 使用できます。だから私は次のようなことを考えています-

function expand(card){
    card.setAttribute("style","width: 300px;");
    card.nextElementSibling.setAttribute("style","width: 200px");
}

function restore(card){
    card.setAttribute("style","width: 250px;");
    card.nextElementSibling.setAttribute("style","width: 250px");
}

コーナーアイテムを個別に管理する必要があるため、これはかなり悪いようです(おそらく!)。したがって、現在の連続アイテム数を知る必要があります。また、カードにカーソルを合わせると、カードは拡張されますが、 repeat(auto-fit,250px) 、個々のセルが固定されたままであるため、カードはその兄弟と交差します( 250px )。 どうすれば問題を解決できますか?または、より良い提案された解決策はありますか? ここに 私のgitリポジトリです。

編集1- 私の問題を明確にするために:

  • コーナーアイテムの管理方法、つまり、右コーナーのアイテムの場合、前の兄弟を縮小します。次ではありません。
  • セルは固定されたままです。つまり、拡大するアイテムは縮小するアイテムの境界を遮ります-
  • になります

    だから、によって引き起こされるこの行動に対処する方法 auto-fit,250px

    回答 1 件
    • 私は正直にそれを使用してそれを解決しようとしました grid-template-columns: repeat(auto-fit, minmax(250px,auto)); 子要素のサイズは異なりますが、不安定すぎてそのように機能しません。しかし、私は思いません grid このタスクには必須です。これを解決する方法を理解する最も簡単な方法-古き良きJavaScript(+ jQuery)と flex 。正しい方法は、ホバーされた要素の最も近い兄弟だけでなく、単一の行のすべての要素のサイズを変更することです。任意の画面サイズでお試しください。

      $(document).ready(function() {
        /* defines main digits */
        let boxWidth = $('#box').innerWidth();
        let itemOuterWidth = $('.item').outerWidth(true);
        let itemInnerWidth = $('.item').innerWidth();
        SetSeparators(boxWidth, itemOuterWidth);
        /* refresh main digits ater page resize */
        $(window).resize(function() {
          $('.item').css({
            "flex": ""
          });
          boxWidth = $('#box').innerWidth();
          itemOuterWidth = $('.item').outerWidth(true);
          itemInnerWidth = $('.item').innerWidth();
          SetSeparators(boxWidth, itemOuterWidth);
        });
        $('#box').on('mouseover', '.item', function(e) {
          GetElementsPosition($(this).index('.item'), $(this), boxWidth, itemOuterWidth, itemInnerWidth);
        });
        $('#box').on('mouseleave', '.item', function(e) {
          $('.item').css({
            "flex": ""
          });
        });
      });
      /* set separator elemet to avoid blocks to jump from row to row while resizing */
      function SetSeparators(boxWidth, itemOuterWidth) {
        $('.separator').remove();
        let countRowItems = Math.floor(boxWidth / itemOuterWidth);
        $('<div class="separator"></div>').insertBefore('.item:nth-child(' + countRowItems + 'n+1)');
      }
      function GetElementsPosition(index, element, boxWidth, itemOuterWidth, itemInnerWidth) {
        /* calculating row items, column position and row position of a current elemet */
        let countRowItems = Math.floor(boxWidth / itemOuterWidth);
        let colPosition = index % countRowItems;
        let rowPosition = Math.floor(index / countRowItems);
        /* exmanpd size of a hovered element in pixels*/
        let expandSize = 50;
        /* counting number of items in a hovered row */
        let currentRowCounter = 0;
        $('.item').each(function(e) {
          let thisIndex = $(this).index('.item');
          let thisRowPosition = Math.floor(thisIndex / countRowItems);
          if (rowPosition == thisRowPosition) {
            currentRowCounter++;
          }
        });
        /* settting each element widht according to it's position in a list and row */
        $('.item').each(function(e) {
          $(this).css({
            "flex": "0 1 " + itemInnerWidth + "px"
          });
          let thisIndex = $(this).index('.item');
          let thisColPosition = thisIndex % countRowItems;
          let thisRowPosition = Math.floor(thisIndex / countRowItems);
          if ((rowPosition == thisRowPosition) && (colPosition == thisColPosition)) {
            $(this).css({
              "flex": "0 1 " + (itemInnerWidth + expandSize) + "px"
            });
          } else if (rowPosition == thisRowPosition) {
            $(this).css({
              "flex": "0 1 " + (itemInnerWidth - (expandSize / (currentRowCounter - 1))) + "px"
            });
          } else {
            $(this).css({
              "flex": ""
            });
          }
        });
      }
      
      
      * {
        box-sizing: border-box;
      }
      html {
        height: 100%;
      }
      body {
        min-height: 100%;
        margin: 0;
        padding: 0;
      }
      #box {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-start;
        align-items: flex-start;
      }
      .item {
        background: gray;
        flex: 0 1 250px;
        height: 50px;
        transition: all .5s ease;
        margin: 0 15px 15px 15px;
      }
      .separator {
        flex: 0 1 100%;
      }
      
      
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <div id='box'>
        <div class='item'></div>
        <div class='item'></div>
        <div class='item'></div>
        <div class='item'></div>
        <div class='item'></div>
        <div class='item'></div>
        <div class='item'></div>
        <div class='item'></div>
      </div>
      
      

    あなたの答え