最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery data $(...).data('foo') sometimes returning undefined in Backbone app - Stack Overflow

programmeradmin1浏览0评论

Running into a weird bug – so I have an attribute defined as 'data-tagtype' on my button elems in my HTML. When a user clicks on a button, the following method gets called:

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
    });
  }
},

This works most of the time, but for some reason sometimes type is undefined for (seemingly) random elements. The corresponding HTML is here:

<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>

It's weird because there doesn't seem to be a pattern with respect to which ones return undefined when. Sometimes all of them work and sometimes one of them returns undefined for a couple of seconds, but then if I keep clicking it returns the proper value.

The View is definitely rendered/loaded into the DOM before any of these methods get called.

Any ideas? Does Backbone do something maybe?

Running into a weird bug – so I have an attribute defined as 'data-tagtype' on my button elems in my HTML. When a user clicks on a button, the following method gets called:

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
    });
  }
},

This works most of the time, but for some reason sometimes type is undefined for (seemingly) random elements. The corresponding HTML is here:

<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>

It's weird because there doesn't seem to be a pattern with respect to which ones return undefined when. Sometimes all of them work and sometimes one of them returns undefined for a couple of seconds, but then if I keep clicking it returns the proper value.

The View is definitely rendered/loaded into the DOM before any of these methods get called.

Any ideas? Does Backbone do something maybe?

Share Improve this question edited Feb 27, 2014 at 22:47 mu is too short 435k71 gold badges859 silver badges818 bronze badges asked Feb 27, 2014 at 20:40 DennisDennis 2333 silver badges12 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 12

The problem is that Backbone views use event delegation for their event handling. That means that e.target will be the the element that is clicked rather than the element that is responding to the event. If you click on the <i>, e.target will be that <i> but if you click on the text, e.target will be the <button>; the <i> doesn't have the data attribute you're looking for but the <button> does. That means that sometimes $(e.target).data('tagtype') will be undefined.

You can see this behavior in a simple example:

<div id="x">
    <button type="button" data-tagtype="love"><i>icon</i> text</button>
</div>

and a minimal view:

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

Demo: http://jsfiddle/ambiguous/pe77p/

If you click on <i>icon</i>, you'll get undefined love in the console but if you click on the text, you'll get love love in the console.

That little demo also contains the solution: use e.currentTarget instead of e.target.

发布评论

评论列表(0)

  1. 暂无评论