【问题标题】:Alternative way to know if mouse is over an element (Javascript)了解鼠标是否在元素上的替代方法(Javascript)
【发布时间】:2020-06-29 17:55:13
【问题描述】:

我有一个脚本,当我的鼠标悬停在它上面时,它会显示一个“悬停元素”(如缩放)。我知道这有点乱,但这里有一个例子:

function showOverflow2(e) {
  let cell = e.currentTarget;
  let clone = cell.cloneNode(true);

  if (cell.children[0].scrollWidth <= cell.children[0].clientWidth) {
    return false;
  };

  clone.innerHTML = clone.children[0].innerHTML;

  clone.style.position = 'absolute';

  clone.style.backgroundColor = 'white';
  clone.style.borderWidth = '2px';

  clone.style.lineHeight = cell.scrollHeight + 'px';

  clone.style.whiteSpace = 'nowrap';


  x0 = (
    cell.offsetLeft +
    parseFloat(
      getComputedStyle(
        cell.parentElement.parentElement.parentElement.parentElement
      )["padding-left"].slice(0, -2)
    ) + 2
  );

  y0 = (
    cell.offsetTop +
    parseFloat(
      getComputedStyle(
        cell.parentElement.parentElement.parentElement.parentElement
      )["padding-top"].slice(0, -2)
    ) + 2
  );

  xmid = x0 + (cell.clientWidth / 2);
  ymid = y0 + (cell.clientHeight / 2);

  let body = document.getElementsByTagName('body')[0];
  body.appendChild(clone);

  clone.style.height = cell.scrollHeight + 'px';
  clone.style.width = clone.scrollWidth + 'px';

  xf = xmid - (clone.clientWidth / 2);
  yf = ymid - (clone.clientHeight / 2);

  clone.style.top = yf + 'px';
  clone.style.left = xf + 'px';

  
  // FOCUS ON THIS PART
  

  clone.addEventListener("mouseout", function() {
    clone.remove();
  });
  
  // END OF FOCUS
  
};



let all_cells = document.getElementsByTagName('td');
for (let i = 0; i < all_cells.length; i++) {
  let current_cell = all_cells[i];

  if (current_cell.className !== 'buttons') {
    current_cell.addEventListener("mouseover", showOverflow2);
  }
}
body {
  margin: 0;
}

#container {
  background-color: gainsboro;
  border: 2px solid black;
  border-radius: 2px;
  padding: 1.2%;
  max-width: 50%;
}

table {
  border-collapse: separate;
  border-spacing: 0 0.5rem;
  table-layout: fixed;
  width: 100%;
}

tr {
  background-color: white;
}

td {
  width: calc(100%/3);
  border: solid gray;
  border-width: 2px 1px 2px 0;
  padding: 0.7% 1%;
  text-align: center;
  white-space: nowrap;
}

span {
  display: block;
  overflow: hidden;
}

td:first-child {
  border-left-width: 2px;
  border-radius: 3px 0 0 3px;
}

td:last-child {
  border-right-width: 2px;
  border-radius: 0 3px 3px 0;
}
<div id="container">
  <table id="table">
    <tr>
      <td class="cell1"><span>AAAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAAAAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
  </table>
</div>

要删除“缩放”并恢复正常,我只是使用:

    clone.addEventListener("mouseout", function() {
    clone.remove();

如果您将鼠标平稳地移动到元素上,这会很好,但如果使用更大的表格和更快的移动,您可以自己看到某些元素没有恢复正常:

function showOverflow2(e) {
  let cell = e.currentTarget;
  let clone = cell.cloneNode(true);

  if (cell.children[0].scrollWidth <= cell.children[0].clientWidth) {
    return false;
  };

  clone.innerHTML = clone.children[0].innerHTML;

  clone.style.position = 'absolute';

  clone.style.backgroundColor = 'white';
  clone.style.borderWidth = '2px';

  clone.style.lineHeight = cell.scrollHeight + 'px';

  clone.style.whiteSpace = 'nowrap';


  x0 = (
    cell.offsetLeft +
    parseFloat(
      getComputedStyle(
        cell.parentElement.parentElement.parentElement.parentElement
      )["padding-left"].slice(0, -2)
    ) + 2
  );

  y0 = (
    cell.offsetTop +
    parseFloat(
      getComputedStyle(
        cell.parentElement.parentElement.parentElement.parentElement
      )["padding-top"].slice(0, -2)
    ) + 2
  );

  xmid = x0 + (cell.clientWidth / 2);
  ymid = y0 + (cell.clientHeight / 2);

  let body = document.getElementsByTagName('body')[0];
  body.appendChild(clone);

  clone.style.height = cell.scrollHeight + 'px';
  clone.style.width = clone.scrollWidth + 'px';

  xf = xmid - (clone.clientWidth / 2);
  yf = ymid - (clone.clientHeight / 2);

  clone.style.top = yf + 'px';
  clone.style.left = xf + 'px';

  
  // FOCUS ON THIS PART
  

  clone.addEventListener("mouseout", function() {
    clone.remove();
  });
  
  // END OF FOCUS
  
};



let all_cells = document.getElementsByTagName('td');
for (let i = 0; i < all_cells.length; i++) {
  let current_cell = all_cells[i];

  if (current_cell.className !== 'buttons') {
    current_cell.addEventListener("mouseover", showOverflow2);
  }
}
body {
  margin: 0;
}

#container {
  background-color: gainsboro;
  border: 2px solid black;
  border-radius: 2px;
  padding: 1.2%;
  max-width: 50%;
}

table {
  border-collapse: separate;
  border-spacing: 0 0.5rem;
  table-layout: fixed;
  width: 100%;
}

tr {
  background-color: white;
}

td {
  width: calc(100%/3);
  border: solid gray;
  border-width: 2px 1px 2px 0;
  padding: 0.7% 1%;
  text-align: center;
  white-space: nowrap;
}

span {
  display: block;
  overflow: hidden;
}

td:first-child {
  border-left-width: 2px;
  border-radius: 3px 0 0 3px;
}

td:last-child {
  border-right-width: 2px;
  border-radius: 0 3px 3px 0;
}
<div id="container">
  <table id="table">
    <tr>
      <td class="cell1"><span>AAAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAAAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
    <tr>
      <td class="cell1"><span>AAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAAAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
    <tr>
      <td class="cell1"><span>AAAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAAAAAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
    <tr>
      <td class="cell1"><span>AAAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAAAAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
    <tr>
      <td class="cell1"><span>AAAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAAAAAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
    <tr>
      <td class="cell1"><span>AAAAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAAAAAaAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
    <tr>
      <td class="cell1"><span>AAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAASAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
    <tr>
      <td class="cell1"><span>AAAAAAAAAABBBCC</span></td>
      <td class="cell2"><span>AAAAAAAAAABBBB</span></td>
      <td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
      </td>
    </tr>
  </table>
</div>

如果我不能信任 mouseout 事件,我可以做些什么来解决这个问题?

我想过在鼠标移动时使用 eventListener 来测试鼠标是否在使用绝对坐标的元素内,但可能有一个更简单的解决方案。

【问题讨论】:

标签: javascript html jquery mouseevent dom-events


【解决方案1】:

您可以使用 CSS 执行类似的操作,方法是重复内容(放大)并在悬停时显示和隐藏它。下面是一个简单的例子。

table {
  padding: 30px;
}

td {
  position: relative;
  padding: 4px;
  border: 1px solid blue;
}

.grow {
  display: none;
  background-color: #fff;
  border: 1px solid #000;
  padding: 3px;
  z-index: 10;
}

td:hover .grow {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  transform: scale(1.5);
}
<html>

<head></head>

<body>
  <table>
    <tr>
      <td>asdf<span class="grow">ASDF</span></td>
      <td>fasd<span class="grow">FASD</span></td>
  </table>
</body>

</html>

【讨论】:

    【解决方案2】:

    我正在回答我自己的问题,因为我需要结合一些想法才能使其运作良好。

    首先我需要指出,出于某种原因,我描述的问题仅在打开开发人员选项卡 (f12) 时才会在浏览器中发生,否则一切正常。

    但我仍然想确定没有细胞会那样冻结,所以我像 Ed Lucas 一样使用 css。不过,我需要 Javascript 才能正确居中。

    经过几天的尝试,我终于找到了一种使用 css 将其居中的方法,该方法适用于绝对定位并且子元素更大。

    我没有删除 Javascript 方法,因为它让我可以灵活地触发和恢复此事件。

    最后,我的代码是这样的:

    function showOverflow(e) {
    
      const div = e;
      const cell = div.parentElement;
      const span = div.children[0];
    
      if (span.scrollWidth <= span.clientWidth) {
        return false;
      }
    
      const clone = div.cloneNode(true);
      clone.classList.add('hovercell');
    
      cell.appendChild(clone);
    
      let cell_style = getComputedStyle(cell);
    
      function cloneRemove(host) {
        clone.remove();
        clearInterval(host.id);
      }
    
      function isInside(host) {
        if (cell_style['z-index'] === '0') {
          cloneRemove(host);
        }
      }
    
      let host = {};
      host.id = setInterval(isInside.bind(null, host), 100);
    
      clone.addEventListener("mouseleave", function() {
        cloneRemove(host);
      });
    
    }
    td {
      border: 2px solid gray;
      padding: 0.7% 1%;
      text-align: center;
      white-space: nowrap;
      z-index: 0;
      position: relative;
    }
    
    td:hover {
      z-index: 2;
    }
    
    span {
      display: block;
      overflow: hidden;
    }
    
    .hovercell {
      background-color: white;
      border: 2px solid gray;
      
      padding: 6px 8px;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%) scale(1.2);
    }
    <table>
      <tbody>
        <tr>
          <td>
            <div onclick="showOverflow(this)">
              <span>A big cell--- 1</span>
            </div>
          </td>
          <td>
            <div onclick="showOverflow(this)">
              <span>A big cell--- 2</span>
            </div>
          </td>
        </tr>
      </tbody>
    </table>

    希望对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2017-09-24
      • 2020-10-09
      • 2014-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      相关资源
      最近更新 更多