解决香草JS + HTML中相邻元素问题的最有效方法?

时间:2019-01-18 22:16:46

标签: javascript html html5 dom javascript-objects

这是问题所在

使用html,vanilla javascript和css创建10x10网格。

单击该网格上的一个正方形后,将相邻正方形(顶部,左侧等)的背景颜色更改为黄色。

我能够解决此问题,但我认为它不是很有效-我的html只是一行:

<table id="grid"></table>

然后我使用javascript手动用一堆单元格/正方形填充表格。我给每个单元格两个属性data-rowdata-col来存储单元格所在的位置。然后点击我正在做这样的事情:

  var row = this.getAttribute('data-row');
  var col = this.getAttribute('data-col');

  ...

  //if not on the top most row, retrieve square above
  if(row>0){
      let sel = "td[data-row='"+(row-1)+"'][data-col='"+col+"']";
      let elem = document.querySelector(sel);
      elem.classList.toggle('yellow');
  }

  ...

  //3 more if blocks like the one above to find the bottom, left and right squares

有没有更有效或更简洁的方法?感谢您的提前答复!感激不尽:)

2 个答案:

答案 0 :(得分:0)

您可能会考虑无论如何都调用querySelector,然后检查是否已选择元素,而不是之前具有不同的if (row > 0) ...块。例如:

tryChange(-1, 0);
tryChange(1, 0);
tryChange(0, -1);
tryChange(0, 1);
function tryChange(xDiff, yDiff) {
  const sel = "td[data-row='"+(row + xDiff)+"'][data-col='"+(col + yDiff)+"']";
  const elem = document.querySelector(sel);
  if (elem) {
    elem.classList.toggle('yellow');
  }
}

如果未选择任何元素,则if (elem)测试将失败。

答案 1 :(得分:0)

陈述期望结果的方式使我认为所单击的单元格应该变黄,而问题是要求您处理单元格的Moore neighborhood

实现此目标的一种方法(我过去在游戏中使用过)是在JavaScript中保存网格单元的DOM元素(如果需要的话,是一个小的“影子DOM”)数组,并在单击数组中的单元格以找到邻居。

如果感兴趣的是一个可行的例子:

"use strict";

// iterate through the Moore neighbors of a cell
// ( in a 2D rectangular array)

function iter8( r, c, cellArray, callback) {
    r=+r; // convert row and column string arguments to number
    c=+c;

    const 
        maxRow = cellArray.length -1,
        maxCol = cellArray[0].length -1,
        r0 = r ? r-1 : 0,
        r1 = r < maxRow ? r+1 : maxRow,
        c0 = c ? c-1 : 0,
        c1 = c < maxCol? c+1 : maxCol
    ;
    for( var row = r0; row <= r1; ++ row) {
        for( var col = c0; col <= c1; ++ col) {
            if( ! (row == r && col == c)) {
                callback( cellArray[row][col], row, col, cellArray);
            }
        }
    }
}

//  *******   Test Code Follows  *********

const div = document.getElementById("board");
const array = [];
for( var r = 0; r < 10; ++r) {
    array.push([]);
    for( var c = 0; c < 10; ++c) {
        var cell = document.createElement( "SPAN");
        cell.className = "cell";
        cell.dataset["row"] = r;
        cell.dataset["col"] = c;
        cell.textContent = "(" + r + "," + c + ")";
        array[ r].push( cell);
        div.appendChild( cell);
    }
    div.appendChild( document.createElement("BR"));
}
div.addEventListener("click", event => {
    let cell = event.target;
    if( cell.classList.contains("cell")) {
         iter8( cell.dataset.row, cell.dataset.col, array, 
             neighbor => neighbor.classList.contains("yellow") || neighbor.classList.add("yellow")
         );
    }
}, false);
    
    
.div {
    white-space: nowrap;
}
.cell {
    display: inline-block;
    width: 2.5em;
    text-align: center;
    background-color: green;
    cursor: default;
}
.cell.yellow {
    background-color: yellow;
}
<div id="board">