我想在侦听器中的click
事件上设置自定义属性,然后在另一个事件侦听器中进一步读取此属性:
document.body.addEventListener('click', function(e) {
if (e.someCustomProperty) {
// ...
}
});
document.getElementById('some-element').addEventListener('click', function(e) {
e.someCustomProperty = someValue;
});
在我尝试使用的所有浏览器的最新版本中,这似乎都可以正常工作:
冒泡时,事件对象保留自定义属性。
这使我非常有信心这种行为得到了广泛支持,但是我找不到任何证据证明这是标准行为。
我是否可以相信这种行为在所有现代浏览器中都能起作用,并且会继续起作用?
如果没有,执行此操作的标准方法是什么?
我找到了similar question from 2011,但是唯一的答案现在已经过时了,提到它不能在IE8上使用(今天我不在乎)。
也许我应该为我要实现的目标提供一些背景知识,以及为什么以下提供的替代方法-我认为-不能帮助您
我有一个模式窗口,基本上是屏幕中央的固定DIV:
<body>
<div id="modal">
<!-- content -->
</div>
</body>
模态打开后,我在body
上设置了一个点击侦听器,它检查模态内部还是外部发生了点击:
因此,下面的代码:
document.body.addEventListener('click', function(e) {
if (! e.insideModal) {
modal.close();
}
});
document.getElementById('modal').addEventListener('click', function(e) {
e.insideModal = true;
});
失败的替代方法:
stopPropagation()
放在模式点击侦听器中,因为body
上的其他侦听器仍必须能够捕获点击; document.getElementById('modal').contains(e.target)
,因为当点击起泡到body
时,模态的内容可能已经更改,并且点击目标可能消失; window
或其他任何地方使用dataset
上的属性,因为我看不到如何帮助我知道 this 特定点击在到达body
之前已经到达了模式;如果您愿意,可以随时鸣叫!这就是为什么该活动看起来像是放置此信息的最佳位置。
答案 0 :(得分:0)
您可以将要传递的数据存储在data-*
属性中(这是它们的存在-存储自定义数据)。您可以将需要传递的数据分配给event.target.dataset.someCustomProperty
并在下一个处理程序中读取它。这种解决方案的缺点是所有数据都应转换为字符串(如果需要传递对象,则必须在其上使用JSON.stringify)。
document.getElementById('div').addEventListener('click', event => {
console.log(event.target.dataset.customProperty);
});
document.getElementById('button').addEventListener('click', event => {
event.target.dataset.customProperty = "Value of custom property";
});
<div id="div">
<button id="button">Click me</button>
</div>
澄清后编辑
为了使模式窗口在外部单击时可以关闭,可以使用一种非常简单的技术:模式窗口用透明的覆盖物包裹,该覆盖物覆盖了整个屏幕,并且具有onclick
事件监听器,在内部它与{{ 1}}(发出event.target
事件的元素)和click
(附加事件监听器的元素)。相等意味着点击了叠加层。不等于表示已点击了模式。
event.currentTarget
function openModal() {
document.getElementById('overlay').classList.add('visible');
}
document.getElementById('overlay').addEventListener('click', event => {
if(event.target === event.currentTarget){
event.target.classList.remove('visible');
}
});
.overlay {
display: none;
background: transparent;
height: 100vh;
width: 100vw;
position: fixed;
top: 0;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.overlay.visible {
display: flex
}
.modal {
width: 100px;
height: 100px;
background: grey;
}
答案 1 :(得分:0)
我不推荐。这些是原因:
window