2017-12-22 303 views
9

Bunun bir hata veya özellik olup olmadığından emin değil. Bir tablo dışındaki tablo öğeleriyle html ayrıştırılırken jQuery, tablo olmayan öğeleri yok sayar. element.innerHTML = html İşteAyrıştırma yaparken, jQuery bir tablo olmayan herhangi bir şeyi yoksayar ve belge tablo etiketini kaldırır

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

olur javascript ovaya aynı html geçerken $(html) geçirilen

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

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

olur o https://codepen.io/addbrick/pen/mprBgP

DÜZENLEME eylem olduğu: Sağ yazdıktan sonra farkettim ki jQuery, dom içindeki karşıt davranış nedeniyle tablo elemanlarını kaldırıyor.

cevap

4

Başlamak için geçerli bir HTML değil.

Evet. Jquery çözümleyici bunu temizler.

source code jquery'ye yakından bakarsanız, html işlevi aslında innerHTML'u ayarlamadan önce parseHTML kullanır.

Ve parseHTML bir buildFragment çağırıyor ve dizenin içindeki tüm bozuk öğeleri kaldırıyor. Aşağıda

gerçek geçirilen dize değerlendirilir ve DOM düğümleri oluşturma alır nerede

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

Evet, yani buildFragment işlevinin kaynak kodunun bir parçasıdır.

Son olarak, div doğrudan bir tablonun içinde bir öğe kullanılmamalıdır. Bir td ve tr içine sarılabilir.

Peki neden jQuery bunu göz ardı etti? çünkü bu gerçek ve geçerli bir html değildir. html specification of Table numaralı telefona yakın bir şekilde bakarsanız, sadece belirtilen etiketlere sahip olabilirsiniz. Bir tablo etiketinde,

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

Ve her etiket

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

Gördüğünüz gibi içeride

doğrudan izin yok div etiketi yoktur.

Ancak, vanilla javascript innerHTML söz konusu olduğunda, böyle bir ayrıştırma gerçekleşmez ve tarayıcı dom düğümlerine sağlanan dizeyi doğrudan yorumlar ve bunları belgeye ekler.

Tüm öğelerin çocuklarını kaldırır, içerik dizesini ayrıştırır ve sonuçta oluşan düğümleri öğenin alt öğesi olarak atar.