2012-05-26 3 views
2

Я просто тестирую замену целой страницы другой страницей с использованием JavaScript и I found this answer с document.write. Что касается того, почему document.write, мне нужно было заменить весь HTML, включая скрипты и стили, используя одну и ту же страницу.document.write и делегированный обработчик обработчика событий

Он делает то, что я хочу, но я не могу показаться, что он совместим с обработчиками событий. Мои обработчики все подключенные к document с помощью:

$(document).delegate(...); 

В настоящее время у меня есть странные результаты. In a fiddle I made, он прикрепляет обработчик. При щелчке событие срабатывает, перезаписывает страницу, снова запускает функцию, но не прикрепляет обработчик.

Однако в моем проекте я выполняю ту же процедуру (d.w(), а затем добавляю обработчики). Он повторно подключается, и обработчики работают, но после выполнения второй процедуры (все еще на той же странице) она больше не прикрепляется.

Так что мои вопросы:

  • При использовании d.w(), делают существующие обработчики стираются из document?
  • Есть window а также document то же после последующих d.w() s? или они как-то «обновлены»
  • Есть ли скрипты, которые уже разобраны, остаются в памяти и запускаются после последующих d.w()? Или они тоже стираются?
+1

'$ (документ) .find ("пролетных")' возвращает '1' в обоих случаях, когда' patch' запущен, но почему-то '.delegate' не работает во второй раз. – pimvdb

ответ

6

(Нижеследующее относится к Google Chrome)

Только document очищается, сценарии в памяти все еще остаются теми же. Вы можете легко протестировать его, установив что-то в переменную и посмотреть, существует ли она после очистки документа с помощью .open.

Старый родной обработчик поэтому потерян из документа, но jQuery все еще считает, что обработчик существует в собственной модели событий. Вы можете увидеть его редактирование журнала для:

console.log('patch', JSON.stringify($.cache)); 

JQuery только когда-либо присоединяет один родной обработчик каждого события, так что если у вас есть "click" события, зарегистрированное на document, дополнительные обработчики, присоединенные с JQuery не придают новые native handler, вместо этого обработчик вставляется в массив внутренних обработчиков jQuery.

Теперь, потому что document.open удалили родную обработчик, но не ясно, JavaScript, JQuery до сих пор думает, что родной обработчик существует, и далее .delegate идет только в массив внутреннего обработчика JQuery. Если вы замените обработчик на обычный старый document.onclick, вы увидите, что он начинает работать.

Вы можете также сохранить с помощью JQuery, если добавить $(document).unbind() (или более надежные $.cache = {};, но это внутреннее и может меняться) до .delegate, так что Jquery снова синхронизируются. Иначе этого не будет, так как не имеет понятия, вы вызвали document.open.

Итак:

  1. Да
  2. Они все те же объекты, могут быть проверены путем сохранения ссылки и проверки, что agaist document после .open
  3. Они остаются в памяти.

http://jsfiddle.net/wphzt/4/

+0

+1, спасибо за информационный пост. Я сделал некоторую отладку - соответствующий код кажется [здесь] (https://github.com/jquery/jquery/blob/master/src/event.js#L109). Очередь все еще находится в памяти jQuery, поэтому она больше не будет вызывать 'addEventListener', но на самом деле обработчик * был удален, поскольку документ очищен. В результате дальнейшие клики вообще не регистрируются. – pimvdb

+0

Ах, я вижу. Поэтому jQuery по-прежнему считает, что он существует из-за его собственных записей. Это многое объясняет. Благодаря! – Joseph

+0

Интересно, если я удалю запись 'document' из' jQuery.cache' перед назначением обработчика ... 'var cache_idx = document [$. Expando]; if ($ .cache [cache_idx]) {удалить $ .cache [cache_idx]; } '... Следующая попытка вызвать обработчик приводит к ошибке в Firefox' попытка запуска скрипта компиляции и хоста на очищенной области @ jquery.min.js: 3' Не уверен, что это значит. http://jsfiddle.net/wphzt/5/ –

0

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

document.write('<span>'+(++i)+'</span>'); 

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