知道鼠标是否在元素上的替代方法 (Javascript)
Alternative way to know if mouse is over an element (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>
要删除“缩放”和 return 正常的东西,我只是使用:
clone.addEventListener("mouseout", function() {
clone.remove();
如果您将鼠标平滑地移到元素上,这会很好地工作,但是如果移动得更大 table 和移动得更快,您可以亲眼看到某些元素 return 不正常:
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 以使用绝对坐标测试鼠标是否在元素内部,但可能有更简单的解决方案。
您可以使用 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>
我正在回答我自己的问题,因为我需要结合一些想法才能让它运作良好。
首先我需要指出的是,出于某种原因,我描述的问题仅在打开“开发人员”选项卡 (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>
希望对大家有所帮助。
我有一个脚本,当我的鼠标悬停在它上面时,它会显示一个“悬停元素”(如缩放)。我知道这有点乱,但这里有一个例子:
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>
要删除“缩放”和 return 正常的东西,我只是使用:
clone.addEventListener("mouseout", function() {
clone.remove();
如果您将鼠标平滑地移到元素上,这会很好地工作,但是如果移动得更大 table 和移动得更快,您可以亲眼看到某些元素 return 不正常:
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 以使用绝对坐标测试鼠标是否在元素内部,但可能有更简单的解决方案。
您可以使用 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>
我正在回答我自己的问题,因为我需要结合一些想法才能让它运作良好。
首先我需要指出的是,出于某种原因,我描述的问题仅在打开“开发人员”选项卡 (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>
希望对大家有所帮助。