开发者

HTML element in memory and display problem after inserting it to DOM

When we run following script under Firefox ...

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

... and look to HTML, this inserted element will have style attribute:

style="di开发者_如何学运维splay: block;"

Under Webkit, element will have:

style="display: none;"

This scenario in used in a JavaScript component, i develop. This component has a collection of HTML elements in it's internal variables, and inserts they to specified destination container.

Because inserted element having display-property initialized in style attribute, it overrides CSS. This breaks the layout of a page.

As a quick solution, i can store "style" attribute, before element is inserted to the DOM, and, after inserting, write stored version over created one.

Is there any better solution ?

Why this ever happens and how can i check, whether element is not yet inserted to the DOM ?


When I do that with either Chrome or Safari (both WebKit-based browsers), if I inspect the element with the built-in tools, it has no style.display property at all, and so the default div style of display: block is used. (Here's a version with some text in the div, so it's easier to see and to find with the DOM inspector.)

So I suspect the problem lies elsewhere. For instance, is there intervening code that may be failing on WebKit, so that d.show(); never ends up getting called? That would certainly explain it. Easy enough with the built-in tools in Chrome or Safari to set a breakpoint on the code creating the div and walk through it.

Re your question:

...how can i check, whether element is not yet inserted to the DOM ?

That question was asked here on StackOverflow just recently, and one of the answers specific to jQuery was rather elegant:

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

Update: Re your comment below

Look at this test page with Firefox. The div has "style=display: block;" explicitly defined. Under Webkit, it has empty style attr. I'm using built-in inspector in both Firefox and Safari.

Ah, okay, so the problem isn't a display: none in WebKit browsers (your statement about that in the question led me astray), but rather that Firefox (and possibly other Gecko browsers) end up having display: block on the element.

I'd probably approach this like this:

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

...with this CSS:

.hidden {
    display: none;
}

Live copy

That way, you know you won't end up with a style.display property set at all.


Update 2: The other thing you can do is remove the style.display property directly:

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

Live example

You alluded to effects, so if you're doing fadeIn or something like that, use the callback:

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

Live example


How about if you do

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜