开发者

jquery $(this) not working in coffee script / backbone

I recently started playing with Backbone and CoffeeScript using Brunch and was wondering why something like this...

events: {
  "click .button" : "open",
  "hover .info"   : "hover"
},

hover: =>
  $(this).css("background-color", "#333")

..does not work.

From my understanding CoffeeScript has its own version of this which could conflict with what jQuery uses but in the documentation I thought => binds it to the current object. I have also tried -> as well to no avail. Any idea on why this开发者_开发百科 doesn't work?

HTML:

<div id='outer'> 
   <div class='.info'> <a href='google.com'> google </a> </div> 
   <div class='.info'> <a href='google.com'> google </a> </div> 
   <div class='.info'> <a href='google.com'> google </a> </div> 
</div>


From the docs:

All attached callbacks are bound to the view before being handed off to jQuery, so when the callbacks are invoked, this continues to refer to the view object.

And if this is the view object (rather than, say, an HTML element), $(this) is fairly meaningless. What you want to do, I believe, is pass the element to which the view refers to $, e.g.:

hover: =>
  $(this.el).css("background-color", "#333")
  # -----^


Jordan's answer is correct with respect to this - if you want the view's element use this.el.

In your case you want the element that triggered the event i.e. the .info element. This can be retrieved through event.currentTarget1

hover: (e) =>
  $(e.currentTarget).css("background-color", "#333")


Jordan and gingerhendrix are both correct, but let me step back a moment to consider the more general question of => vs. ->.

You've no doubt seen/used code like

$('#foo').hover ->
  $(this).css('background-color', '#333')

Why does this work? Well, internally, jQuery's hover function looks something like this [heavily stylized, obviously]:

hover: (callback) ->
  for el in @
    el.onmouseenter = el.onmouseleave = (e) -> callback.call el, e

callback.call el, e is just like calling callback(e), except that it makes this point to el inside of that function call. So that's why $(this) gives you a jQuery object wrapped around the element that the hover event is on.

But this wouldn't work if you wrote

$('#foo').hover => ...

because => overrides call and apply; it forces this to always mean the same thing, no matter how the function is called.

Here's the thing: Backbone's hover wraps around jQuery's hover in such a way that this points to the View instance anyway... so it actually doesn't matter in your case whether you use -> or =>. That's why they use $(this.el) in the docs. And that's great, because you'll almost certainly want to have access to the view's properties when handling events. As gingerhendrix pointed out, this.el is going to give you the overall View element, not the specific element receiving the hover event; but the event object e has what you need (and so much more).

For more on the bound function operator, check out my book.


Well $(this) is not working me to so I did $(event.target). This will work for sure.


I write my jQuery calls like this when using Coffee Script:

$ -> $('#entryBox').val "Placeholder text"

I haven't even bothered figuring out why it works yet, but it does work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜