Javascript 光标位置到CSS网格位置

Javascript 光标位置到CSS网格位置,javascript,css,css-grid,Javascript,Css,Css Grid,我有一个CSS网格布局,希望得到光标下方的单元格位置。 想象一下下面的例子: 如果我的光标在图像中的星号所在的位置,我正在寻找一个javascript函数,它返回{grid row start:2,grid row end:3,grid column start:5,grid column end:6} 你们中有人知道用本机函数来实现这一点吗?还是我必须自己计算这些值? 谢谢:) 我的示例的代码如下所示: <html> <head> <st

我有一个CSS网格布局,希望得到光标下方的单元格位置。 想象一下下面的例子:

如果我的光标在图像中的星号所在的位置,我正在寻找一个javascript函数,它返回
{grid row start:2,grid row end:3,grid column start:5,grid column end:6}

你们中有人知道用本机函数来实现这一点吗?还是我必须自己计算这些值? 谢谢:)

我的示例的代码如下所示:

<html>
    <head>
        <style>
            .container {
                display: grid;
                grid-gap: 10px;
                background-color: blue;
                grid-template-columns: repeat(6, 1fr);
                height: 400px;
            }
            .container div {
                background-color: green;
            }
            .grid-stack-item {
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="grid-stack-item" data-gs-x="0" data-gs-y="0" data-gs-width="2" data-gs-height="1">
                <div class="grid-stack-item-content">1</div>
            </div>
            <div class="grid-stack-item" data-gs-x="2" data-gs-y="0" data-gs-width="2" data-gs-height="2">
                <div class="grid-stack-item-content">2</div>
            </div>
            <div class="grid-stack-item" data-gs-x="4" data-gs-y="0" data-gs-width="1" data-gs-height="1">
                <div class="grid-stack-item-content" style="overflow: hidden">3</div>
            </div>
            <div class="grid-stack-item" data-gs-x="5" data-gs-y="0" data-gs-width="1" data-gs-height="1">
                <div class="grid-stack-item-content"> 4</div>
            </div>
            <div class="grid-stack-item" data-gs-x="0" data-gs-y="1" data-gs-width="1" data-gs-height="1">
                <div class="grid-stack-item-content">5</div>
            </div>
            <div class="grid-stack-item" data-gs-x="1" data-gs-y="1" data-gs-width="1" data-gs-height="2">
                <div class="grid-stack-item-content">6</div>
            </div>

            <div class="grid-stack-item" data-gs-x="0" data-gs-y="2" data-gs-width="1" data-gs-height="1">
                <div class="grid-stack-item-content">8</div>
            </div>
            <div class="grid-stack-item" data-gs-x="2" data-gs-y="2" data-gs-width="2" data-gs-height="1">
                <div class="grid-stack-item-content">9</div>
            </div>
            <div class="grid-stack-item" data-gs-x="4" data-gs-y="2" data-gs-width="1" data-gs-height="1">
                <div class="grid-stack-item-content">10</div>
            </div>
            <div class="grid-stack-item" data-gs-x="5" data-gs-y="2" data-gs-width="1" data-gs-height="1">
                <div class="grid-stack-item-content">11</div>
            </div>
        </div>
    <script>
        for(let elm of document.getElementsByClassName('grid-stack-item')){
            elm.style['grid-column-start'] = parseInt(elm.getAttribute('data-gs-x')) + 1;
            elm.style['grid-column-end'] = parseInt(elm.getAttribute('data-gs-x')) + parseInt(elm.getAttribute('data-gs-width')) + 1;
            elm.style['grid-row-start'] = parseInt(elm.getAttribute('data-gs-y')) +1 ;
            elm.style['grid-row-end'] = parseInt(elm.getAttribute('data-gs-y')) + parseInt(elm.getAttribute('data-gs-height')) +1;
        }
    </script>
    </body>

</html>


.集装箱{
显示:网格;
栅隙:10px;
背景颜色:蓝色;
网格模板列:重复(6,1fr);
高度:400px;
}
.货柜组{
背景颜色:绿色;
}
.网格堆栈项{
}
1.
2.
3.
4.
5.
6.
8.
9
10
11
for(让document.getElementsByClassName('grid-stack-item')的elm{
elm.style['grid-column-start']=parseInt(elm.getAttribute('data-gs-x'))+1;
elm.style['grid-column-end']=parseInt(elm.getAttribute('data-gs-x'))+parseInt(elm.getAttribute('data-gs-width'))+1;
elm.style['grid-row-start']=parseInt(elm.getAttribute('data-gs-y'))+1;
elm.style['grid-row-end']=parseInt(elm.getAttribute('data-gs-y'))+parseInt(elm.getAttribute('data-gs-height'))+1;
}

您要做的是找出鼠标在哪个元素上,然后从该元素中获取
窗口。getComputedStyle(element)。gridColumnStart
(以及其他)

最简单的方法是向每个
网格堆栈项
元素添加一个
mouseenter
事件

下面是一个粗略的例子:

让currentCellPosition={
“网格行开始”:空,
“网格行结束”:空,
“网格列开始”:空,
“网格列结束”:空
}
Array.from(document.getElementsByClassName(“网格堆栈项”)).forEach(element=>{
元素。addEventListener(“鼠标指针”,()=>{
const style=window.getComputedStyle(元素);
currentCellPosition={
“网格行开始”:style.gridRowStart,
“网格行结束”:style.gridRowEnd,
“网格列开始”:style.gridColumnStart,
“网格列结束”:style.gridColumnEnd
}
})
})
在本例中,
currentCellPosition
将始终具有最近的单元格位置

document.addEventListener(“DOMContentLoaded”,()=>{
const output=document.getElementById(“输出”);
Array.from(document.getElementsByClassName(“cell”)).forEach(element=>{
元素。addEventListener(“鼠标指针”,()=>{
const style=window.getComputedStyle(元素)
output.innerHTML=`
行开始:${style.gridRowStart}
行结束:${style.gridRowEnd}
列开始:${style.gridColumnStart}
列结束:${style.gridColumnEnd}
`;
})
})
});
.container{
边框:2倍纯绿;
显示:网格;
网格模板列:自动;
网格模板行:自动;
高度:200px;
宽度:100%;
}
.a{
网格行开始:1;
网格行端:2;
网格列开始:1;
网格柱端:2;
背景颜色:浅蓝色;
}
.b{
网格行开始:2;
网格行端:3;
网格列开始:1;
网格柱端:3;
背景颜色:橙色;
}
c{
网格行开始:1;
网格行端:2;
网格列开始:2;
网格柱端:3;
背景颜色:浅绿色;
}


这里的想法是在容器之外添加一个额外的网格层。让我们称之为“伪容器”。 此伪容器将处于绝对位置。 它将包含16.6%宽度和高度与网格匹配的列中的元素。 现在我们可以将mouseenter绑定到伪元素

根据@Ian的回答,我做了一把小提琴:

首先创建一些伪元素:

var cont = $(".pseudoContainer");
for (var i = 0; i < 18; i++) {
var newDiv = document.createElement("div");
newDiv.setAttribute('class', 'pseudoitem');
  newDiv.innerHTML = '<div class="pseudoitem-inner"></div>';
  cont.append(newDiv);
}
通过一些样式,您可以看到:

.pseudoContainer{
  position:absolute;
  top:0;
  left:0;
  width: 100%;
  display: block;
  padding: 3px;
   z-index:1;
}
.pseudoitem{
      width: calc(16.6% - 10px);
    height: 126px;
    float: left;
    padding: 5px 5px 5px;
    z-index:2;
}
.pseudoitem-inner{
  background-color: red;
    height: 100%;
    width: 100%;
}
.container{
  z-index:1;
}
.grid-stack-item{
  z-index:3;
}
现在,您只需要细化伪元素创建过程,以便它们包含网格信息

编辑: 现在,您将在MouseOver上获得所需的信息。 这里的方法也是在容器之外添加一个额外的网格层,并设置绝对位置。 不幸的是,这将只适用于这个网格,这真的不是我最好的工作。 在原理上,它与解决方案1相同,但现在这里也使用网格样式

var cont = $(".pseudoContainer");
var y,x;
for (var i = 0; i < 18; i++) {
if(i <= 5) y = 0, x = i;
if(i > 5 && i <= 11) y = 1, x = i - 6;
if(i > 11 && i <= 18) y = 2, x = i - 12;
  var newDiv = document.createElement("div");
  newDiv.setAttribute('class', 'pseudoitem');
  newDiv.setAttribute('data-gs-width', '1');
  newDiv.setAttribute('data-gs-height', '1');
  newDiv.setAttribute('data-gs-x', x);
  newDiv.setAttribute('data-gs-y', y);
  newDiv.innerHTML = '<div class="pseudoitem-inner"></div>';
  cont.append(newDiv);
}

for(let elm of document.getElementsByClassName('pseudoitem')){
            elm.style['grid-column-start'] = parseInt(elm.getAttribute('data-gs-x')) + 1;
            elm.style['grid-column-end'] = parseInt(elm.getAttribute('data-gs-x')) + parseInt(elm.getAttribute('data-gs-width')) + 1;
            elm.style['grid-row-start'] = parseInt(elm.getAttribute('data-gs-y')) +1 ;
            elm.style['grid-row-end'] = parseInt(elm.getAttribute('data-gs-y')) + parseInt(elm.getAttribute('data-gs-height')) +1;
        }


let currentCellPosition = {
  "grid-row-start": null,
  "grid-row-end": null,
  "grid-column-start": null,
  "grid-column-end": null
}

Array.from(document.getElementsByClassName("pseudoitem")).forEach(element => {
  element.addEventListener("mouseenter", () => {
    const style = window.getComputedStyle(element);
    currentCellPosition = {
      "grid-row-start": style.gridRowStart,
      "grid-row-end": style.gridRowEnd,
      "grid-column-start": style.gridColumnStart,
      "grid-column-end": style.gridColumnEnd
    }
    console.log(currentCellPosition);
  })
})
EDIT2: 我已经重写了计算。现在您可以定义“repeat”和“rows”参数,将自动创建layer2网格

小提琴被更新,下面是代码更改:

var cont = $(".pseudoContainer");
var y,x;
var repeat = 6;
var rows = 3;
for (var i = 0; i < rows*repeat; i++) {

  if(i%repeat === 0) {
    y = i/repeat;
  }
  x = i- y * repeat;

  var newDiv = document.createElement("div");
  newDiv.setAttribute('class', 'pseudoitem');
  newDiv.setAttribute('data-gs-width', '1');
  newDiv.setAttribute('data-gs-height', '1');
  newDiv.setAttribute('data-gs-x', x);
  newDiv.setAttribute('data-gs-y', y);
  newDiv.innerHTML = '<div class="pseudoitem-inner"></div>';
  cont.append(newDiv);
}

for(let elm of document.getElementsByClassName('pseudoitem')){
            elm.style['grid-column-start'] = parseInt(elm.getAttribute('data-gs-x')) + 1;
            elm.style['grid-column-end'] = parseInt(elm.getAttribute('data-gs-x')) + parseInt(elm.getAttribute('data-gs-width')) + 1;
            elm.style['grid-row-start'] = parseInt(elm.getAttribute('data-gs-y')) +1 ;
            elm.style['grid-row-end'] = parseInt(elm.getAttribute('data-gs-y')) + parseInt(elm.getAttribute('data-gs-height')) +1;
        }


let currentCellPosition = {
  "grid-row-start": null,
  "grid-row-end": null,
  "grid-column-start": null,
  "grid-column-end": null
}

Array.from(document.getElementsByClassName("pseudoitem")).forEach(element => {
  element.addEventListener("mouseenter", () => {
    const style = window.getComputedStyle(element);
    currentCellPosition = {
      "grid-row-start": style.gridRowStart,
      "grid-row-end": style.gridRowEnd,
      "grid-column-start": style.gridColumnStart,
      "grid-column-end": style.gridColumnEnd
    }
    console.log(currentCellPosition);
  })
})
var cont=$(“.pseudoContainer”);
变量y,x;
重复变量=6;
var行=3;
对于(变量i=0;i.pseudoContainer{
  position:absolute;
  top:10px;
  left:10px;
  width: 100%;
      height: 400px;
  display: grid;
   z-index:1;
   grid-template-columns: repeat(6, 1fr);
   grid-gap: 0px;
}
.pseudoitem{

    z-index:2;
}
.pseudoitem-inner{

    height: 100%;
    width: 100%;
}
.container{
  z-index:1;
}
.grid-stack-item{
  z-index:3;
}
var cont = $(".pseudoContainer");
var y,x;
var repeat = 6;
var rows = 3;
for (var i = 0; i < rows*repeat; i++) {

  if(i%repeat === 0) {
    y = i/repeat;
  }
  x = i- y * repeat;

  var newDiv = document.createElement("div");
  newDiv.setAttribute('class', 'pseudoitem');
  newDiv.setAttribute('data-gs-width', '1');
  newDiv.setAttribute('data-gs-height', '1');
  newDiv.setAttribute('data-gs-x', x);
  newDiv.setAttribute('data-gs-y', y);
  newDiv.innerHTML = '<div class="pseudoitem-inner"></div>';
  cont.append(newDiv);
}

for(let elm of document.getElementsByClassName('pseudoitem')){
            elm.style['grid-column-start'] = parseInt(elm.getAttribute('data-gs-x')) + 1;
            elm.style['grid-column-end'] = parseInt(elm.getAttribute('data-gs-x')) + parseInt(elm.getAttribute('data-gs-width')) + 1;
            elm.style['grid-row-start'] = parseInt(elm.getAttribute('data-gs-y')) +1 ;
            elm.style['grid-row-end'] = parseInt(elm.getAttribute('data-gs-y')) + parseInt(elm.getAttribute('data-gs-height')) +1;
        }


let currentCellPosition = {
  "grid-row-start": null,
  "grid-row-end": null,
  "grid-column-start": null,
  "grid-column-end": null
}

Array.from(document.getElementsByClassName("pseudoitem")).forEach(element => {
  element.addEventListener("mouseenter", () => {
    const style = window.getComputedStyle(element);
    currentCellPosition = {
      "grid-row-start": style.gridRowStart,
      "grid-row-end": style.gridRowEnd,
      "grid-column-start": style.gridColumnStart,
      "grid-column-end": style.gridColumnEnd
    }
    console.log(currentCellPosition);
  })
})