【问题标题】:HTML element in memory and display problem after inserting it to DOM内存中的 HTML 元素和插入到 DOM 后的显示问题
【发布时间】:2011-03-19 10:11:36
【问题描述】:

当我们在 Firefox 下运行以下脚本时...

var d = $("<div class='test'></div>");
d.hide();
$("body").prepend(d);
d.show();

...查看 HTML,这个插入的元素将具有 style 属性:

style="display: block;"

在 Webkit 下,元素将具有:

style="display: none;"

这个场景在我开发的一个 JavaScript 组件中使用。该组件的内部变量中有一组 HTML 元素,并将它们插入到指定的目标容器中。

因为在 style 属性中初始化了 display-property 的插入元素,它会覆盖 CSS。这会破坏页面的布局。

作为一种快速的解决方案,我可以在元素插入 DOM 之前存储“样式”属性,并且在插入之后,将存储的版本写入创建的版本。

有没有更好的解决方案?

为什么会发生这种情况以及我如何检查元素是否还没有插入到 DOM 中

【问题讨论】:

    标签: javascript jquery css dom


    【解决方案1】:

    When I do that 使用 Chrome 或 Safari(都是基于 WebKit 的浏览器),如果我使用内置工具检查元素,它根本没有 style.display 属性,因此默认的 div 样式使用display: block。 (Here's a version 在 div 中有一些文本,因此使用 DOM 检查器更容易查看和查找。)

    所以我怀疑问题出在其他地方。例如,是否存在可能在 WebKit 上失败的干预代码,从而使 d.show(); 永远不会被调用?那肯定会解释的。使用 Chrome 或 Safari 中的内置工具很容易在创建 div 的代码上设置断点并遍历它。

    你的问题:

    ...如何检查元素是否尚未插入 DOM?

    这个问题最近在 StackOverflow 上被问到,其中一个特定于 jQuery 的答案相当优雅:

    if (d.closest("body").length == 0) {
        // It's not in the DOM yet
    }
    

    更新:在下方回复您的评论

    用 Firefox 查看这个测试页面。 div 有“style=display:block;”明确定义。在 Webkit 下,它的样式属性为空。我在 Firefox 和 Safari 中都使用了内置检查器。

    啊,好吧,所以问题不在于 WebKit 浏览器中的 display: none(您在问题中关于该问题的陈述使我误入歧途),而是 Firefox(可能还有其他 Gecko 浏览器)最终具有 display: block在元素上。

    我可能会这样处理:

    var d = $("<div class='test'></div>");
    d.addClass("hidden");
    $("body").prepend(d);
    d.removeClass("hidden");
    

    ...使用这个 CSS:

    .hidden {
        display: none;
    }
    

    Live copy

    这样,您知道您根本不会设置style.display 属性。


    更新 2:您可以做的另一件事是直接删除 style.display 属性:

    var d = $("<div class='test'>Hi there</div>");
    d.hide();
    $("body").prepend(d);
    d.show();
    d[0].style.display = "";
    

    Live example

    你提到了效果,所以如果你正在做 fadeIn 或类似的事情,请使用回调:

    var d = $("<div class='test'>Hi there</div>");
    d.hide();
    $("body").prepend(d);
    d.fadeIn(function() {
        this.style.display = "";
    });
    

    Live example

    【讨论】:

    • 用 Firefox 查看这个测试页面。 div 有“style=display:block;”明确定义。在 Webkit 下,它的样式属性为空。我在 Firefox 和 Safari 中都使用了内置检查器。
    • @AntonAL:我明白你在说什么。更新了答案。
    • 我对纯 CSS 效果也有同样的想法。它可以工作,但是当我们执行 removeClass() 时,不会播放 CSS 动画。我们应该在一些小间隔之后进行,比如 100 毫秒。谢谢!
    • @AntonAL:有另一个想法,在最后添加了一个最终更新。玩得开心!
    【解决方案2】:

    如果你这样做会怎么样

    var d = $("<div class='test'></div>");
    d.hide();
    $("body").prepend(d);
    d.removeAttr('style'); // this will revert to the original styling
    

    【讨论】:

    • 它可以工作,但它不会恢复样式属性,它会清除它。谢谢。
    • @Anton,确实如此。但是由于您的代码仅通过.hide() 方法添加display:none,因此删除样式属性将返回到.test 类指定的任何内容。
    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多