对于 DOM 操作,哪个更好 - DOM API 还是innerHTML?

发布于 2024-09-13 10:25:08 字数 460 浏览 3 评论 0原文

我有以下代码:

tr = document.createElement("tr");
root.appendChild(tr);
td = document.createElement("td");
td.appendChild(document.createTextNode("some value"));
tr.appendChild(td);

嗯,这段代码与第一个版本相同

root.innerHTML = "<tr><td>some value</td></tr>";

可能是更好的方法,因为浏览器不必呈现字符串。但它太长了。特别是对于更大的结构,这种实现变得非常难以阅读。所以我觉得有更好的方法来编写这个(没有任何 JavaScript 库)。您将如何实现这一点以使代码更具可读性? (现在我将代码与注释分开。)

I have the following code:

tr = document.createElement("tr");
root.appendChild(tr);
td = document.createElement("td");
td.appendChild(document.createTextNode("some value"));
tr.appendChild(td);

Well, this code is same as

root.innerHTML = "<tr><td>some value</td></tr>";

The first version is probably a better way to go, because the browser does not have to render a string. But it is too long. Especially for bigger structures, this implementation is becoming really hard to read. So I felt like there is a better way to write this (without any JavaScript library). How would you implement this so the code would be more readable? (Right now I am separating code with comments.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

疯到世界奔溃 2024-09-20 10:25:08

您始终可以围绕笨重的 DOM API 编写包装函数,以使代码更具可读性。我通常使用类似的东西:

function newElement (type,attr,children) {
    var el = document.createElement(type);
    for (var n in attr) {
        if (n == 'style') {
            setStyle(el,attr[n]); /* implementation of this function
                                   * left as exercise for the reader
                                   */
        }
        else {
            el[n] = attr[n];
        }
    }
    if (children) {
        for (var i=0; i<children.length; i++) {
            el.appendChild(children[i]);
        }
    }
}
function newText (text) {
    document.createTextNode(text);
}

然后你可以编写更多的声明性代码:

var tr = newElement('tr',{},[
    newElement('td',{},[
        newText('some value')
    ])
]);

只要记住 css 和 javascript 之间的差异:

var div = newElement('div',{
    className:'foo',
    style:{
        marginLeft:'10px'
    }
},[
    newText('notice we use "className" instead of class" '+
            'and "marginLeft" instead of "margin-left"')
]);

You could always write wrapper functions around the clunky DOM API to make the code more readable. I usually use something like:

function newElement (type,attr,children) {
    var el = document.createElement(type);
    for (var n in attr) {
        if (n == 'style') {
            setStyle(el,attr[n]); /* implementation of this function
                                   * left as exercise for the reader
                                   */
        }
        else {
            el[n] = attr[n];
        }
    }
    if (children) {
        for (var i=0; i<children.length; i++) {
            el.appendChild(children[i]);
        }
    }
}
function newText (text) {
    document.createTextNode(text);
}

Then your can write much more declarative code:

var tr = newElement('tr',{},[
    newElement('td',{},[
        newText('some value')
    ])
]);

Just remember the differences between css and javascript:

var div = newElement('div',{
    className:'foo',
    style:{
        marginLeft:'10px'
    }
},[
    newText('notice we use "className" instead of class" '+
            'and "marginLeft" instead of "margin-left"')
]);
瀞厅☆埖开 2024-09-20 10:25:08

innerHTML 绝对比 DOM 快(参见讨论部分) 。前段时间,我遇到了一种用 innerHTML 方便地编写大型 HTML 结构的方法,比字符串连接要好一点,或者必须编写大型结构:

var html = [
   '<ul class="myclass">',
      '<li class="item">item1</li>',
      '<li class="item">item2</li>',
      '<li class="item">item3</li>',
      '<li class="item">item4</li>',
      '<li class="item">item5</li>',
   '</ul>'
].join("");

root.innerHTML =html;

innerHTML is definitely faster than DOM (see discussion section). Some time ago, I came across a way to conveniently write large HTML structures with innerHTML, it's a little better that string concatenation, or having to write large structures:

var html = [
   '<ul class="myclass">',
      '<li class="item">item1</li>',
      '<li class="item">item2</li>',
      '<li class="item">item3</li>',
      '<li class="item">item4</li>',
      '<li class="item">item5</li>',
   '</ul>'
].join("");

root.innerHTML =html;
梦明 2024-09-20 10:25:08

正如我在评论中提到的,innerHTML 实际上比创建 DOM 节点更快,但它是非结构化的。

比创建 DOM 节点更快但仍然结构化的方法是使用 DOM 2 表方法:

var tr = root.insertRow(-1);
var td = tr.insertCell(0);
var txt = document.createTextNode("some value");
td.appendChild(txt);
// or simply: td.innerHTML = "some value";

As I've mentioned in the comment, innerHTML is actually faster than creating DOM nodes, but it is unstructured.

A faster method than creating DOM nodes, but still structured, is to use the DOM 2 table methods:

var tr = root.insertRow(-1);
var td = tr.insertCell(0);
var txt = document.createTextNode("some value");
td.appendChild(txt);
// or simply: td.innerHTML = "some value";
旧时浪漫 2024-09-20 10:25:08

嘿,我在这方面迟到了,但想为大家添加此信息。
在一些移动浏览器开发过程中,我遇到了这个问题,我想亲自看看现在哪个更好。

在我的 Android 手机上,这里有一些有趣的结果:

      DOM: 614 / 25
innerHTML: 697 / 542
      DOM: 546 / 18
innerHTML: 639 / 552
      DOM: 604 / 12
innerHTML: 641 / 534
      DOM: 619 / 11
innerHTML: 643 / 554
      DOM: 618 / 13
innerHTML: 655 / 600

第一个数字是添加 2700 个 li 元素的实际执行情况。
而且,更有趣是第二个数字,它是 ol 使用 innerHTML = ''; 刷新这些结果所需的时间

亲自尝试DOM 与innerHTML

Hey, I'm late to the game on this one, but wanted to add this information for you all.
During some mobile browser development this issue came up for me, and wanted to see for myself which is better these days.

On my Android phone here's some interesting results:

      DOM: 614 / 25
innerHTML: 697 / 542
      DOM: 546 / 18
innerHTML: 639 / 552
      DOM: 604 / 12
innerHTML: 641 / 534
      DOM: 619 / 11
innerHTML: 643 / 554
      DOM: 618 / 13
innerHTML: 655 / 600

The first number is the actual execution of adding 2700 li elements.
And, even more interesting is the second number, which is how long it takes the ol to flush out those results using innerHTML = '';

Try for yourself at DOM vs innerHTML.

盛装女皇 2024-09-20 10:25:08

我相信 innerHTML 最初是 IE 的东西。

我也认为你设置了它,因为它不是一种方法,所以第二个例子是

root.innerHTML = "<tr><td>some value</td></tr>";

但是要回答你的问题, innerHTML 更方便,但通常说它更慢。然而,KennyTM 在评论中说它是更快

必须决定性能权衡(可能可以忽略不计)是否值得采用 DOM API 方式或 innerHTML 方式进行。

innerHTML was originally an IE thing, I believe.

I also think you set it, as it is not a method, so that second example would be

root.innerHTML = "<tr><td>some value</td></tr>";

But to answer your question, innerHTML is more convenient, but it is often said to be slower. However, KennyTM says in the comments that it is much faster.

You have to decide if the performance trade off, which may probably be negligible, is worth doing it the DOM API way or the innerHTML way.

挽容 2024-09-20 10:25:08

我会重新排序以使其更具可读性

var d = document;
td = d.createElement("td");
tr = d.createElement("tr");
td.appendChild( d.createTextNode("some value") );
tr.appendChild(td);
root.appendChild(tr);

I would have reordered to make it more readable

var d = document;
td = d.createElement("td");
tr = d.createElement("tr");
td.appendChild( d.createTextNode("some value") );
tr.appendChild(td);
root.appendChild(tr);
心在旅行 2024-09-20 10:25:08

使用 jQuery http://jquery.com/

$('#root tbody').append('<td><td>some value</td></td>');

它甚至会使用正确的 DOM 方法。

编辑:来自 jQuery 文档:

jQuery 是一个快速且简洁的
简化的 JavaScript 库
HTML文档遍历、事件
处理、动画和 Ajax
快速网络交互
发展。 jQuery 的设计目的是
改变你的写作方式
JavaScript。

** 编辑:** 另外,我使上面的示例更加符合 HTML @koby ;)

Use jQuery http://jquery.com/

$('#root tbody').append('<td><td>some value</td></td>');

It will even use the proper DOM methods.

EDIT: From the jQuery docs:

jQuery is a fast and concise
JavaScript Library that simplifies
HTML document traversing, event
handling, animating, and Ajax
interactions for rapid web
development. jQuery is designed to
change the way that you write
JavaScript.

** EDIT:** Also, I made the sample above a little more HTML conformant @koby ;)

≈。彩虹 2024-09-20 10:25:08

您是否尝试过使用 JavaScript 模板引擎?

它们通常通过 innerHTML 注入 HTML 字符串,并且比桌面和移动设备中的 DOM 操作要快得多,同时保持视图和逻辑之间的分离。

我们使用 PURE 完全分离 HTML 标记和 JavaScript 逻辑。设计人员和开发人员可以在相同的源上一起工作。

如果您不喜欢它,您可以在网上找到许多其他可能更适合您口味的产品。

Did you try to use a JavaScript templating engine?

They generally inject HTML strings by innerHTML and are way faster than DOM manipulations in both desktops and mobiles while keeping a separation between view and logic.

We use PURE which totally separates the HTML markup and the JavaScript logic. Designers and developers can work together on the same sources.

If you don't like it, you can find plenty of others on the web that may better suit your taste.

若水微香 2024-09-20 10:25:08

我自己编写了一些测试来比较 innerHTML 和 DOM API。 DOM API 绝对更快。

以下是结果(我在 Firefix 3.6.8 和 Chrome 5.0.375.125 beta 上进行了测试):
http://yilmazhuseyindevelopment.appspot.com/ois/images/ahh5aWxtYXpodXNleWluZ GV2ZWxvcG1lbnRyEQsSCultYWdlRGF0YRiptwUM

在第一个测试时,我使用 DOM API 和innerHTML 将一个文本节点添加到页面正文 1000 次。

在第二个测试中,我使用 DOM API 和内部 HTML 创建了一个表。这是我测试的实际代码:

<html>
    <head>
        <script type="text/javascript">
        window.onload = function(){
            var body = document.getElementsByTagName("body")[0];
            var text,table,tr,td;
            var count = 1000;
            console.time("DOM");
            for(var i = 0 ; i<count ; i++){
                    text = document.createTextNode("text");
                    body.appendChild(text);
                    body.removeChild(text)
            }
            console.timeEnd("DOM");
            console.time("innerHTML");
            for(var i = 0 ; i<count ; i++){
                body.innerHTML = "text";
                body.innerHTML = "";
            }
            console.timeEnd("innerHTML");
            //table structure
            console.time("DOM2");
            for(var i = 0 ; i<count ; i++){
                    table = document.createElement("table");
                    tr = document.createElement("tr");
                    td = document.createElement("td");
                    text = document.createTextNode("text");
                    table.appendChild(tr);
                    tr.appendChild(td);
                    td.appendChild(text);
                    body.appendChild(table);
                    body.removeChild(table);
            }
            console.timeEnd("DOM2");
            console.time("innerHTML2");
            for(var i = 0 ; i<count ; i++){
                body.innerHTML = "<table><tr><td>text</td></tr></table>";
                body.innerHTML = "";
            }
            console.timeEnd("innerHTML2");
        }
        </script>
    </head>

    <body/>
</html>

我想这意味着 DOM API 对于现代浏览器来说更好(性能方面)。

I wrote some tests myself that compares innerHTML and the DOM API. The DOM API was definitely faster.

Here are the results (I have tested on Firefix 3.6.8 and Chrome 5.0.375.125 beta):
http://yilmazhuseyindevelopment.appspot.com/ois/images/ahh5aWxtYXpodXNleWluZGV2ZWxvcG1lbnRyEQsSCUltYWdlRGF0YRiptwUM

In the first test, I added one textnode to body of page 1000 times with the DOM API and innerHTML.

In the second test I created a table with the DOM API and inner HTML. Here is the actual code for my test:

<html>
    <head>
        <script type="text/javascript">
        window.onload = function(){
            var body = document.getElementsByTagName("body")[0];
            var text,table,tr,td;
            var count = 1000;
            console.time("DOM");
            for(var i = 0 ; i<count ; i++){
                    text = document.createTextNode("text");
                    body.appendChild(text);
                    body.removeChild(text)
            }
            console.timeEnd("DOM");
            console.time("innerHTML");
            for(var i = 0 ; i<count ; i++){
                body.innerHTML = "text";
                body.innerHTML = "";
            }
            console.timeEnd("innerHTML");
            //table structure
            console.time("DOM2");
            for(var i = 0 ; i<count ; i++){
                    table = document.createElement("table");
                    tr = document.createElement("tr");
                    td = document.createElement("td");
                    text = document.createTextNode("text");
                    table.appendChild(tr);
                    tr.appendChild(td);
                    td.appendChild(text);
                    body.appendChild(table);
                    body.removeChild(table);
            }
            console.timeEnd("DOM2");
            console.time("innerHTML2");
            for(var i = 0 ; i<count ; i++){
                body.innerHTML = "<table><tr><td>text</td></tr></table>";
                body.innerHTML = "";
            }
            console.timeEnd("innerHTML2");
        }
        </script>
    </head>

    <body/>
</html>

I guess that means the DOM API is better (performance wise) for modern browsers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文