事件目标应该是锚点,而不是图像

时间:2015-10-31 21:24:25

标签: javascript

我正在使用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,而不是实际的锚点。我怎么能纠正这个?谢谢!

3 个答案:

答案 0 :(得分:16)

使用event.currentTargetevent.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]);
}