Ссылка на элемент прерывается при изменении свойства innerHTML контейнера

#javascript #dom #object #mootools #pass-by-reference

#javascript #dom #объект #mootools #передача по ссылке

Вопрос:

При создании элементов с помощью кода я столкнулся с проблемой, когда изменение innerHTML свойства элемента прерывает любые ссылки на другие элементы, которые были введены в измененный элемент до модификации.

У меня здесь есть тестовый пример:http://jsfiddle.net/mJ7bF/1 / в котором я ожидал бы, что link1 ссылка будет вести себя точно так же, как link2 делает.

Этот второй тестовый пример представляет собой тот же код, но вместо того, чтобы использовать innerHTML свойство для добавления <br> тега, я создаю разрыв строки с помощью объекта. Этот тест ведет себя так, как ожидалось: http://jsfiddle.net/K4c9a/2 /

Мой вопрос касается не этого конкретного кода, а концепции, лежащей в его основе: что происходит со link1 ссылкой в этом первом тестовом примере? Если это не относится к узлу HTML / DOM, который виден, когда cont узел вводится в документ, на что это ссылается, и как это согласуется с природой ссылок объектов javascript?

Ответ №1:

здесь есть несколько вещей.

прежде всего. строки неизменяемы, следовательно, выполнение element.innerHTML = "<br>" действует как полное чтение и перезапись.

во-вторых, почему это плохо:

помимо производительности, mootools (и jquery, если уж на то пошло) присваивает специальные уникальные последовательные uid всем элементам, на которые ссылаются. вы ссылаетесь на элемент, вызывая для него селектор или создавая его и т.д.

затем рассмотрим этот КОНКРЕТНЫЙ элемент с uid скажем, 5. uid он связан со специальным объектом с именем Storage , который находится за закрытием (поэтому он частный). у него есть uid ключ as.

затем хранилище элементов работает над element.store("key", value") и element.retrieve("key")

и, наконец, почему это имеет значение: events хранятся в хранилище элементов (например, Хранилище [5][‘events’]) — выполните element.retrieve(«события») и изучите это в fireBug, если вам интересно.

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

вот и все, надеюсь, это имеет смысл.

чтобы добавить br, просто сделайте new Element("br").inject(element) вместо этого или создайте шаблонный фрагмент для партии (самый быстрый) и добавьте 1 большой фрагмент, добавив события после.

Ответ №2:

HTML внутренне представлен структурой объекта DOM. Что-то вроде класса Tree в традиционных языках программирования. Если вы установите innerHTML, предыдущие узлы в родительском узле будут уничтожены, новый innerHTML будет проанализирован и будут созданы новые объекты. Ссылки больше не совпадают.

 div
|-- a..
  

Приведенный выше объект div содержит объект привязки в качестве дочернего элемента. Теперь установите переменную link1 в качестве ссылки на адрес этого объекта привязки. Тогда .innerHTML является = "<br />" , что означает, что все узлы div удаляются и воссоздаются динамически на основе проанализированного результата нового значения .innerHTML. Теперь старая ссылка больше недействительна, потому что тег привязки был воссоздан как новый экземпляр объекта.