修改容器的 innerHTML 属性时元素引用中断
通过代码创建元素时,我遇到了一个问题:修改元素的 innerHTML
属性会破坏对修改之前注入到已修改元素中的其他元素的任何引用。
我这里有一个测试用例: http://jsfiddle.net/mJ7bF/1/ 其中我期望 link1
引用的行为与 link2
完全相同。
第二个测试用例是相同的代码,但我没有使用 innerHTML
属性添加
标记,而是使用对象创建换行符。此测试的行为符合预期: http://jsfiddle.net/K4c9a/2/
我的问题不是关于这个特定的代码,但它背后的概念:第一个测试用例中的 link1
引用会发生什么?如果它不引用 cont
节点注入到文档中时可见的 HTML/DOM 节点,那么它引用什么,以及它如何适应 javascript 的 ByReference 性质物体?
When creating elements via code, I have encountered an issue where modifying the innerHTML
property of an element breaks any references to other elements that are injected into the modified element prior to the modification.
I have a test case here: http://jsfiddle.net/mJ7bF/1/ in which I would expect the link1
reference to behave exactly as link2
does.
This second test case is the same code, but instead of using the innerHTML
property to add the <br>
tag, I create the line break with an object. This test behaves as expected: http://jsfiddle.net/K4c9a/2/
My question is not regarding this specific code, but the concept behind it: what happens to the link1
reference in that first test case? If it doesn't refer to the HTML/DOM node that is visible when the cont
node is injected into the document, what DOES it refer to, and how does this fit in with the ByReference nature of javascript objects?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里很少有东西。
首先。字符串是不可变的,因此
element.innerHTML += "
相当于完整的读取和重写。"
其次,为什么这不好:
除了性能之外,mootools(和 jquery,就此而言)还为所有引用的元素分配特殊的唯一顺序 uid。您通过调用选择器或创建元素等来引用元素。
然后考虑带有
uid
的特定元素,例如 5。uid
链接到一个名为存储位于闭包后面(因此它是私有的)。它以
uid
作为键。然后元素存储在
element.store("key", value")
和element.retrieve("key")
上工作,最后,为什么这很重要:
events
被存储到元素存储中(例如,Storage[5]['events']) - 如果您好奇的话,可以执行 element.retrieve("events") 并在 fireBug 中探索它。旧元素就不再存在了。重新创建,但事件处理程序和对之前绑定的函数的引用将不再起作用,因为它现在将获得一个新的 uid ,
仅此而已,希望
添加 br 是有意义的。
new Element("br").inject(element)
相反,或者为该批次创建一个模板化片段(最快)并添加 1 个大块,然后添加事件。few things here.
first of all. strings are immutable hence doing
element.innerHTML += "<br>"
acts as a complete read and rewrite.second, why that is bad:
aside from performance, mootools (and jquery, for that matter) assigns special unique sequential uids to all referenced elements. you reference an element by calling a selector on it or creating it etc.
then consider that SPECIFIC element with
uid
say 5. theuid
is linked to a special object calledStorage
that sits behind a closure (so its private). it has theuid
as key.element storage then works on a
element.store("key", value")
andelement.retrieve("key")
and finally, why that matters:
events
are stored into element storage (eg, Storage[5]['events']) - do element.retrieve("events") and explore that in fireBug if you're curious.when you rewrite the innerHTML the old element stops existing. it is then recreated but the event handler AND the reference to the function that you bound earlier will no longer work as it will now get a NEW
uid
.that's about it, hope it makes sense.
to add a br just do
new Element("br").inject(element)
instead or create a templated fragment for the lot (fastest) and add in 1 big chunk, adding events after.HTML 在内部由 DOM 对象结构表示。有点像传统编程语言中的 Tree 类。如果设置innerHTML,父节点中的先前节点将被销毁,新的innerHTML将被解析,并创建新的对象。参考文献不再相同。
上面的 div 对象包含一个 Anchor 对象作为子对象。现在设置变量 link1 作为对此 Anchor 对象地址的引用。那么.innerHTML就是
+= "
,这意味着div的所有节点都被移除,并根据.innerHTML的新值的解析结果动态地重新创建。现在旧的引用不再有效,因为 Anchor 标记已重新创建为新的对象实例。"
HTML is represented internally by a DOM object structure. Kind of like a Tree class in traditional programming languages. If you set innerHTML, the previous nodes in the parent node are destroyed, the new innerHTML is parsed, and new objects are created. The references are no longer the same.
The div object above contains an Anchor object as a child. Now set a variable link1 as a reference to the address of this Anchor object. Then the .innerHTML is
+= "<br />"
, which means all of the nodes of div are removed, and recreated dynamically based on the parsed result of the new value of .innerHTML. Now the old reference is no longer valid because the Anchor tag was re-created as a new object instance.