我正在使用Vanilla JS中的对话脚本。我遇到了视频图像上的点击事件的问题。即使是强大的图像被锚标记包围,它也会将图像显示为“trigger-dialog-open”事件中的event.target。
这是HMTL:
<a class="trigger-dialog--open thumbnail" data-dialog-id="dialog-video" href="javascript:;">
<figure>
<img src="http://i.ytimg.com/vi/id/sddefault.jpg" alt="" />
</figure>
</a>
这是JS中的事件:
var openTriggers = document.getElementsByClassName('trigger-dialog--open');
for (var i = 0; i < openTriggers.length; i++) {
openTriggers[i].addEventListener("click", function (event) {
this.openDialog(event.target.getAttribute('data-dialog-id'));
}.bind(this), false);
}
事件处理程序想要知道anchors数据属性中的dialog-id。无法找到它,因为它认为图像是event.target,而不是实际的锚点。我怎么能纠正这个?谢谢!
答案 0 :(得分:16)
使用event.currentTarget
。 event.target
应该是img
元素,因为这是用户点击的内容。然后点击通过图像的容器冒泡。 event.currentTarget
为您提供了点击处理程序实际绑定的元素。
(或者,如果您没有将this
绑定到其他对象,则可以在点击处理程序中使用this
,它也应该是当前目标。)
答案 1 :(得分:1)
我有几个问题是 var openTriggers 应该是模块哈希的一部分吗?因为如果它是全球性的,那么你不会使用这个,你只需添加这个,如果它引用了一个变量,那么函数也包含在。例如:
var aThing = {
openTriggers: document.getElementsByClassName('trigger-dialog--open'),
openModal: null,
openDialog: function(clickedThingAttr){
if(this.openModal !== null){
this.openModal.style.display = 'none';
}else{
this.openModal = document.getElementById(clickedThingAttr);
}
this.openModal = document.getElementById(clickedThingAttr);
this.openModal.style.display = 'block';
},
setEventListenersNStuff: function(){
for (var i = 0, n = this.openTriggers.length;i < n; i++) {
this.openTriggers[i].addEventListener("click", function (event) {
this.openDialog(event.target.getAttribute('data-dialog-id'));
});
};
}
};//end of aThing hash object
aThing.setEventListenersNStuff();
这里有一些问题: 1.你为什么使用 .bind 我认为这是一个jQuery的东西,你想在单击一个对象时将字符串传递给另一个函数,根本不需要绑定。 2.还要确保如果你想做一些像打开模态的东西,除非它有点复杂,否则不需要调用另一种方法。 3.其他可能的对话框怎么样,当点击 .trigger-dialog-open 时,你只是显示一个带有嵌入式id的模态,但是其他的呢?确保在打开新模态之前关闭所有模态,除非您希望打开10个模态。
需要注意的一点是:我添加了行 var i = 0,n = openTriggers.length; i&lt; N; i ++ ,现在在这种情况下它是愚蠢的优化,我听说现代浏览器不适用,但解释我为什么添加它,是因为我&lt; openTriggers.length会对数组进行N次计数和集成。 (这可能是一个过时的optmiziation)。
如果您的意思是全球
下面我添加了一组不同的代码,以防你认为 var openTriggers 是全局的,有点像你上面写的那样。我也使用了querySelectorAll,就像jQuery&#39; $(&#39; .thing&#39;)选择器一样。
anyhoo,我还添加了
var openTriggers = document.querySelectorAll('.trigger-dialog--open');
var n = openTriggers.length;
function openDialog(ddId){
for (var i = 0;i < n; i++) {
openTriggers[i].style.display = 'none';
};
document.getElementById(ddId).style.display = 'block';
};
for (var i = 0;i < n; i++) {
openTriggers[i].addEventListener("click", function (event) {
openDialog(event.target.getAttribute('data-dialog-id'));
});
}
}
因此,对于隐藏已经打开的模态的问题,我建议你可以在一个模块中缓存打开的Dialog,或者你可以切换一个类,这样效率会降低,因为它需要额外的DOM搜索。另外你可以添加一个if this.openModal.id === clickedThingAttr来隐藏如果打开,这样你就有了一个切换功能。
无论如何我建议你阅读这些内容,如果你想使用普通JS但想要jQuery的功能:http://blog.romanliutikov.com/post/63383858003/how-to-forget-about-jquery-and-start-using-native
感谢您的时间。
答案 2 :(得分:0)
您可以使用闭包
var openTriggers = document.getElementsByClassName('trigger-dialog--open');
for (var i = 0; i < this.openTriggers.length; i++) {
(function(element) {
element.addEventListener("click", function (event) {
element.openDialog(event.target.getAttribute('data-dialog-id'));
}, false)
})(openTriggers[i]);
}