如何使用 JavaScript 获取元素的网格坐标?

Ser*_*han 7 javascript css jquery css-grid

假设我有一个 3 列的 CSS 网格。有没有一种方法,使用JavaScript,以获得grid-rowgrid-column自动放置元素?

例子:

console.log($('#test').css('grid-row'), $('#test').css('grid-column'));
// expected output: 2 3 
// actual output: two empty strings
Run Code Online (Sandbox Code Playgroud)
.grid {
  display: grid;
  grid-template-columns: repeat( 3, 1fr);
}
Run Code Online (Sandbox Code Playgroud)
<div class="grid">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div id="test"></div>
  <div></div>
  <div></div>
  <div></div>
</div>
Run Code Online (Sandbox Code Playgroud)

这是示例的 JSFiddle:https ://jsfiddle.net/w4u87d2f/7/

在这个例子中,我可以通过计算元素并知道网格有三列来计算:

grid-column = $('#test').index() % 3 + 1;
grid-row = Math.ceil( $('#test').index() / 3 )
Run Code Online (Sandbox Code Playgroud)

但这仅适用于非常简单的网格,也意味着我必须考虑更改列数的断点。

编辑:这不是Retrieve the position (X,Y) of an HTML element的副本,因为我对像素坐标不感兴趣,但对 CSS-Grid 中的行号和列号不感兴趣。

sor*_*ell 10

上面的答案是一个很好的开始,并且使用了 jQuery。这是一个纯 Javascript 等效项,如果您指定了第一个子元素的网格列(例如在指定月份第一天的日历中),它还实现了“偏移”

function getGridElementsPosition(index) {
  const gridEl = document.getElementById("grid");

  // our indexes are zero-based but gridColumns are 1-based, so subtract 1
  let offset = Number(window.getComputedStyle(gridEl.children[0]).gridColumnStart) - 1; 

  // if we haven't specified the first child's grid column, then there is no offset
  if (isNaN(offset)) {
    offset = 0;
  }
  const colCount = window.getComputedStyle(gridEl).gridTemplateColumns.split(" ").length;

  const rowPosition = Math.floor((index + offset) / colCount);
  const colPosition = (index + offset) % colCount;

  //Return an object with properties row and column
  return { row: rowPosition, column: colPosition };
}

function getNodeIndex(elm) {
  var c = elm.parentNode.children,
    i = 0;
  for (; i < c.length; i++) if (c[i] == elm) return i;
}

function addClickEventsToGridItems() {
  let gridItems = document.getElementsByClassName("grid-item");
  for (let i = 0; i < gridItems.length; i++) {
    gridItems[i].onclick = (e) => {
      let position = getGridElementsPosition(getNodeIndex(e.target));
      console.log(`Node position is row ${position.row}, column ${position.column}`);
    };
  }
}

addClickEventsToGridItems();
Run Code Online (Sandbox Code Playgroud)

这是相应的笔,显示它在具有指定偏移的日历上的操作。

  • 谢谢你的纯JS版本。以前不知道“window.getComputedStyle()”,它确实改变了游戏规则。 (2认同)

Rya*_*son 6

//Add click event for any child div of div = grid
$(document).ready(function(){
    $('.grid').on('click', 'div', function(e){
          GetGridElementsPosition($(this).index()); //Pass in the index of the clicked div
    //Relevant to its siblings, in other words if this is the 5th div in the div = grid
    });
});

function GetGridElementsPosition(index){
    //Get the css attribute grid-template-columns from the css of class grid
    //split on whitespace and get the length, this will give you how many columns
    const colCount = $('.grid').css('grid-template-columns').split(' ').length;

    const rowPosition = Math.floor(index / colCount);
    const colPosition = index % colCount;

    //Return an object with properties row and column
    return { row: rowPosition, column: colPosition } ;
}
Run Code Online (Sandbox Code Playgroud)