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
精彩评论