Передать $ (this) в функцию set timeout? - PullRequest
1 голос
/ 08 июля 2011

Что-то вроде ...

 $('.foo').live 'click', -> 
    setTimeout (()->$(this).parent().hide()), 5000

Спасибо за любую помощь!

Ответы [ 4 ]

5 голосов
/ 08 июля 2011

Джеймс правильно диагностировал проблему: когда вы передаете функцию в setTimeout, она вызывается в контексте window (как если бы вы вызывали func как func()). Есть два хороших решения:

1) (Quickest) Измените тонкую стрелку -> на жирную стрелку =>, которая связывает функцию с текущим контекстом, гарантируя, что this в функции имеет то же значение как this вне его. Тогда ваш код будет

$('.foo').live 'click', -> 
  setTimeout (=> $(this).parent().hide()), 5000

2) (наиболее эффективный) Просто запишите значение либо this, либо $(this) вне функции, которую вы передаете setTimeout. Это имеет меньше накладных расходов, чем привязка функции. Тогда ваш код будет

$('.foo').live 'click', -> 
  $this = $(this)
  setTimeout (-> $this.parent().hide()), 5000

Я часто пишу $this = $(this) в верхней части обратных вызовов. Это очень полезная идиома, которая избавит вас от многих головных болей и обеспечит бесперебойную работу.

3 голосов
/ 08 июля 2011

это в setTimeout будет либо window, либо неопределенным. В этом случае вам лучше либо обернуть анонимной функцией, чтобы закрыть ее, либо использовать bind (this), чтобы связать объект this для функции

setTimeout((function() { return function() { $(this).parent().hide(); } })(), 5000);

или

var func = function() { $(this).parent().hide(); };
setTimeout(func.bind(this), 5000);

(я не очень хорошо знаю coffeescript, так что, надеюсь, это правильный эквивалент JS)

Как sidenote, разве в jquery нет функции для отсрочки анимации, подобной этой?

1 голос
/ 08 июля 2011

CoffeeScript имеет ключевое слово «do», которое «немедленно вызывает переданную функцию».Здесь должно помочь.

$('.foo').live 'click', -> 
  foo = $(this)
  do foo ->
    setTimeout (()->foo.parent().hide()), 5000
0 голосов
/ 08 июля 2011

$(this) для функций. Поэтому $(this) здесь не указывает $('.foo') объект. Сначала вы должны кэшировать этот объект в некоторой переменной, а затем передать эту переменную в setTimeout функцию.

что-то вроде:

 var foo = $('.foo');
 setTimeout(foot.parent().hide(), 5000);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...