Почему создание элементов с пользовательскими тегами добавляет пространство имен xml в outerHTML в IE9 или 10 до тех пор, пока не будет вызван метод .find()?

У меня есть jsfiddle, который демонстрирует вопрос:

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?");
});

Почему это происходит? Это не происходит в Chrome или Firefox. Есть ли лучший способ исправить это, чем вызвать .find("test") на объект?

Изменить

Чтобы уточнить, я не спрашиваю, почему добавлен тег xml, скорее, мне интересно, почему вызов .find() избавляется от него. Для меня это не имеет смысла.

Ответ 1

Почему это происходит? Это не происходит в Chrome или Firefox. Есть ли лучший способ исправить это, чем вызвать .find( "test" ) для объекта

Это IE, вызывающий проблему при выполнении document.createElement по неизвестному типу элемента html. Он считает, что это XML node и добавляет пространство имен xml с префиксом <?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" />. Вместо этого, если вы попытаетесь сделать это явным, чтобы упомянуть, что это элемент html, эта проблема не возникает.

Try:

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

Проблема больше не возникает.

Чтобы уточнить, я не спрашиваю, почему добавлен тег xml, скорее, мне интересно, почему вызов .find() избавляется от него. Для меня это не имеет смысла.

Теперь, когда вы выполняете поиск, jquery внутренне использует context.getElementsByTagName или (аналогично по типу, является ли он классом или тегом или идентификатором и т.д.), что означает, что эта операция выполняется над элементом test, Поэтому в IE, когда вы это делаете, он, вероятно, внутренне решает тот факт, что вы пытаетесь выполнить операцию над элементом html, а не с элементом xml, и он изменяет тип документа для базового контекста (но я не знаю, почему он изменяется родительский контекст, а не просто возвращение совпадения). Вы также можете проверить это на этом простом примере.

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); 

Демо

Обновление

Вот документированный способ определения пользовательских элементов

Тип настраиваемого элемента идентифицирует интерфейс пользовательского элемента и представляет собой последовательность символов, которые должны соответствовать заданию NCName и содержать символ U + 002D HYPHEN-MINUS. Тип настраиваемого элемента не должен быть одним из следующих значений: аннотацию-XML, цветовой профиль, шрифт-лицо, шрифт-лицо-Src, шрифта лицом Ури шрифт-лицо-формат, шрифт лицо имя, недостающей глиф

Итак, в соответствии с этим ваше имя тега somename-test ex: - custom-test IE распознает его и работает как ожидалось.

Демо