15

“css 网格布局” = https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout

有谁知道一种 javascript 方法来计算鼠标当前所在的列/行?

我猜这样的事情是获取鼠标所在单元格的开始,但这仅对相同大小的网格有用。

MouseGridColumn = round(mouseX / ( gridContainerWidth  / gridTotalColumnsNumber ) )
MouseGridRow    = round(mouseY / ( gridContainerHeight / gridTotalRowsNumber    ) )

有没有办法用不相等的细胞来做到这一点?


更新 1 - 添加代码笔

这是一个代码笔,它显示了 3 个不同百分比的列宽 ( grid-template-columns: 25% 50% 25%;)、2 行、一个没有元素的网格单元和一个跨越多行的元素: http: //codepen.io/anon/pen/NbeOXp


更新 2 - 尝试计算鼠标所在的网格单元格。

在这里,我向网格中的每个单元格添加了隐藏元素,以检测鼠标所在的单元格。但是它只返回它所在的当前元素的“自动”。向网格 IMO 添加额外的隐藏元素也很笨拙.

http://codepen.io/anon/pen/gLZBZw提示:使用鼠标悬停在网格上。

4

5 回答 5

3

将事件侦听器添加到网格列的父级。它称为事件委托。您可以event.target在悬停事件中使用 in 并在 for 循环内部比较ev.target.parent element==document.querySelect("#parentElement")[index] Post all ur code html 代码,以便根据需要准确编写它。

于 2016-12-17T13:42:54.923 回答
2

我认为您正在为不同大小的网格寻找解决方案,而网格的想法是它们始终具有相同的大小(totalWidth/gridNumber)。只有元素可能会溢出 1、2、5 或更多网格。我做了一个小对象来检测网格数的变化,如果我误解了什么,请在评论中解释。

http://codepen.io/devrafalko/pen/bBOQbo?editors=1011

gridDetect = {
  gridNum:12,
  currentGrid:null,
  callback:null,
  initGridDetect: function(fun){
    var b = this.detectGrid.bind(this);
    document.addEventListener('mousemove',b);
    this.callback = fun;
  },
  detectGrid: function(event){
    var w = document.body.clientWidth;
    var mouse = event.clientX;
    var limitMouse = mouse > w ? w:mouse;
    var getGridNumber = Math.floor(limitMouse/(w/this.gridNum));
    if(this.currentGrid!==getGridNumber){
      this.currentGrid = getGridNumber;
      this.callback(getGridNumber);
    }
  }
}


gridDetect.initGridDetect(function(grid){
  console.log(grid);
  //it's called when the grid is about change
  //do what you want here with grid argument
});

于 2016-12-17T15:05:52.283 回答
1

在这里,我使用一些可以帮助您的东西,使用.getComputedStyle并获取网格的行和列(.gridTemplateRows.gridTemplateColumns)的已计算值,这会将其保存在一个数组中,您可以根据需要对其进行迭代

https://codepen.io/leirbagabo/pen/MWoLYKz

于 2021-11-08T01:28:38.170 回答
0

将带有自定义标记或类的空元素添加到网格的顶部和左侧边缘,使用“拉伸”设置它们的样式,然后将宽度/高度相加以获得网格线的坐标。

于 2018-01-12T03:08:15.450 回答
0

您在这里有两个任务:

  1. 检测元件。
  2. 获取元素的列/行。

检测元件

如果为每个网格项添加所需的事件处理程序,则可以避免检测元素。

但是,如果您想添加鼠标悬停(或其他事件处理程序),您可以通过每个网格项添加循环并使用element.getBoundingClientRect()方法。演示(我将添加点击处理程序以避免污染控制台):

var grid = document.querySelector(".grid");

grid.addEventListener("click", function(event) {
  var gridItems = this.children;
  for (var i = 0; i < gridItems.length; i++) {
    var gridItem = gridItems[i];
    var rect = gridItem.getBoundingClientRect();
    var elementDetected = event.clientX >= rect.left
    	&& event.clientX <= rect.right
      && event.clientY >= rect.top
      && event.clientY <= rect.bottom;
    if (elementDetected) {
      console.log(gridItem);
      return;
    }
  }
  
  console.log("no element detected!");
});
.grid {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  grid-gap: 10px;
}

/* styles just for demo */
.grid__item {
  background-color: tomato;
  color: white;
  
  /* styles for centering text */
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="grid">
  <div class="grid__item">One</div>
  <div class="grid__item">Two</div>
  <div class="grid__item">Three</div>
  <div class="grid__item">Four</div>
  <div class="grid__item">Five</div>
  <div class="grid__item">Six</div>
  <div class="grid__item">Seven</div>
  <div class="grid__item">Eight</div>
  <div class="grid__item">Nine</div>
</div>

由于方法的原因,使用 jQuery 会使这项任务更加简单is(":hover")

$(".grid").click(function(event) {
  var hoveredGridItems = $(this).children()
    .filter(function() { return $(this).is(":hover"); });
  
  if (hoveredGridItems.length > 0)
    console.log(hoveredGridItems[0]);
  else
    console.log("no element detected!");
});
.grid {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  grid-gap: 10px;
}

/* styles just for demo */
.grid__item {
  background-color: tomato;
  color: white;
  
  /* styles for centering text */
  display: flex;
  align-items: center;
  justify-content: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="grid">
  <div class="grid__item">One</div>
  <div class="grid__item">Two</div>
  <div class="grid__item">Three</div>
  <div class="grid__item">Four</div>
  <div class="grid__item">Five</div>
  <div class="grid__item">Six</div>
  <div class="grid__item">Seven</div>
  <div class="grid__item">Eight</div>
  <div class="grid__item">Nine</div>
</div>

获取元素的列/行

我会在这里只信任 CSS,因此只有当我们明确设置grid-columngrid-row属性时,获取列和行才能按预期工作。因此,您拥有适用于各种情况的代码行:

// pure JS
var styles = window.getComputedStyle(gritItem);
var gridColumn = styles["grid-column-start"];
var gridRow = styles["grid-row-start"];

// jquery
var gridColumn = $gridItem.css("grid-column");
var gridRow = $griditem.css("grid-row");

如果gridColumn和/或gridRow的值不是auto / auto,那么您肯定知道行和列。

但是在自动放置时检测行和列是非常不可靠的,因为可能的列跨度/行跨度值不同,margins网格项的可能,align-self以及justify-self(元素只能占据部分网格区域的情况)等。

于 2017-08-03T09:57:20.553 回答