Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 一种更有效的解析dom元素的方法?_Javascript_Dom - Fatal编程技术网

Javascript 一种更有效的解析dom元素的方法?

Javascript 一种更有效的解析dom元素的方法?,javascript,dom,Javascript,Dom,我有一些HTML需要解析 基本上,我正在遍历给定元素的dom。抓取文本节点和元素节点 当我遇到文本节点时,我会逐个字符地将它们打印到不同的元素中。每个字符都被放置在自己的范围内,并具有自己的样式,该样式取自任何附加样式的元素节点 因此,当找到一个元素节点时,它的样式将应用于检测到的任何文本节点,直到找到另一个元素节点并用新样式替换旧样式 下面的代码可以工作。如果源元素中有一个句子或短段落,它会在不到一秒钟的时间内准确地复制文本。文本越长,花费的时间就越长(duh) 有趣的是,目标元素中已经存在的

我有一些HTML需要解析

基本上,我正在遍历给定元素的dom。抓取文本节点和元素节点

当我遇到文本节点时,我会逐个字符地将它们打印到不同的元素中。每个字符都被放置在自己的范围内,并具有自己的样式,该样式取自任何附加样式的元素节点

因此,当找到一个元素节点时,它的样式将应用于检测到的任何文本节点,直到找到另一个元素节点并用新样式替换旧样式

下面的代码可以工作。如果源元素中有一个句子或短段落,它会在不到一秒钟的时间内准确地复制文本。文本越长,花费的时间就越长(duh)

有趣的是,目标元素中已经存在的文本越多,花费的时间就越长。因此,如果我在同一个源元素上运行了10次这个函数,并且处理了相同的文本体,那么第10次到第1次到第10次的运行速度会比第1次到第1次慢,这可能是因为在一个已经有内容的元素中渲染文本比较困难

不管怎样,我真的需要找到一种方法让它运行得更快

最后,这是一个可能需要处理的HTML代码片段示例:

<span style='blah: blah;'> Some text </span><span>Even more text </span> <p> stuff </p>
一些文本甚至更多文本东西

生成的HTML将是:

<span style='blah: blah;'>S</span>
<span style='blah: blah;'>o</span>
<span style='blah: blah;'>m</span>
<span style='blah: blah;'>e</span>
<span style='blah: blah;'> </span> 
<span style='blah: blah;'>t</span>
<span style='blah: blah;'>e</span>
<span style='blah: blah;'>x</span>
<span style='blah: blah;'>t</span> 
.......
S
o
M
E
T
E
x
T
.......
没什么特别的

代码如下:

代码:

ed.rta\u to\u arr\u paste=函数(ele,cur\u样式){
var child_arr=ele.childNodes;
如果(!(已设置(当前样式))){
cur_style={};
}
对于(变量i=0;i
编辑:
谷歌文档就是这样一个例子

当用户将文本粘贴到文档中时,它首先在屏幕外呈现,然后使用与此类似的函数(我假设)进行处理。然后重新打印文档中的文本。
这一切发生得非常快(除非文本很长)。

看起来每次调用都在DOM中搜索一个元素。我认为您应该将事件附加到类似onload的DOM元素中(或者更好地使用jquery document.ready)。在调用for循环之前,我还要(作为一个小的重构)首先检查以确保您有子元素(child_arr.length>0)(这可能是完全不重要的,但最佳实践)

看起来您在每次调用时都在DOM中搜索一个元素。我认为您应该将事件附加到类似onload的DOM元素中(或者更好地使用jquery document.ready)。在调用for循环之前,我还要(作为一个小的重构)首先检查确保您有子对象(child_arr.length>0)(这可能是完全不重要的,但却是最佳实践)

看起来您是在直接将新元素插入DOM树,所以我认为您可以通过不这样做获得最佳改进

避免逐个插入大量元素。每次插入元素时,浏览器都必须重新计算页面布局,这需要时间

相反,将节点添加到不在DOM中的元素中,最好使用,可以通过创建

然后你所要做的就是插入这个片段,浏览器只需要重新计算一次

更新:

您还可以尝试使用正则表达式将文本转换为
span
元素

var html = value.replace(/(.)/g, "<span>$1</span>")

似乎您正在直接将新元素插入DOM树中,因此我认为您可以通过不这样做获得最佳的改进

避免逐个插入大量元素。每次插入元素时,浏览器都必须重新计算页面布局,这需要时间

相反,将节点添加到不在DOM中的元素中,最好使用,可以通过创建

然后你所要做的就是插入这个片段,浏览器只需要重新计算一次

更新:

您还可以尝试使用正则表达式将文本转换为
span
元素

var html = value.replace(/(.)/g, "<span>$1</span>")

你能提供一个演示吗?不知怎的,我很难理解你想要做什么…由于保密协议特别严格,我无法发布演示。检查编辑,也许会有帮助。@Tyler:at的演示会很有帮助,即使你只是删掉专有函数,这样它们基本上可以进行相同的处理,而不暴露你的代码。
add\u single\u char
在做什么?如何将下一个字符添加到元素中?通过减少元素的属性访问,您已经可以节省“一些”时间。它会将child_arr[i].nodeValue.charAt(n)处的字符添加到目标元素(在本例中为div)。它会返回为包含该字符而创建的跨度。您能提供一个演示吗?不知怎的,我很难理解你想要做什么…由于保密协议特别严格,我无法发布演示。检查编辑,也许会有帮助。@Tyler:at的演示会很有帮助,即使你只是删掉专有函数,这样它们基本上可以进行相同的处理,而不暴露你的代码。
add\u single\u char
在做什么?如何将下一个字符添加到元素中?您已经可以通过减少元素的属性访问来节省“一些”时间。它将child_arr[i].nodeValue.charAt(n)处的字符添加到目标元素中,在本例中该元素是div。它返回在
ed.rta_to_arr_paste = function(ele, cur_style) {

    var child_arr = ele.childNodes;

    if(!(is_set(cur_style))) {
        cur_style = {};
    }

    for(var i = 0, l = child_arr; i <l; i++) {
        var child = child_arr[i];
        if(child.nodeType == 1) {
            // this will always be true, because `el.style` returns an object
            // so comparing it does not make sense. Maybe just override it always
            if(cur_style != child.style) { 
                cur_style = child.style;
            }
            // doesn't need to be called for other nodes
            ed.rta_to_arr_paste(child, cur_style); 
        } 
        else if(child.nodeType == 3) {
            var value = child.nodeValue;
            for(var n = 0, ln = value.length; n < ln; n++) {
                ed.add_single_char(value.charAt(n), cur_style);
            }
        }       
    }
}