Що саме може спричинити помилку "HIERARCHY_REQUEST_ERR: DOM Виняток 3"?


184

Як саме це стосується jQuery? Я знаю, що бібліотека використовує внутрішні функції JavaScript внутрішньо, але що саме вона намагається робити, коли виникає така проблема?

Відповіді:


227

Це означає, що ви намагалися вставити вузол DOM у місце дерева DOM, куди він не може зайти. Я найчастіше зустрічаю це місце на Safari, яке не дозволяє:

document.appendChild(document.createElement('div'));

Як правило, це лише помилка, коли це було насправді призначено:

document.body.appendChild(document.createElement('div'));

Інші причини, помічені в дикій природі (підсумовані з коментарів):

  • Ви намагаєтесь додати вузол до себе
  • Ви намагаєтеся приєднати null до вузла
  • Ви намагаєтесь додати вузол до текстового вузла.
  • Ваш HTML-код недійсний (наприклад, не вдалося закрити цільовий вузол)
  • Веб-переглядач вважає, що HTML, який ви намагаєтеся додати, - це XML (виправити, додавши <!doctype html>до введеного HTML або вказавши тип вмісту під час отримання через XHR)

49
Помилка також виникає при спробі додати вузол до себе. Я щойно сам наткнувся на цього :-)
Бен Клейтон,

5
Я щойно намагався додати нуль до елемента (і абсолютно незв’язаний підказок - завжди переконайтеся, що ваші функції повертають те, що ви їм написали, щоб повернути: P)
Велі Гебрев,

Я бачив це, коли один із завершальних тегів не вистачав із цілі.
Том Н

IE (9) може нанести цю помилку під час використання jQuery для додавання результатів AJAX. Уникайте цього, використовуючи, response.xmlде це можливо. Наприклад,$(e).append(response.xml || $(response));
Кортні Крістенсен

Зробив це, коли я змінив з jQuery (настільний) на zepto на Android. Повернувся назад.
Равіндранат Акіла

5

Якщо ви отримуєте цю помилку через jquery ajax виклику $ .ajax

Потім вам може знадобитися вказати, який тип даних повертається з сервера. Я дуже виправив відповідь, використовуючи цю просту властивість.

$.ajax({
    url: "URL_HERE",
    dataType: "html",
    success: function(response) {
        $('#ELEMENT').html(response);
    }
});

1
єдиний базовий код для вебу / PhoneGap, перероблено для динамічного завантаження шаблону з допомогою відповіді на koorchik в stackoverflow.com/questions/8366733 / ... . працював у настільному браузері, не працював у браузері для мобільних пристроїв або рідному додатку. це рішення зробило трюк.
Kinjal Dixit

Тут же проблема, дивно, лише в iOS 5. Вказання данихType. Спасибі
homerjam

3

Зокрема, за допомогою jQuery ви можете зіткнутися з цією проблемою, якщо забути домітки навколо тега html при створенні елементів:

 $("#target").append($("div").text("Test"));

Виникне ця помилка, тому що ви мали на увазі

 $("#target").append($("<div>").text("Test"));

3

Ця помилка може виникнути, коли ви намагаєтеся вставити вузол у DOM, який є недійсним HTML, який може бути настільки ж тонким, як неправильний атрибут, наприклад:

// <input> can have a 'type' attribute
var $input = $('<input/>').attr('type', 'text');
$holder.append($input);  // OK

// <div> CANNOT have a 'type' attribute
var $div = $('<div></div>').attr('type', 'text');
$holder.append($div);   // Error: HIERARCHY_REQUEST_ERR: DOM Exception 3

2

@ Келлі Нортон має рацію у своїй відповіді, що The browser thinks the HTML you are attempting to append is XMLта пропонує specifying the content type when fetching via XHR.

Це правда, але ви іноді використовуєте сторонні бібліотеки, які не збираєтесь змінювати. У моєму випадку це інтерфейс JQuery. Тоді вам слід надати право Content-Typeу відповіді, а не змінювати тип відповіді на стороні JavaScript. Встановіть придатною Content-Typeдля text/htmlі ви прекрасно.

У моєму випадку це було так само просто , як перейменування file.xhtmlдо file.html- сервер додатки мали деяке розширення до MIME типів відображень з коробки. Коли вміст є динамічним, ви можете якось встановити тип вмісту відповіді (наприклад, res.setContentType("text/html")в API сервлетів).


1

Ви можете побачити ці питання

Отримання HIERARCHY_REQUEST_ERR при використанні Javascript для рекурсивного генерування вкладеного списку

або

Діалог інтерфейсу jQuery із зворотним зворотом кнопки ASP.NET

Висновок такий

при спробі використовувати функцію додавання, ви повинні використовувати нову змінну, як, наприклад, цей приклад

jQuery(function() {
   var dlg = jQuery("#dialog").dialog({ 
                        draggable: true, 
                        resizable: true, 
                        show: 'Transfer', 
                        hide: 'Transfer', 
                        width: 320, 
                        autoOpen: false, 
                        minHeight: 10, 
                        minwidth: 10 
          });
  dlg.parent().appendTo(jQuery("form:first"));
});

У наведеному вище прикладі використовується var "dlg" для запуску функції appendTo. Тоді помилка "HIERARCHY_REQUEST_ERR" знову не з’явиться.


1

Я зіткнувся з цією помилкою під час використання розширення Google Chrome Sidewiki. Вимкнення цього рішення вирішило проблему для мене.


1

Я збираюся додати ще одну конкретну відповідь, тому що це був 2-годинний пошук відповіді ...

Я намагався вставити тег у документ. Html був таким:

<map id='imageMap' name='imageMap'>
  <area shape='circle' coords='55,28,5' href='#' title='1687.01 - 0 percentile' />
</map>

Якщо ви помітили, тег закривається в попередньому прикладі ( <area/>). Це не було прийнято в браузерах Chrome. w3schools, здається, вважає, що його слід закрити, і я не зміг знайти офіційну специфікацію цього тегу, але він точно не працює в Chrome. Firefox не прийме його з <area/>або <area></area>або <area>. Хром повинен бути <area>. IE приймає що-небудь.

У будь-якому випадку ця помилка може бути, тому що ваш HTML неправильний.


1

Я знаю, що ця тема є давньою, але я зіткнувся з іншою причиною проблеми, яка може бути корисною для інших. Я отримував помилку, коли Google Analytics намагався долучитись до коментаря HTML. Код порушника:

document.documentElement.firstChild.appendChild(ga);

Це спричинило помилку, оскільки моїм першим елементом був коментар HTML (а саме код шаблону Dreamweaver).

<!-- #BeginTemplate "/Templates/default.dwt.php" -->

Я змінив код правопорушення на щось, мабуть, не бронебійне, але краще:

document.documentElement.firstChild.nodeType===1 ? document.documentElement.firstChild.appendChild(ga) : document.documentElement.lastChild.appendChild(ga);

1

Якщо ви зіткнулися з цією проблемою, намагаючись додати вузол до іншого вікна в Internet Explorer, спробуйте використовувати HTML всередині вузла замість самого вузла.

myElement.appendChild(myNode.html());

IE не підтримує додавання вузлів до іншого вікна.


Ви насправді спробували це? Навіть у Chrome я отримую TypeError: Не вдалося виконати "appendChild" на "Node": параметр 1 не типу "Node". (...). Це тому, що .html () має рядковий тип, а appendChild очікує типу Node.
joedotnot

1

Ця ПОМИЛКА трапилася зі мною в IE9, коли я намагався динамічно додатиChild до того, що вже існувало у вікні A. Вікно A створило б дочірнє вікно B. У вікні B після деяких дій користувача функція запуститься і зробить appendChild на елемент форми у вікні A з використанням window.opener.document.getElementById('formElement').appendChild(input);

Це призведе до помилки. Те ж саме із створенням елемента введення, використовуючи document.createElement('input');у дочірньому вікні, передаючи його як параметр у window.openerвікно A, і там робимо додавання. Тільки якщо я створив елемент введення в тому самому вікні, куди я збирався його додати, це вдалося б без помилок.

Отже, мій висновок (будь ласка, перевірте): жоден елемент не може бути динамічно створений (за допомогою document.createElement) в одному вікні, а потім доданий (використовуючи .appendChild) до елемента в іншому вікні (не роблячи, можливо, конкретного додаткового кроку, який я пропустив, щоб він не вважався XML або щось). Це не в IE9 і призводить до помилки, але у FF це працює чудово.

PS. Я не використовую jQuery.


Завдяки вашому вказівникові, я з'ясував спосіб подолати це. Будь ласка, дивіться відповідь, яку я опублікував, якщо вас цікавить.
T.Ho

0

Ще однією причиною цього може стати те, що ви додаєте до того, як елемент буде готовий, наприклад

<body>

<script>
document.body.appendChild(foo);
</script>

</body>
</html>

У цьому випадку вам потрібно буде перемістити сценарій після. Не зовсім впевнений, що це кошерніше, але переміщення сценарію після тіла, здається, не допоможе: /

Замість того, щоб переміщувати сценарій, ви також можете зробити додавання в обробці подій.


0

Я отримав цю помилку, тому що забув клонувати свій елемент.

// creates an error
clone = $("#thing");
clone.appendTo("#somediv");

// does not
clone = $("#thing").clone();
clone.appendTo("#somediv");

0

Тільки для довідки.

IE блокує додавання будь-якого елемента, створеного в іншому контексті вікна, від контексту вікна, до якого елемент додається.

напр

var childWindow = window.open('somepage.html');

//will throw the exception in IE
childWindow.document.body.appendChild(document.createElement('div'));

//will not throw exception in IE
childWindow.document.body.appendChild(childWindow.document.createElement('div'));

Я ще не зрозумів, як створити елемент dom за допомогою jQuery, використовуючи інший контекст вікна.


0

Я отримую цю помилку в IE9, якщо у мене був відключений варіант налагодження сценарію (Internet Explorer). Якщо я ввімкнув налагодження сценарію, я не бачу помилки, і сторінка працює нормально. Це здається дивним, що виняток DOM стосується налагодження або ввімкнено, або вимкнено.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.