jQuery 非常奇怪的行为 - 输出 html 的顺序与附加的顺序不同

发布于 2024-11-18 07:39:11 字数 1002 浏览 2 评论 0原文

我有一个刷新元素队列的函数 - 每个元素都必须由 div 表示,但效果对我来说完全是 WTF。这是函数:

this.refreshQueue = function( ) {
    $("#queue").html('');
    for( var id in self.queue ) {
        console.log('Opening div');
        $("#queue").html( $("#queue").html()+'<div class="queueelement">');
        self.appendUser( self.queue[id].data );
        console.log('Closing div');
        $("#queue").html( $("#queue").html()+'</div>');
    }
} 

this.appendUser = function( data ) {
    console.log('Appending h4');
    $("#queue").html( $("#queue").html()+'<h4>'+data.login +'</h4>' );
}

我在 firebug 日志中看到:

Opening div
Appending h4
Closing div

没关系,但是该操作后的 HTML 看起来像这样:

<div class="queueelement"></div>
<h4>Somelogin</h4>

而不是:

<div class="queueelement">
<h4>Somelogin</h4>
</div>

有什么想法导致此问题吗?

早期我尝试过 .append() - 效果相同。

I have a function that refreshes queue of elements - each one have to be represented by div, but effect is total WTF for me. Here is the function:

this.refreshQueue = function( ) {
    $("#queue").html('');
    for( var id in self.queue ) {
        console.log('Opening div');
        $("#queue").html( $("#queue").html()+'<div class="queueelement">');
        self.appendUser( self.queue[id].data );
        console.log('Closing div');
        $("#queue").html( $("#queue").html()+'</div>');
    }
} 

this.appendUser = function( data ) {
    console.log('Appending h4');
    $("#queue").html( $("#queue").html()+'<h4>'+data.login +'</h4>' );
}

I See in firebug log:

Opening div
Appending h4
Closing div

That's ok, but HTML after that operation looks like that:

<div class="queueelement"></div>
<h4>Somelogin</h4>

Instead of:

<div class="queueelement">
<h4>Somelogin</h4>
</div>

Any ideas what causes this ?

Early i have tried with .append() - same effect.

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

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

发布评论

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

评论(5

别理我 2024-11-25 07:39:11

请参阅文档

此方法使用浏览器的 innerHTML 属性。

您不能先设置开始标签,然后再添加结束标签。浏览器正在通过自动添加结束标签来更正开始标签。

您不只是设置 HTML(作为文本),还会对其进行解析并创建 DOM 元素并将其插入到树中。为了可解析,HTML 必须正确。

无论您使用什么方法,都会发生这种情况。您也可以在控制台中尝试:

> d = document.createElement('div');
  <div>​</div>​
> d.innerHTML = '<span>';
  "<span>"
> d.innerHTML += 'foo';
  "<span></span>foo"
> d.innerHTML += '</span>';
  "<span></span>foo</span>"
> d.innerHTML
  "<span></span>foo"

您必须构建整个字符串并立即插入。

See the documentation:

This method uses the browser's innerHTML property.

You cannot set an opening tag and later add a closing tag. The browser is correcting the opening tag by adding a closing one automatically.

You are not just setting HTML (as text), it is also parsed and DOM elements are created and inserted into the tree. To be parseable, the HTML has to be correct.

This will happen with any method you use. You can also try it in the console:

> d = document.createElement('div');
  <div>​</div>​
> d.innerHTML = '<span>';
  "<span>"
> d.innerHTML += 'foo';
  "<span></span>foo"
> d.innerHTML += '</span>';
  "<span></span>foo</span>"
> d.innerHTML
  "<span></span>foo"

You have to build the whole string and insert it at once.

笑忘罢 2024-11-25 07:39:11

问题是您试图将 HTML 放入 DOM 中,就好像它是 HTML 文档一样。当浏览器读取 HTML 页面时,会将其转换为 DOM 结构。这是一个相关节点的树状系统。它与原始 HTML 有一些相似之处,并且可以对其进行序列化,但您不能只向其中添加 HTML 并期望它像向原始文档添加内容一样工作。

$("#queue").html( $("#queue").html()+'<div class="queueelement">');

这表示“在 HTML 末尾添加一个 div 节点”。由于每个节点都必须关闭或自动关闭,因此浏览器会自动关闭它。

当您稍后添加 时,它是无意义的 - 结束标记不能单独存在,因此它会被忽略。

解决方案是将所有 HTML 添加在一起并一次性插入,或者从 appendUser 中修改 div 元素。

The problem is that you're trying to put HTML into a DOM as if it was an HTML document. When a browser reads an HTML page, it converts it into a DOM structure. This is a tree-like system of related nodes. It bears some resemblance to the original HTML and can be serialised to it, but you can't just add HTML to it and expect it to work as if you were adding content to the original document.

$("#queue").html( $("#queue").html()+'<div class="queueelement">');

That says "add a div node to the end of the HTML". Since every node must be closed or self-closing, the browser automatically closes it.

When you add the </div> later, it is nonsensical -- a closing tag can't exist on its own, so it is ignored.

The solution is to add all the HTML together and insert it in one go, or to modify the div element from within appendUser.

明明#如月 2024-11-25 07:39:11

我认为你必须构建一个字符串并立即输出到 html,而不是使用 .html() 插入未完成的元素。

像这样的东西:

    this.refreshQueue = function () {
        var output = "";
        for (var id in self.queue) {
            output += "<div class=\"queueelement\">";
            output += appendUser(self.queue[id].data);
            output += "<\div>";
        }
        $("#queue").html(output);
    }

    this.appendUser = function (data) {
        return "<h4>" + data.login + "</h4>";
    }

I think you'll have to build a string and output to the html at once, instead of inserting unfinished elements using .html().

Something like this:

    this.refreshQueue = function () {
        var output = "";
        for (var id in self.queue) {
            output += "<div class=\"queueelement\">";
            output += appendUser(self.queue[id].data);
            output += "<\div>";
        }
        $("#queue").html(output);
    }

    this.appendUser = function (data) {
        return "<h4>" + data.login + "</h4>";
    }
下雨或天晴 2024-11-25 07:39:11

html() 自动关闭所有未关闭的标签。因此,当您尝试添加更多 html 时,它已经关闭了 div。为什么不直接使用 wrap() 呢?

self.appendUser( self.queue[id].data ).wrap($('<div />').addClass('queueelement')).parent().appendTo($("#queue"));

您可以让函数本身返回 $('

)' 元素

html() closes any unclosed tags automatically. So when you try and add more html it has already closed the div. Why not just use wrap() ?

self.appendUser( self.queue[id].data ).wrap($('<div />').addClass('queueelement')).parent().appendTo($("#queue"));

You'd have the function itself just return the $('<h4 />)' element

熟人话多 2024-11-25 07:39:11

您还可以将标签放入其自己的变量中,然后将内部字符串添加到该 div 变量中,然后将其附加到容器 div 中。

    var div = $("<div class='elem'></div>");
    div.append("<h4>Some Login</h4>");

    $("#out").append(div);

http://jsfiddle.net/Gz3qR/

You could also put the tag into its own variable and then add your inner string to that div variable, and then append it to a container div.

    var div = $("<div class='elem'></div>");
    div.append("<h4>Some Login</h4>");

    $("#out").append(div);

http://jsfiddle.net/Gz3qR/

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