2017-12-22 122 views
9

Không chắc chắn đây có phải là lỗi hay tính năng hay không. Khi phân tích cú pháp html với các phần tử bảng bên ngoài một bảng, jQuery bỏ qua các phần tử không phải bảng.Khi phân tích cú pháp, jQuery bỏ qua bất kỳ thứ gì không phải là bảng và tài liệu sẽ xóa thẻ bảng

<tr><td>table data</td></tr> 
<div>div after will be ignored</div> 

truyền vào $(html) trở thành

<tr><td>table data</td></tr> 

Khi đi qua html cùng vào đồng bằng javascript element.innerHTML = html trở thành

table data 
<div>div after will be ignored</div> 

Đây là nó trong hành động https://codepen.io/addbrick/pen/mprBgP

EDIT: Ngay sau khi công bố điều này tôi nhận ra jQuery là loại bỏ các yếu tố bảng vì hành vi ngược lại trong dom.

Trả lời

4

Để bắt đầu, đó không phải là HTML hợp lệ.

Có. Trình phân tích cú pháp Jquery dọn dẹp.

Nếu bạn có cái nhìn cận cảnh tại source code jquery, hàm html sử dụng parseHTML trước khi nó thực sự đặt innerHTML.

Và phân tích cú phápHTML đang gọi một buildFragment và xóa tất cả các phần tử giả bên trong chuỗi.

Dưới đây là một phần của mã nguồn của chức năng buildFragment

// Add nodes directly 
      if (jQuery.type(elem) === "object") { 
       jQuery.merge(nodes, elem.nodeType ? [ elem ] : elem); 

      // Convert non-html into a text node 
      } else if (!rhtml.test(elem)) { 
       nodes.push(context.createTextNode(elem)); 

      // Convert html into DOM nodes 
      } else { 
       tmp = tmp || safe.appendChild(context.createElement("div")); 

       // Deserialize a standard representation 
       tag = (rtagName.exec(elem) || [ "", "" ])[ 1 ].toLowerCase(); 
       wrap = wrapMap[ tag ] || wrapMap._default; 

       tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter(elem) + wrap[ 2 ]; 

       // Descend through wrappers to the right content 
       j = wrap[ 0 ]; 
       while (j--) { 
        tmp = tmp.lastChild; 
       } 



// Manually add leading whitespace removed by IE 
      if (!support.leadingWhitespace && rleadingWhitespace.test(elem)) { 
       nodes.push(context.createTextNode(rleadingWhitespace.exec(elem)[ 0 ])); 
      } 

      // Remove IE's autoinserted <tbody> from table fragments 
      if (!support.tbody) { 

       // String was a <table>, *may* have spurious <tbody> 
       elem = tag === "table" && !rtbody.test(elem) ? 
        tmp.firstChild : 

        // String was a bare <thead> or <tfoot> 
        wrap[ 1 ] === "<table>" && !rtbody.test(elem) ? 
         tmp : 
         0; 

Vâng, đó là nơi bạn thực tế chuỗi thông qua được đánh giá và tạo ra các nút DOM.

Và cuối cùng, div không được sử dụng một phần tử bên trong bảng trực tiếp. Có thể được bọc bên trong tdtr.

Vậy tại sao chính xác jquery bỏ qua nó? bởi vì đó không phải là html thực và hợp lệ. Nếu bạn nhìn gần tại html specification of Table, bạn chỉ có thể có các thẻ nhất định. Trong một thẻ bảng,

<!ELEMENT TABLE - - 
    (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)> 
<!ATTLIST TABLE      -- table element -- 
    %attrs;        -- %coreattrs, %i18n, %events -- 
    summary  %Text;   #IMPLIED -- purpose/structure for speech output-- 
    width  %Length;  #IMPLIED -- table width -- 
    border  %Pixels;  #IMPLIED -- controls frame width around table -- 
    frame  %TFrame;  #IMPLIED -- which parts of frame to render -- 
    rules  %TRules;  #IMPLIED -- rulings between rows and cols -- 
    cellspacing %Length;  #IMPLIED -- spacing between cells -- 
    cellpadding %Length;  #IMPLIED -- spacing within cells -- 
    > 

Và bên trong một mỗi thẻ

<!ELEMENT THEAD - O (TR)+   -- table header --> 
<!ELEMENT TFOOT - O (TR)+   -- table footer --> 

Như bạn thấy, không có thẻ div cho phép trực tiếp.

Tuy nhiên, trong trường hợp vani javascript innerHTML, không có phân tích cú pháp như vậy xảy ra và trình duyệt trực tiếp diễn giải chuỗi được cung cấp cho nút dom và thêm chúng vào tài liệu.

Xóa tất cả các phần tử con, phân tích chuỗi nội dung và chỉ định các nút kết quả là con của phần tử.

Các vấn đề liên quan