说我有这样的清单:
<ul id='dom_a'>
<li>foo</li>
</ul>
我知道如何在ul标签中插入元素:
Element.insert('dom_a', {bottom:"<li>bar</li>"});
由于我收到的字符串包含dom id,我需要插入内部HTML 而不是整个元素。我需要一个函数来执行此操作:
insert_content('dom_a', {bottom:"<ul id='dom_a'><li>bar</li></ul>"});
获得:
<ul id='dom_a'>
<li>foo</li>
<li>bar</li>
</ul>
我应该如何使用Prototype?
以下是我提出的解决方案,有人能做得更好吗?
Zena.insert_inner = function(dom, position, content) {
dom = $(dom);
position = position.toLowerCase();
content = Object.toHTML(content);
var elem = new Element('div');
elem.innerHTML = content; // strip scripts ?
elem = elem.down();
var insertions = {};
$A(elem.childElements()).each(function(e) {
insertions[position] = e;
dom.insert(insertions);
});
}
答案 0 :(得分:2)
我认为您可以解析变量中的代码块,然后询问它的innerHTML,然后使用insert将其粘贴到DOM中实际节点的底部。
这可能是这样的:
var rep_struct = "<ul id='dom_a'><li>bar</li></ul>";
var dummy_node = new Element('div'); // So we can easily access the structure
dummy_node.update(rep_struct);
$('dom_a').insert({bottom: dummy_node.childNodes[0].innerHTML});
答案 1 :(得分:1)
我认为只需附加临时元素第一个子节点的innerHTML
,就可以缩减代码:
Zena.insert_inner = function(dom, position, content) {
var d = document.createElement('div');
d.innerHTML = content;
var insertions = {};
insertions[position] = d.firstChild.innerHTML;
Element.insert(dom, insertions);
}
虽然没有太大的改进,example here。
答案 2 :(得分:0)
我一直在查看原型文档,我发现了这个:update function。
顺便说一下,您可以使用更新功能来查找当前bottom
内容,然后通过添加所需代码和以前存储的代码来更新它(就像innerHTML一样)。
答案 3 :(得分:0)
您可以使用正则表达式去除外部元素。
Element.Methods.insert_content = function(element, insertions) {
var regex = /^<(\w+)[^>]*>(.*)<\/\1>/;
for (key in insertions) {
insertions[key] = regex.exec(insertions[key])[2];
}
Element.insert(element, insertions);
};
Element.addMethods();
$('dom_a').insert_content({bottom:"<ul id='dom_a'><li>bar</li></ul>"});
答案 4 :(得分:0)
如果您使用的是PrototypeJS,您可能还想将script.aculo.us添加到您的项目中。 script.aculo.us中的Builder提供了一种构建复杂DOM结构的好方法,如下所示:
var myList = Builder.node("ul", {
id: "dom_a"
},[
Builder.node("li", "foo"),
Builder.node("li", "bar"),
]);
在此之后,您可以使用任何插入/更新函数(PrototypeJS)或甚至标准JavaScript appendChild插入此对象,该对象应该在DOM中的任何位置呈现为HTML。
$("my_div").insert({After: myList});
请注意,在PrototypeJS中,插入有4种不同的模式:After,Before,Top和Bottom。如果使用insert而不指定上述“模式”,则默认值为Bottom。也就是说,新的DOM代码将作为 innerHTML附加在下面容器元素的现有内容中。 Top将执行相同的操作,但将其添加到现有内容之上。之前和之后也是很酷的方式来附加到DOM。如果您使用这些内容,则内容将添加到容器元素之前和之后的DOM结构中,而不是内部作为innerHTML。
然而,使用Builder,有一件事需要记住,...好吧两件事: 一世。您不能在对象中输入原始HTML作为内容...这将失败:
Builder.node("ul", "<li>foo</li>");
II。当您指定节点属性时,请记住必须使用className来表示HTML属性类(并且可能还有htmlFor for for属性...虽然对于属性似乎在HTML5中被弃用(?),但是谁不想使用它用于标签)
Builder.node("ul", {
id: "dom_a",
className: "classy_list"
});
我知道你因为我的观点而挠头。 &GT; 什么,没有原始的HTML,dang! 不用担心。如果您仍然需要在Builder创建的DOM中添加可能包含HTML的内容,只需在第二阶段使用insert({Before / After / Top / Bottom:string})执行此操作。但是你为什么要在第一时间做呢?如果您为所有函数编写了一个生成各种DOM元素而不是拼接各种字符串的函数,那将是非常好的做法。前一种方法将是整洁和优雅的。这类似于内联样式与类类型的问题。好的设计毕竟应该从 meta 内容中分离内容,或者格式化标记/降价。
在您的工具箱中保持方便的最后一件事是Protype的DOM遍历,以防您想要动态插入和删除HTML Houdini等内容。查看元素next,up,down,previous方法。除了$$之外,使用起来也很有趣,特别是如果你知道CSS3选择器。