我知道这看起来很奇怪,但我有一种情况,当我们将鼠标悬停在目标上时,我需要模拟单击事件。
\n\n我目前正在使用 JavaScript 的.click()方法 \xe2\x80\x93 https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click,但点击冒泡到liDOM 中并activateAnchor()同时触发功能。我尝试过使用stopPropagation,但这没有效果。
我的问题是:这是否可能,或者我是否需要以不同的方式处理这个问题。
\n\n我这里有一个例子 \xe2\x80\x93 https://jsfiddle.net/dryrobe/vsq7czmx/43/
\n\nconst output = document.querySelector(\'.output\');\nconst switcherList = document.querySelector(\'[data-custom-switcher]\');\nconst switcherListItems = Array.from(switcherList.getElementsByTagName(\'li\'));\nconst switcherListItemsAnchors = Array.from(switcherList.getElementsByTagName(\'a\'));\n\nswitcherListItemsAnchors.map(switcherListItemAnchor => switcherListItemAnchor.addEventListener(\'mouseenter\', simulateClick.bind(switcherListItemAnchor)));\nswitcherListItems.map(switcherListItem => switcherListItem.addEventListener(\'click\', activateAnchor.bind(switcherListItem)));\n\n// This should only fire when each item is clicked, but it fires on hover.\nfunction activateAnchor() {\n event.stopPropagation();\n addMessage(\'activateAnchor\');\n}\n\n// This should fire when each item is hovered\nfunction simulateClick() {\n event.stopPropagation();\n this.click();\n addMessage(\'simulateClick\');\n}\n\nfunction addMessage(message) {\n if(message === \'activateAnchor\') {\n output.innerHTML += `<h1>This is the activateAnchor function</h1>`;\n }\n if(message === \'simulateClick\') {\n output.innerHTML += `<h1>This is the simulateClick function</h1>`;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
这.click()将导致传播点击事件。如果您希望点击事件不传播,则必须添加点击侦听器并调用stopPropagation该事件。您无法阻止click事件从mouseenter处理程序内部传播。检查e.isTrusted事件是由 Javascript 触发还是由用户实际点击触发 - 如果为 false,则由 Javascript 触发,您可以调用stopPropagation:
switcherListItemsAnchors.forEach((switcherListItemAnchor) => {
switcherListItemAnchor.addEventListener('mouseenter', simulateClick.bind(switcherListItemAnchor))
switcherListItemAnchor.addEventListener('click', (e) => {
if (!e.isTrusted) {
e.stopPropagation();
}
})
});
Run Code Online (Sandbox Code Playgroud)
另请注意,您只能用于.map从另一个数组创建一个数组。对于副作用(例如添加侦听器),请forEach改用。
.bind如果this绑定函数内部已打算成为单击的元素(或者如果this未在函数内部使用),则也不需要:
switcherListItemsAnchors.forEach((switcherListItemAnchor) => {
switcherListItemAnchor.addEventListener('mouseenter', simulateClick.bind(switcherListItemAnchor))
switcherListItemAnchor.addEventListener('click', (e) => {
if (!e.isTrusted) {
e.stopPropagation();
}
})
});
Run Code Online (Sandbox Code Playgroud)
const output = document.querySelector('.output');
const switcherList = document.querySelector('[data-custom-switcher]');
switcherList.querySelectorAll('a').forEach((switcherListItemAnchor) => {
switcherListItemAnchor.addEventListener('mouseenter', simulateClick)
switcherListItemAnchor.addEventListener('click', (e) => {
if (!e.isTrusted) {
e.stopPropagation();
}
})
});
switcherList.querySelectorAll('li').forEach(switcherListItem => {
switcherListItem.addEventListener('click', activateAnchor);
});
// This should only fire when each item is clicked, but it fires on hover.
function activateAnchor() {
addMessage('activateAnchor');
}
// This should fire when each item is hovered
function simulateClick(e) {
this.click();
addMessage('simulateClick');
}
function addMessage(message) {
if (message === 'activateAnchor') {
output.innerHTML += `<h1>This is the activateAnchor function</h1>`;
}
if (message === 'simulateClick') {
output.innerHTML += `<h1>This is the simulateClick function</h1>`;
}
}Run Code Online (Sandbox Code Playgroud)
* {
padding: 0;
margin: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
height: 100vh;
font-family: sans-serif;
font-size: 100%;
}
.output {
width: 100%;
background-color: yellow;
}
ul {
display: flex;
list-style: none;
}
li+li {
margin-left: 20px;
}
a {
padding: 20px;
background-color: pink;
transition: background-color .5s ease-in-out;
text-decoration: none;
color: #000;
}
a:hover {
background-color: #ddd;
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
478 次 |
| 最近记录: |