是否可以在不破坏后代的情况下附加到innerHTML? 事件监听器?
在以下示例代码中,我将一个 onclick
事件处理程序附加到包含文本“foo”的范围。 该处理程序是一个匿名函数,它会弹出一个 alert()
。
但是,如果我分配给父节点的 innerHTML
,这个 onclick
事件处理程序就会被销毁 - 单击“foo”无法弹出警报框。
这可以修复吗?
<html>
<head>
<script type="text/javascript">
function start () {
myspan = document.getElementById("myspan");
myspan.onclick = function() { alert ("hi"); };
mydiv = document.getElementById("mydiv");
mydiv.innerHTML += "bar";
}
</script>
</head>
<body onload="start()">
<div id="mydiv" style="border: solid red 2px">
<span id="myspan">foo</span>
</div>
</body>
</html>
In the following example code, I attach an onclick
event handler to the span containing the text "foo". The handler is an anonymous function that pops up an alert()
.
However, if I assign to the parent node's innerHTML
, this onclick
event handler gets destroyed - clicking "foo" fails to pop up the alert box.
Is this fixable?
<html>
<head>
<script type="text/javascript">
function start () {
myspan = document.getElementById("myspan");
myspan.onclick = function() { alert ("hi"); };
mydiv = document.getElementById("mydiv");
mydiv.innerHTML += "bar";
}
</script>
</head>
<body onload="start()">
<div id="mydiv" style="border: solid red 2px">
<span id="myspan">foo</span>
</div>
</body>
</html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
使用
.insertAdjacentHTML()
保留事件侦听器,并且所有主流浏览器都支持。 它是.innerHTML
的简单一行替换。'beforeend'
参数指定元素中插入 HTML 内容的位置。 选项有'beforebegin'
、'afterbegin'
、'beforeend'
和'afterend'
。 他们对应的位置是:Using
.insertAdjacentHTML()
preserves event listeners, and is supported by all major browsers. It's a simple one-line replacement for.innerHTML
.The
'beforeend'
argument specifies where in the element to insert the HTML content. Options are'beforebegin'
,'afterbegin'
,'beforeend'
, and'afterend'
. Their corresponding locations are:不幸的是,即使您尝试追加,对
innerHTML
的赋值也会导致所有子元素被破坏。 如果您想保留子节点(及其事件处理程序),则需要使用 DOM 函数:编辑:鲍勃的解决方案,来自评论。 发表你的答案,鲍勃! 获得荣誉。 :-)
Unfortunately, assignment to
innerHTML
causes the destruction of all child elements, even if you're trying to append. If you want to preserve child nodes (and their event handlers), you'll need to use DOM functions:Edit: Bob's solution, from the comments. Post your answer, Bob! Get credit for it. :-)
现在是 2012 年,jQuery 具有附加和前置函数来完成此操作,添加内容而不影响当前内容。 很有用。
Now, it is 2012, and jQuery has append and prepend functions that do exactly this, add content without effecting current content. Very useful.
我创建了我的标记作为字符串插入,因为它比使用花哨的 dom 内容更少的代码并且更容易阅读。
然后我将其设置为临时元素的innerHTML,这样我就可以获取该元素的唯一子元素并将其附加到主体。
I created my markup to insert as a string since it's less code and easier to read than working with the fancy dom stuff.
Then I made it innerHTML of a temporary element just so I could take the one and only child of that element and attach to the body.
作为一个轻微的(但相关的)旁白,如果您使用 javascript 库(例如 jquery (v1.3))来执行 dom 操作,您可以利用实时事件来设置一个处理程序,例如:
它将应用于该处理 程序在任何类型的 jquery 操作期间始终使用选择器。 对于实时事件,请参阅:docs.jquery.com/events/live 对于 jquery 操作,请参阅:< a href="http://docs.jquery.com/Manipulation" rel="nofollow noreferrer">docs.jquery.com/manipulation
As a slight (but related) asside, if you use a javascript library such as jquery (v1.3) to do your dom manipulation you can make use of live events whereby you set up a handler like:
and it will be applied to that selector at all times during any kind of jquery manipulation. For live events see: docs.jquery.com/events/live for jquery manipulation see: docs.jquery.com/manipulation
还有另一种选择:使用
setAttribute
而不是添加事件侦听器。 像这样:There is another alternative: using
setAttribute
rather than adding an event listener. Like this:是的,如果您直接在模板中使用标签属性
onclick="sayHi()"
绑定事件,就像您的一样,这是可能的- 这种方法类似于 Angular/Vue/React/等框架。 您还可以使用
操作“动态”html,如此处。 它不是严格的不引人注目的js,但对于小型项目来说它是可接受的
Yes it is possible if you bind events using tag attribute
onclick="sayHi()"
directly in template similar like your<body onload="start()">
- this approach similar to frameworks angular/vue/react/etc. You can also use<template>
to operate on 'dynamic' html like here. It is not strict unobtrusive js however it is acceptable for small projects在我看来,丢失事件处理程序是 Javascript 处理 DOM 方式中的一个错误。 为了避免这种行为,您可以添加以下内容:
Losing event handlers is, IMO, a bug in the way Javascript handles the DOM. To avoid this behavior, you can add the following:
最简单的方法是使用数组并将元素推入其中,然后将数组后续值动态插入到数组中。
这是我的代码:
The easiest way is to use an array and push elements into it and then insert the array subsequent values into the array dynamically.
Here is my code:
Element#append
可用于在另一个元素的末尾插入元素。 要从字符串插入 HTML,Range#createContextualFragment<可以使用/code>
。
或者只是附加文本:
如果您不需要直接插入 HTML,请考虑使用 DOM 方法来创建结构:
在相关说明中,相应的
Element#prepend
方法可用于在开头插入元素(第一个子元素之前)一个元素的。Element#append
can be used to insert elements at the end of another element. To insert HTML from a string,Range#createContextualFragment
can be used.Or to just append text:
If you don't need to insert HTML directly, consider using DOM methods to create the structure instead:
On a related note, the corresponding
Element#prepend
method can be used to insert elements at the start (before the first child) of an element.你可以这样做:
You could do it like this:
some.innerHTML += '添加你想要的任何内容';
它对我有用。 我使用此解决方案向输入文本添加了一个按钮
something.innerHTML += 'add whatever you want';
it worked for me. I added a button to an input text using this solution
对于任何带有标头和数据的对象数组。
jsfiddle
https://jsfiddle.网/AmrendraKumar/9ac75Lg0/2/
For any object array with header and data.
jsfiddle
https://jsfiddle.net/AmrendraKumar/9ac75Lg0/2/
我是一个懒惰的程序员。 我不使用 DOM,因为它看起来像是额外的输入。 对我来说,代码越少越好。 以下是我添加“bar”而不替换“foo”的方法:
I'm a lazy programmer. I don't use DOM because it seems like extra typing. To me, the less code the better. Here's how I would add "bar" without replacing "foo":