欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

如何使用JavaScript找到CSS網格布局元素所在的列

錢衛國2年前8瀏覽0評論

如果我使用grid-template-columns: repeat(3,1fr)將一些HTML元素放入一個3列的網格中,用JavaScript找到一個元素的列是可能的嗎?有些元素還跨越多行,因此元素的索引不一定與其列匹配。

例如:

const myElement = document.querySelector('div:nth-child(5)');

myElement.style.background = '#f00';

const columnIndex = 1; // How do I find this?
console.log('myElement is in column ' + columnIndex);

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 30px;
}

.item,
.item-large {
  padding: 30px;
  background: #3cf;
}

.item-large {
  grid-row: span 2;
}

<div class="grid">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item-large"></div>
  <div class="item">Which column am I in?</div>
  <div class="item-large"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

我在這里做的是遍歷所有元素,每次左邊的位置增加并且小于我的元素位置時,我增加一個計數器來跟蹤該列。

我還修改了這里的代碼片段,使其更具互動性。如果您單擊div的,它會重新選擇并顯示新的列號..

var myElement = document.querySelector('div:nth-child(5)');
const allElements = document.querySelector('.grid').querySelectorAll('div');


//myElement.style.background = '#f00';
myElement.classList.add('item-found');

function showFound() {
  let maxcolpos = -1, colposCount = 0;
  
  for(elem of allElements) {
    let l = elem.getBoundingClientRect().left;
    if (l > maxcolpos) {
      maxcolpos = l;
      if (myElement.getBoundingClientRect().left > l) colposCount ++;
    }
  }

  const columnIndex = colposCount + 1; //zero based, leave +1 if you want 0 based
  myElement.innerText = 'Column = ' + columnIndex;
 }
 
 showFound();
 
 document.querySelector('.grid').addEventListener("click", function(e) {
   if (e.target && !e.target.matches(".grid")) {
     myElement.classList.remove('item-found');
     myElement.innerText = '';
     myElement = e.target;
     myElement.classList.add('item-found');
     showFound();
   }
 });

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 30px;
}

.item,
.item-large {
  padding: 30px;
  background: #3cf;
}

.item-large {
  grid-row: span 2;
}

.item-found {
  background-color: red;
}

<div class="grid">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item-large"></div>
  <div class="item"></div>
  <div class="item-large"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

我知道這個話題很老了,但是對于那些糾結于React和TypeScript的人來說,這可能很有趣。

我制作了一個Dashboard組件,它有一個嵌套的Grid組件,Grid組件有嵌套的Widget組件,Widget組件可以獲得要跨越多少列的屬性——如果沒有給定值,則默認為1。

我不喜歡網格中的最后一項“沒有完成”整個塊。使用這段代碼,網格中的最后一項將延伸到最后一個網格列的末尾。它計算它的當前位置,所以如果你有一個未知網格項目的網格,但仍然想要一個完整的塊,這將派上用場。

不要忘記給JSX中的網格元素賦予ref={gridRef}屬性:-)

const gridRef = useRef<HTMLDivElement>(null);

useLayoutEffect(() => {
    if (!gridRef.current) return;
    const widgets = gridRef.current.children as HTMLCollectionOf<HTMLDivElement>;
    const widgetsLeftPosition: number[] = [];
    const widgetsInLastRow: HTMLDivElement[] = [];

    // add offset from screenedge to array
    for (let i = 0; i < widgets.length; i++) {
        const currentWidgetLeftPosition = widgets[i].getBoundingClientRect().left;
        widgetsLeftPosition.push(currentWidgetLeftPosition);
    }

    // add elements (from rear end) to array, and
    // check if position of current element has same offset as first item, then break 
    // (which results in having only the elements of the last row in the array)
    for (let i = widgetsLeftPosition.length - 1; i >= 0; i--) {
        widgetsInLastRow.push(widgets[i]);
        if (widgetsLeftPosition[i] === widgetsLeftPosition[0]) break;
    }

    // for every element in the last row: check the gridColumnEnd value and
    // take the last character (which is a 'string-integer').
    // parse it to a normal integer, then sum up all integers and return that value
    const columnSpanStart = () => {
        let sum = 0;
        for (let i = 0; i < widgetsInLastRow.length; i++) {
            const spanString = getComputedStyle(widgetsInLastRow[i]).gridColumnEnd;
            sum += parseInt(spanString.slice(-1));
        }
        return sum;
    };

    // finally, use the returned value from columnSpanStart() as gridColumn 'start' value.
    // this will overwrite the default 'grid-column-end' style given by the widget component.
    const lastWidget = widgets[widgets.length - 1];
    lastWidget.style.gridColumn = `${columnSpanStart()} / -1`;
}, []);