2017-12-22 137 views
9

यह सुनिश्चित नहीं है कि यह एक बग या सुविधा है या नहीं। तालिका के बाहर तालिका तत्वों के साथ एचटीएमएल पार्स करते समय, jQuery गैर-तालिका तत्वों को अनदेखा करता है। जब सादे जावास्क्रिप्ट element.innerHTML = htmlपार्सिंग करते समय, jQuery किसी भी चीज को अनदेखा करता है जो तालिका नहीं है और दस्तावेज़ तालिका टैग को हटा देता है

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

यहाँ हो जाता है में एक ही एचटीएमएल गुजर

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

$(html) में पारित कर दिया

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

हो जाता है यह https://codepen.io/addbrick/pen/mprBgP

संपादित कार्रवाई में है: पोस्ट करने के बाद सही यह मुझे एहसास हुआ jQuery डोम में विपरीत व्यवहार की वजह से तालिका तत्वों को हटा रहा है।

उत्तर

4

आरंभ करने के लिए, यह एक मान्य HTML नहीं है।

हां। Jquery पार्सर सफाई है कि।

यदि आपके पास source code jquery पर नजदीकी नज़र डालें, तो HTML फ़ंक्शन वास्तव में innerHTML सेट करने से पहले parseHTML का उपयोग करता है।

और पार्सएचटीएमएल बिल्डिंग को कॉल कर रहा है और स्ट्रिंग के अंदर सभी नकली तत्वों को हटा रहा है।

नीचे

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

हां, यह वह जगह है जहाँ आप वास्तविक स्ट्रिंग पारित मूल्यांकन किया है और डोम नोड्स बनाने हो जाता है buildFragment समारोह के स्रोत कोड का एक हिस्सा है।

और अंततः, div को सीधे तालिका के अंदर एक तत्व का उपयोग नहीं किया जाना चाहिए। td और tr के अंदर लपेटा जा सकता है।

तो क्यों वास्तव में jquery ने इसे अनदेखा किया? क्योंकि यह वास्तविक और मान्य एचटीएमएल नहीं है। यदि आप html specification of Table पर नज़दीक देखते हैं, तो आपके पास केवल दिए गए टैग हो सकते हैं। एक मेज टैग में,

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

और एक प्रत्येक टैग

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

आप देख सकते हैं अंदर, वहाँ कोई div टैग सीधे अनुमति है।

हालांकि वेनिला जावास्क्रिप्ट innerHTML के मामले में, ऐसा कोई पार्सिंग नहीं होता है और ब्राउज़र सीधे डोम नोड्स को प्रदान की गई स्ट्रिंग का अर्थ देता है और उन्हें दस्तावेज़ में जोड़ता है।

तत्व के सभी बच्चों को हटा देता है, सामग्री स्ट्रिंग को पार करता है और परिणामी नोड्स को तत्व के बच्चों के रूप में निर्दिष्ट करता है।

संबंधित मुद्दे