Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why creating the elements with custom tags adds the xml namespace in the outerHTML in IE9 or 10 until the .find() method is called?

I have a jsfiddle that demonstrates the question:

http://jsfiddle.net/H6gML/8/

$(document).ready(function() {

    // this seems fine in IE9 and 10
    var $div = $("<div>");
    console.log("In IE, this <div> is just fine: " + $div[0].outerHTML);

    // this is weird in IE
    var $test = $("<test>");    
    console.log("However, this <test> has an xml tag prepended: \n" 
                + $test[0].outerHTML);    
    $test.find("test");    
    console.log("Now, it does not: \n" + $test[0].outerHTML);    
    console.log("Why does this behave this way?");
});

Why does this happen? It doesn't happen in Chrome or Firefox. Is there a better way to fix this than to call .find("test") on the object?

Edit

To clarify, I'm not asking why the xml tag is added, rather, I'm wondering why the .find() call get's rid of it. It doesn't make sense to me.

like image 645
quakkels Avatar asked Nov 15 '13 21:11

quakkels


1 Answers

Why does this happen? It doesn't happen in Chrome or Firefox. Is there a better way to fix this than to call .find("test") on the object

It is the IE causing the issue while doing document.createElement on an unknown html element type. It thinks it is an XML node and adds the xml namespace prefixed <?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" />. Instead if you try to make it explicit to mention that it is an html element, this issue doesn't happen.

Try:

 var $test = $("<html><test/></html>");

The issue no longer occurs.

To clarify, I'm not asking why the xml tag is added, rather, I'm wondering why the .find() call get's rid of it. It doesn't make sense to me.

Now, when you do a find, jquery internally uses context.getElementsByTagName or (similar based on the type whether it is a class or a tag or id etc..) which means it does this operation on the element test. So in IE when you do that it probably internally resolves the fact that you are trying to perform the operation on an html element and not an xml element and it changes the document type for the underlying context(But i don't know why it changes the parent context though rather than just returning a match). You can check this out by this simple example as well.

var $test = document.createElement("test");    
console.log("However, this <test> has an xml tag prepended: \n" 
            + $test.outerHTML);  
$test.getElementsByTagName("test");
console.log("Now, it does not: \n" + $test.outerHTML); 

Demo

Update

Here is a documented way of defining the custom elements

The custom element type identifies a custom element interface and is a sequence of characters that must match the NCName production and contain a U+002D HYPHEN-MINUS character. The custom element type must not be one of the following values: annotation-xml, color-profile, font-face, font-face-src, font-face-uri, font-face-format, font-face-name, missing-glyph

So according to this had your tag name been somename-test ex:- custom-test IE recognizes it and it works as expected.

Demo

like image 69
PSL Avatar answered Nov 15 '22 19:11

PSL