首页 > 解决方案 > 了解鼠标是否在元素上的替代方法(Javascript)

问题描述

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

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 来测试鼠标是否在使用绝对坐标的元素内,但可能有一个更简单的解决方案。

标签: javascripthtmljquerymouseeventdom-events

解决方案


您可以通过重复内容(放大)并在悬停时显示和隐藏它来使用 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>


推荐阅读