Chính xác thì điều gì có thể gây ra một HIERARCHY_REQUEST_ERR: Ngoại lệ DOM 3 -Error?


184

Chính xác thì nó liên quan đến jQuery như thế nào? Tôi biết thư viện sử dụng các hàm javascript gốc trong nội bộ, nhưng chính xác thì nó đang cố gắng làm gì mỗi khi có vấn đề như vậy xuất hiện?

Câu trả lời:


227

Điều đó có nghĩa là bạn đã cố gắng chèn một nút DOM vào một vị trí trong cây DOM nơi nó không thể đi. Nơi phổ biến nhất tôi thấy là trên Safari, nơi không cho phép như sau:

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

Nói chung, đây chỉ là một lỗi mà điều này thực sự được dự định:

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

Các nguyên nhân khác nhìn thấy trong tự nhiên (tóm tắt từ ý kiến):

  • Bạn đang cố nối thêm một nút vào chính nó
  • Bạn đang cố nối null vào một nút
  • Bạn đang cố nối một nút vào một nút văn bản.
  • HTML của bạn không hợp lệ (ví dụ: không đóng nút mục tiêu của bạn)
  • Trình duyệt cho rằng HTML bạn đang cố nối thêm là XML (khắc phục bằng cách thêm <!doctype html>vào HTML đã chèn của bạn hoặc chỉ định loại nội dung khi tìm nạp qua XHR)

49
Lỗi cũng xảy ra khi bạn thử và nối một nút vào chính nó. Tôi chỉ chạy vào cái này một mình :-)
Ben Clayton

5
Tôi chỉ nhận được điều này khi cố gắng thêm null vào một phần tử (và một mẹo hoàn toàn không liên quan - luôn đảm bảo các hàm của bạn trả về thứ bạn đã viết chúng để trả về: P)
Veli Gebrev

Tôi đã thấy điều này khi một trong những thẻ đóng bị mất khỏi mục tiêu.
Tom H

IE (9) có thể đưa ra lỗi này khi sử dụng jQuery để nối các kết quả AJAX. Tránh điều này bằng cách sử dụng response.xmlnơi có sẵn. Ví dụ:$(e).append(response.xml || $(response));
Courtney Christensen

Có được điều này khi tôi thay đổi từ jQuery (máy tính để bàn) sang zepto trên Android. Chuyển về.
Ravindranath Akila

5

Nếu bạn gặp lỗi này do ajax jquery, hãy gọi $ .ajax

Sau đó, bạn có thể cần phải xác định những gì datatype sẽ trở lại từ máy chủ. Tôi đã sửa lỗi phản hồi rất nhiều bằng cách sử dụng tài sản đơn giản này.

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

1
cơ sở mã duy nhất cho web / phonegap, được tái cấu trúc để tải động mẫu bằng cách sử dụng câu trả lời của koorchik tại stackoverflow.com/questions/8366733/ . làm việc trong trình duyệt máy tính để bàn, không hoạt động trong trình duyệt di động hoặc ứng dụng gốc. Giải pháp này đã làm được mẹo.
Kinjal Dixit

Vấn đề tương tự ở đây, kỳ lạ chỉ có trong iOS 5. Chỉ định dataType hoạt động. Cảm ơn
homerjam

3

Cụ thể với jQuery, bạn có thể gặp phải vấn đề này nếu quên các dấu mũ xung quanh thẻ html khi tạo các phần tử:

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

Sẽ phát sinh lỗi này vì ý của bạn là

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

3

Lỗi này có thể xảy ra khi bạn cố gắng chèn một nút vào DOM là HTML không hợp lệ, có thể là một cái gì đó tinh tế như một thuộc tính không chính xác, ví dụ:

// <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

@Kelly Norton là đúng trong câu trả lời của mình The browser thinks the HTML you are attempting to append is XMLvà gợi ý specifying the content type when fetching via XHR.

Điều đó đúng tuy nhiên đôi khi bạn sử dụng các thư viện của bên thứ ba mà bạn sẽ không sửa đổi. Đó là giao diện người dùng JQuery trong trường hợp của tôi. Sau đó, bạn nên cung cấp quyền Content-Typetrong phản hồi thay vì ghi đè loại phản hồi về phía JavaScript. Đặt bạn Content-Typeđến text/htmlvà bạn cũng tốt.

Trong trường hợp của tôi, đó là dễ dàng như việc đổi tên file.xhtmlđể file.html- ứng dụng máy chủ đã có một số phần mở rộng cho MIME loại ánh xạ ra khỏi hộp. Khi nội dung động, bạn có thể đặt loại nội dung phản hồi bằng cách nào đó (ví dụ: res.setContentType("text/html")trong API của Servlet).


1

Bạn có thể thấy những câu hỏi này

Bắt HIERARCHY_REQUEST_ERR khi sử dụng Javascript để tạo đệ quy một danh sách lồng nhau

hoặc là

Hộp thoại UI UI với postback nút ASP.NET

Kết luận là

Khi bạn cố gắng sử dụng chức năng chắp thêm, bạn nên sử dụng biến mới, như ví dụ này

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

Trong ví dụ trên, sử dụng var "dlg" để chạy hàm appendTo. Sau đó, lỗi HIERARCHY_REQUEST_ERR "sẽ không xuất hiện trở lại.


1

Tôi đã gặp lỗi này khi sử dụng tiện ích mở rộng Google Chrome Sidewiki. Vô hiệu hóa nó giải quyết vấn đề cho tôi.


1

Tôi sẽ thêm một câu trả lời cụ thể hơn ở đây vì đó là 2 giờ tìm kiếm cho câu trả lời ...

Tôi đã cố gắng tiêm một thẻ vào một tài liệu. Các html là như thế này:

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

Nếu bạn nhận thấy, thẻ được đóng trong ví dụ trước ( <area/>). Điều này không được chấp nhận trong trình duyệt Chrome. w3schools dường như nghĩ rằng nó nên bị đóng và tôi không thể tìm thấy thông số chính thức về thẻ này, nhưng nó chắc chắn không hoạt động trong Chrome. Firefox sẽ không chấp nhận nó với <area/>hoặc <area></area>hoặc <area>. Chrome phải có <area>. IE chấp nhận bất cứ điều gì.

Dù sao, lỗi này có thể là do HTML của bạn không đúng.


1

Tôi biết chủ đề này đã cũ, nhưng tôi đã gặp phải một nguyên nhân khác của vấn đề mà những người khác có thể thấy hữu ích. Tôi đã gặp lỗi với Google Analytics khi cố gắng tự thêm vào nhận xét HTML. Mã vi phạm:

document.documentElement.firstChild.appendChild(ga);

Điều này gây ra lỗi vì yếu tố đầu tiên của tôi là một nhận xét HTML (cụ thể là mã mẫu Dreamweaver).

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

Tôi đã sửa đổi mã vi phạm thành một thứ được thừa nhận là không chống đạn, nhưng tốt hơn:

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

1

Nếu bạn gặp phải vấn đề này trong khi cố gắng nối một nút vào một cửa sổ khác trong Internet Explorer, hãy thử sử dụng HTML bên trong nút thay vì chính nút đó.

myElement.appendChild(myNode.html());

IE không hỗ trợ nối các nút vào một cửa sổ khác.


Bạn đã thực sự thử điều này? Ngay cả trong Chrome tôi cũng nhận được TypeError: Không thể thực thi 'appendChild' trên 'Nút': tham số 1 không phải là loại 'Nút'. Đó là bởi vì .html () thuộc loại chuỗi và appendChild đang mong đợi loại Node.
joedotnot

1

ERROR này đã xảy ra với tôi trong IE9 khi tôi cố gắng nối thêm một cách linh hoạt vào một cửa sổ đã tồn tại trong cửa sổ A. Cửa sổ A sẽ tạo một cửa sổ con B. Trong cửa sổ B sau khi một số hành động của người dùng, một chức năng sẽ chạy và thực hiện một appendChild trên phần tử biểu mẫu trong cửa sổ A bằng cách sử dụng window.opener.document.getElementById('formElement').appendChild(input);

Điều này sẽ ném một lỗi. Tương tự với việc tạo phần tử đầu vào bằng cách sử dụng document.createElement('input');trong cửa sổ con, chuyển nó dưới dạng tham số cho window.openercửa sổ A và thực hiện nối thêm. Chỉ khi tôi tạo phần tử đầu vào trong cùng một cửa sổ nơi tôi sẽ nối nó, nó sẽ thành công mà không có lỗi.

Do đó, kết luận của tôi (vui lòng xác minh): không có phần tử nào có thể được tạo động (sử dụng document.createElement) trong một cửa sổ, sau đó nối (sử dụng .appendChild) vào một phần tử trong một cửa sổ khác (mà không cần thêm một bước cụ thể nào mà tôi đã bỏ lỡ để đảm bảo nó không được coi là XML hoặc một cái gì đó). Điều này không thành công trong IE9 và đưa ra lỗi, trong FF điều này vẫn hoạt động tốt.

Tái bút Tôi không sử dụng jQuery.


Nhờ con trỏ của bạn, tôi đã tìm ra một cách xung quanh này. Vui lòng xem câu trả lời tôi đã đăng nếu bạn quan tâm.
T.Ho

0

Một lý do khác có thể xảy ra là bạn đang nối thêm trước khi phần tử sẵn sàng, vd

<body>

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

</body>
</html>

Trong trường hợp này, bạn sẽ cần di chuyển tập lệnh sau. Không hoàn toàn chắc chắn nếu đó là kosher, nhưng di chuyển tập lệnh sau khi cơ thể dường như không giúp đỡ: /

Thay vì di chuyển tập lệnh, bạn cũng có thể thực hiện nối thêm trong trình xử lý sự kiện.


0

Tôi đã nhận được lỗi đó vì tôi quên sao chép phần tử của tôi.

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

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

0

Chỉ để tham khảo.

IE sẽ chặn việc nối thêm bất kỳ phần tử nào được tạo trong ngữ cảnh cửa sổ khác với ngữ cảnh cửa sổ mà phần tử đó đang được thêm vào.

ví dụ

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

Tôi chưa tìm ra cách tạo một phần tử dom với jQuery bằng cách sử dụng bối cảnh cửa sổ khác.


0

Tôi gặp lỗi này trong IE9 nếu tôi đã tắt tùy chọn gỡ lỗi tập lệnh (Internet Explorer). Nếu tôi bật gỡ lỗi tập lệnh, tôi không thấy lỗi và trang hoạt động tốt. Điều này có vẻ kỳ lạ là ngoại lệ DOM phải làm gì với gỡ lỗi được bật hoặc tắt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.