jQuery数据$(...).data('foo')有时在Backbone app中返回undefined

Den*_*nis 3 javascript jquery custom-data-attribute backbone.js backbone-views

遇到一个奇怪的错误 - 所以我button在我的HTML中的elems 上定义了一个属性'data-tagtype' .当用户单击按钮时,将调用以下方法:

onClickTag: function(e) {
  if (!this.playerLoaded) {
    return false;
  }
  var type = $(e.target).data('tagtype');
  var seconds = this.getCurrentTime();
  console.log(type);
  if (type) {
    this.model.addTag({
      type: type,
      seconds: seconds
    });
  }
},
Run Code Online (Sandbox Code Playgroud)

这在大多数情况下都有效,但由于某种原因,有时type(看似)随机元素未定义.相应的HTML在这里:

<button id="tag-love" class="tagger disabled" data-tagtype="love"><i class="fa fa-heart fa-fw"></i></button>
<button id="tag-important" class="tagger disabled" data-tagtype="important"><i class="fa fa-exclamation fa-fw"></i> Important</button>
<button id="tag-more" class="tagger disabled" data-tagtype="more"><i class="fa fa-ellipsis-h fa-fw"></i> More</button>
<button id="tag-confused" class="tagger disabled" data-tagtype="confused"><i class="fa fa-question fa-fw"></i> Confused</button>
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为似乎没有关于哪些返回未定义的模式.有时它们都工作,有时其中一个返回undefined几秒钟,但如果我一直点击它返回正确的值.

在调用任何这些方法之前,View肯定会被渲染/加载到DOM中.

有任何想法吗?Backbone可能会做些什么吗?

mu *_*ort 10

问题是Backbone视图使用事件委托进行事件处理.这意味着e.target将是单击的元素而不是响应事件的元素.如果你点击了<i>,那e.target将是那个<i>但是如果你点击文字,e.target将是<button>; 在<i>没有数据属性你正在寻找,但<button>确实.这意味着有时$(e.target).data('tagtype')undefined.

您可以在一个简单示例中看到此行为:

<div id="x">
    <button type="button" data-tagtype="love"><i>icon</i> text</button>
</div>
Run Code Online (Sandbox Code Playgroud)

和最小的观点:

var V = Backbone.View.extend({
    el: '#x',
    events: {
        'click button': 'clicked'
    },
    clicked: function(ev) {
        console.log(
            $(ev.target).data('tagtype'),
            $(ev.currentTarget).data('tagtype')
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/ambiguous/pe77p/

如果你点击<i>icon</i>,你将进入undefined love控制台,但如果你点击text,你将进入love love控制台.

那个小小的演示还包含解决方案:使用e.currentTarget而不是e.target.