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.
精彩评论