防止JavaScript在使用HTMLElement.click()方法时冒泡到DOM中

防止JavaScript在使用HTMLElement.click()方法时冒泡到DOM中,javascript,Javascript,我知道这看起来很奇怪,但我有一种情况,当我们悬停在目标上时,我需要模拟一个点击事件 我目前正在使用JavaScript的.click()方法–,但是单击会冒泡到DOM中的li,同时触发activateAnchor()函数。我尝试过使用停止播放,但没有效果 我的问题是:这是否可能,或者我是否需要以不同的方式处理这个问题 我这里有一个例子—— const output=document.querySelector('.output'); const switcherList=document.que

我知道这看起来很奇怪,但我有一种情况,当我们悬停在目标上时,我需要模拟一个点击事件

我目前正在使用JavaScript的
.click()
方法–,但是单击会冒泡到DOM中的
li
,同时触发
activateAnchor()
函数。我尝试过使用
停止播放
,但没有效果

我的问题是:这是否可能,或者我是否需要以不同的方式处理这个问题

我这里有一个例子——

const output=document.querySelector('.output');
const switcherList=document.querySelector(“[data custom switcher]”);
const switcherListItems=Array.from(switcherList.getElementsByTagName('li');
const switcherListItemsAnchors=Array.from(switcherList.getElementsByTagName('a'));
switcherListItemsAnchors.map(switcherListItemAnchor=>switcherListItemAnchor.addEventListener('mouseenter',simulatedclick.bind(switcherListItemAnchor));
switcherListItems.map(switcherListItem=>switcherListItem.addEventListener('click',activateAnchor.bind(switcherListItem));
//这应该只在单击每个项目时触发,但在悬停时触发。
函数activateAnchor(){
event.stopPropagation();
添加消息('activateAnchor');
}
//当每个项目悬停时,应该触发该命令
函数模拟单击(){
event.stopPropagation();
这个。单击();
添加消息(“模拟单击”);
}
函数addMessage(消息){
如果(消息=='activateAnchor'){
output.innerHTML+=`这是activateAnchor函数';
}
如果(消息=='SimulatedClick'){
output.innerHTML+=`这是模拟单击函数';
}
}
点击
.click()
将导致传播点击事件。如果希望click事件不传播,则必须添加click侦听器,并对该事件调用
stopPropagation
。无法阻止单击事件从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();
    }
  })
});
还请注意,只能使用
.map
从一个数组创建另一个数组。对于副作用(如添加侦听器),请改用
forEach

如果绑定函数中的
this
已被指定为单击的元素(或者如果
this
未在函数中使用),也无需
.bind

const output=document.querySelector('.output');
const switcherList=document.querySelector(“[data custom switcher]”);
switcherList.querySelectorAll('a').forEach((switcherListItemAnchor)=>{
switcherListItemAnchor.addEventListener('mouseenter',simulatedclick)
switcherListItemAnchor.addEventListener('单击',(e)=>{
如果(!e.不受信任){
e、 停止传播();
}
})
});
switcherList.querySelectorAll('li').forEach(switcherListItem=>{
switcherListItem.addEventListener('click',activateAnchor');
});
//这应该只在单击每个项目时触发,但在悬停时触发。
函数activateAnchor(){
添加消息('activateAnchor');
}
//当每个项目悬停时,应该触发该命令
功能模拟单击(e){
这个。单击();
添加消息(“模拟单击”);
}
函数addMessage(消息){
如果(消息=='activateAnchor'){
output.innerHTML+=`这是activateAnchor函数';
}
如果(消息=='SimulatedClick'){
output.innerHTML+=`这是模拟单击函数';
}
}
*{
填充:0;
保证金:0;
}
身体{
显示器:flex;
证明内容:中心;
对齐项目:居中;
柔性包装:包装;
高度:100vh;
字体系列:无衬线;
字体大小:100%;
}
.产出{
宽度:100%;
背景颜色:黄色;
}
保险商实验室{
显示器:flex;
列表样式:无;
}
李+李{
左边距:20px;
}
a{
填充:20px;
背景颜色:粉红色;
过渡:背景色。5s轻松进出;
文字装饰:无;
颜色:#000;
}
a:悬停{
背景色:#ddd;
}



  • 但是为什么要使用.click(),我会这样做

    <div onclick="if(event.stopPropagation){event.stopPropagation();}" onmouseover="RunSomeFunction();">Some Message</div>
    
    一些消息
    
    您只需创建一个完整的,默认情况下不会冒泡。您只需要像调用
    click()
    一样分派它

    const output=document.querySelector('.output');
    const switcherList=document.querySelector(“[data custom switcher]”);
    switcherList.querySelectorAll('a').forEach((switcherListItemAnchor)=>{
    switcherListItemAnchor.addEventListener('mouseenter',simulatedclick)
    });
    switcherList.querySelectorAll('li').forEach(switcherListItem=>{
    switcherListItem.addEventListener('click',activateAnchor');
    });
    //这应该只在单击每个项目时触发,但在悬停时触发。
    函数activateAnchor(){
    添加消息('activateAnchor');
    }
    //当每个项目悬停时,应该触发该命令
    功能模拟单击(e){
    const click=new MouseEvent('click');
    此.dispatchEvent(单击);
    添加消息(“模拟单击”);
    }
    函数addMessage(消息){
    如果(消息=='activateAnchor'){
    output.innerHTML+=`这是activateAnchor函数';
    }
    如果(消息=='SimulatedClick'){
    output.innerHTML+=`这是模拟单击函数';
    }
    }
    *{
    填充:0;
    保证金:0;
    }
    身体{
    显示器:flex;
    证明内容:中心;
    对齐项目:居中;
    柔性包装:包装;
    高度:100vh;
    字体系列:无衬线;
    字体大小:100%;
    }
    .产出{
    宽度:100%;
    背景颜色:黄色;
    }
    保险商实验室{
    显示器:flex;
    列表样式:无;
    }
    李+李{
    左边距:20px;
    }
    a{
    填充:20px;
    背景颜色:粉红色;
    过渡:背景色。5s轻松进出;
    文字装饰:无;
    颜色:#000;
    }
    a:悬停{
    背景
    
    <div onclick="if(event.stopPropagation){event.stopPropagation();}" onmouseover="RunSomeFunction();">Some Message</div>
    
    function simulateClick(e) {
      const click = new MouseEvent('click');
      this.dispatchEvent(click);
      addMessage('simulateClick');
    }