鼠标悬停事件冒泡问题 - Javascript

时间:2016-09-04 08:52:39

标签: javascript css javascript-events

我正在编写一些纯JavaScript,要求我逐行动态地向Flex容器中添加元素。令我惊讶的是,我的鼠标悬停事件在行中传播并触发其他孩子,即使它不应该。以下是我的代码。

function drawChildren() {
    var size = Math.floor(containerSize / childSize);
    var counter = 1;
    var parent = document.getElementById(parentId);
    for(var rowCount = 1; rowCount <= size ; rowCount ++) {
      var row = document.createElement('div');
      row.id = `${parentId}-rowDiv-${rowCount} `;
      row.setAttribute('style', `
        height: ${childSize}px;
        width: ${containerSize}px;
        display: flex; 
        flex-direction:row; `);
      for(var child = 1; child <= size ; child ++) {
        var childDiv = document.createElement('div');
        childDiv.id = `${parentId}-childDiv-${counter}`;
        childDiv.setAttribute('style',`
            height: ${childSize}px;
          width: ${childSize}px; 
          background-color: ${getRandomColor()};`);

        childDiv.addEventListener("mouseover", onMouseOver);  
        childDiv.addEventListener("mouseleave", onMouseLeave);
        row.appendChild(childDiv);
        counter ++;
      }
      parent.appendChild(row);
    }

onmouseover,我调用了下面的函数

function onMouseOver(e) {
    e.stopPropagation();
    document.getElementById(e.target.id).style.display = 'none';
    console.log(e.target.id);
  }

问题是,每当我鼠标悬停在一个对象上时,它就会在该行上传播,并为同一行上的所有其他项触发mouseover事件。它也会一次点火。我试图通过添加js stopPropagation()道具来阻止传播,但没有任何改变。请问是什么造成的,我该如何解决?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

在删除用于获取size和parentId变量的语法后,JS逻辑工作得很好(我猜测它来自JSP)。可能是使用的反引号(`)问题。

您指的是悬停在该行的第一个子节点上隐藏整行的问题。

此处,display:none;将成为罪魁祸首,您可以使用visibility: hidden;代替。

display: none;将从布局中删除元素,释放从布局中获取的空间,从而允许下一个元素占用其空间。 在这个问题中,悬停在第一个孩子身上可以释放第二个元素现在占用的空间。由于你的鼠标仍处于同一位置,它现在将删除第二个元素,循环就这样了。

visibility: hidden;仅隐藏元素,同时在页面布局中保留其空间。

以下是您的代码的工作片段(display: none;visibility : hidden;):

&#13;
&#13;
var containerSize = 200,
  childSize = 50;

function onMouseOverDisplay(e) {
  e.stopPropagation();
  document.getElementById(e.target.id).style.display = 'none';
  console.log(e.target.id);
}

function onMouseOverVisibility(e) {
  e.stopPropagation();
  document.getElementById(e.target.id).style.visibility = 'hidden';
  console.log(e.target.id);
}

function setAttr(elem, attrs) {
  for (var attr in attrs) {
    if (attrs.hasOwnProperty(attr)) {
      elem.setAttribute(attr, attrs[attr]);
    }
  }
}

function drawChildren(parentId) {
  var size = Math.floor(containerSize / childSize),
    parent = document.getElementById(parentId),
    counter = 1,
    rowCount, childCount, row, childDiv;

  for (rowCount = 1; rowCount <= size; rowCount++) {
    row = document.createElement('div');
    row.id = parentId + "-rowDiv-" + rowCount;
    row.setAttribute('style', "height: " + childSize + "px; width: " + containerSize + "px; display: flex; flex-direction: row;");
    for (childCount = 1; childCount <= size; childCount++) {
      childDiv = document.createElement('div');
      childDiv.id = parentId + "-childDiv-" + rowCount + "-" + childCount;
      childDiv.setAttribute('style', "height: " + childSize + "px; width: " + childSize + "px; background-color: cyan; border: 1px solid red;");

      if (parentId === 'tab-display') {
        childDiv.addEventListener("mouseover", onMouseOverDisplay);
      } else if (parentId === 'tab-visibility') {
        childDiv.addEventListener("mouseover", onMouseOverVisibility);
      }

      // childDiv.addEventListener("mouseleave", onMouseLeave);
      row.appendChild(childDiv);
      counter++;
    }
    parent.appendChild(row);
  }
}

drawChildren('tab-display');
drawChildren('tab-visibility');
&#13;
<h2>Using Display None</h2>
<div id="tab-display"></div>

<h2>Using Visibilty Hidden</h2>
<div id="tab-visibility"></div>
&#13;
&#13;
&#13;