我正在尝试“保留”DOM的子树以供以后使用,并根据一些用户操作(我最初创建并使用DocumentFragment操作然后附加到DOM的子树)重新出现,但我不知道我想在DOM中的某处附加并隐藏它,因为对它的进一步操作(在我的情况下很重)操作较慢并且会引起布局重排和进一步的性能影响。
是否有跨浏览器方式(我关心的IE11 +)将一些DOM子树转换回DocumentFragment?没有通过搜索SO或文档找到任何东西。
谢谢
答案 0 :(得分:0)
我建议将您感兴趣的节点保存在数组中。 DocumentFragment更方便,而不像NodeList或HTMLCollection那样令人讨厌。
将“东西”转换为documentFragments的小实用程序。
function fragmentFlush(state){
if(state.text){
state.fragment.appendChild(document.createTextNode(state.text));
state.text = "";
}
return state.fragment;
}
function fragmentIterate(state, value){
if( value instanceof Node ){
fragmentFlush(state).appendChild(value);
}else if(Array.isArray(value)){
value.reduce(fragmentIterate, state);
}else if(value === Object(value)){
fragmentIterate(state, Array.from(value));
}else if(value != null){
state.text += value;
}
return state;
}
function fragment(value){
return fragmentFlush(fragmentIterate({
text: "",
fragment: document.createDocumentFragment()
}, value));
}
“things”因为它遍历任何(非循环)arraylike结构以找到您传递的节点并从中构建(展平的)documentFragment。
(原始值转换为TextNodes,忽略null
和undefined
)
var setA = [/*...*/];
var frag = fragment([
"setA: ", setA,
condition? "some more text": null, //null values are ignred
"setB: ", someNode.children,
//that's why I made this traverse recursively
//so that I can "concat" lists like the following line
//without having to actually concat them
"setC: ", [setA, anotherSet, /* moreNodes */, andAnotherSet]
]);
node.appendChild(frag);
再次注意,不处理循环引用!
关于这三个函数,我刚刚从我的一个库中提取了这个函数。您可能希望将其放入模块中,只导出fragment
或将其包装到IIFE中。