2009-12-18 2 views
1

Хотя я сама проблема, казалось бы, решена, я надеюсь, что кто-то может пролить некоторый свет на почему этого ...JQuery .remove() вызов в функции обратного вызова запускает бесконечный цикл

Ниже приведены два снимка той же функции, задачей которой является удаление div, содержащего сообщение обратной связи с пользователем. Это настройка для использования дополнительного тайм-аута, если задан тайм-аут, он делает вызов самому себе, используя setTimeout(), который затем удаляет div.

Единственное различие между этими двумя версиями функции, где this.remove() называется - в версии проблемы я отправить сообщение в журнал с помощью blackbirdjs первого, а затем вызвать this.remove() - после того, как это выполняется, журнал заполняется бесконечными лог-сообщениями «Удаление обратной связи ...» так же быстро, как браузер может их перекачивать.

В рабочей версии, однако, я просто отменяю порядок, и все выполняется нормально и все хорошо ...

Я ошеломлен, я думаю, что порядок в этом случае будет тривиальным, но, по-видимому, нет. Может ли кто-нибудь пролить свет на то, почему это произойдет? Является ли это ошибкой jQuery или проблемой с blackbird или какой-то странной причудой JavaScript вообще?

Примечание:
я имел некоторый смешанный успех с помощью вызова для подтверждения() - если это возвратилось ложь, я сказал ей вернуться, и это остановило его - однако, просто добавив возвращение после вызова удалить не имело никакого эффекта ,

Интересно, что любая версия, похоже, отлично работает в IE8 - так это может быть проблема firefox/gecko?

Проблема Код:

function clear_feedback(target_container, timeout){ 
    log.debug("timeout: " + timeout); 
    log.debug("target_container: " + target_container); 

    if(timeout == undefined){ 
     log.info("removing target..."); 

     $(target_container).children(".update_feedback").slideUp("slow", 
      function() { 
       log.info("Removing feedback div..."); 
       this.remove(); 
      } 
     ); 
    } 
    else{ 
     log.info("Setting timeout, THEN removing target..."); 

     setTimeout("clear_feedback('" + target_container + "')", timeout); 
    } 
} 

Рабочий код:

function clear_feedback(target_container, timeout){ 
    log.debug("timeout: " + timeout); 
    log.debug("target_container: " + target_container); 

    if(timeout == undefined){ 
     log.info("removing target..."); 

     $(target_container).children(".update_feedback").slideUp("slow", 
      function() { 
       this.remove(); 
       log.info("Removing feedback div..."); 
      } 
     ); 
    } 
    else{ 
     log.info("Setting timeout, THEN removing target..."); 

     setTimeout("clear_feedback('" + target_container + "')", timeout); 
    } 
} 

ответ

1

Вы должны были проверить консоль ошибок браузера, а не просто полагаться на консоль blackbirdjs.

Тогда вы бы заметили, что консоль ошибок браузеров залиты сообщениями об ошибках тоже (с любым из ваших версий коды)

Реальная проблема в вашем коде

this.remove(); 

this является HTML DOM в функции обратного вызова и не имеет функции remove(), поэтому дети только скрываются, но не удаляются. А на this.remove() вы получаете исключение. Поскольку функция обратного вызова генерирует исключение, jQuery заканчивается в бесконечном цикле, пытаясь выполнить свое задание

Что вам нужно сделать, это обернуть элемент в объект jQuery.

$(this).remove(); 

Теперь это также понятно, почему второй вариант, похоже, исправлена ​​ошибка

log.info("Removing feedback div..."); //error logged 
this.remove(); //exception 

this.remove(); //exception 
//log line not executed as previous line threw exception 
log.info("Removing feedback div..."); 

Тот факт, что JQuery даже заканчивается в и бесконечный цикл, и если это правильно поведение является дискуссионным и требует более глубокого изучения во внутренних функциях jQuery. Но это не представляет интереса для вас

Для тех, кто заинтересован есть realted билет ошибка

http://dev.jquery.com/ticket/2846

+0

gah ..../head-slam-on-desk У меня не было возможности проверить это еще и, вероятно, не будет на следующее время (потребовалось несколько лет, чтобы рождественские каникулы начались для меня с пятницы), но после прочтения этого ошибка кажется довольно ясной ... ошибка новобранец. –

+0

Извините за долгую задержку - первый день назад на работе. Большое спасибо! –

0

Я видел проблему так же, как это, но в другом контексте; однако я подозреваю, что коренная причина такая же.

Если вы посмотрите на log.info, вы увидите, что он вставляет узел в DOM. Если одна из функций jquery проходит через DOM только в правильном месте, в частности, прямо в месте, где log.info вставляет узел, а затем, если это вызывает вызов обратного вызова, ваш обратный вызов будет вставлять другой узел, и вы оказываетесь в бесконечном цикле.

Вопрос о том, почему этого не происходит в IE8, вероятно, будет одной из двух причин: либо структура DOM не совсем одинакова в браузерах, либо IE8 использует другую стратегию для обработки вставки узла DOM, в то время как javascript код перемещается по дереву.

Возможно, вы попытаетесь использовать Firebug, разместив точки останова вокруг проблемных линий, а затем просмотрите дерево DOM, чтобы увидеть, можете ли вы обнаружить такое поведение.

+0

Cool - спасибо за информацию - я буду исследовать и пусть вы знаете, что, если что-нибудь, я найти. –

Смежные вопросы