6

HTML5 自閉標籤(Self-Closing Tag)誤用案例

 1 year ago
source link: https://blog.darkthread.net/blog/html5-self-closing-tags/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

HTML5 自閉標籤(Self-Closing Tag)誤用案例-黑暗執行緒

踩到一個地雷。從舊專案搬了網頁到新專案,有些文字顯示不出來,花了點時間追查,發現是因為某 jQuery 元件用了 <span class="..." /> 這種不合法寫法,舊專案為相容 IE 還在用 jQuery 用 1.12 版,搬到改用 jQuery 3.6 的新專案就壞掉了!

XML 語法中 <elementTag ...></element><elementTag ... /> 意義相同且可互換;但依據 HTML5 規範,Self-Closing Tag 只能用在 Void Element (包含 area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr) 以及 Foreign Element (MathML 及 SVG 元素)。因此,<span ... /> 並不是合法寫法,可視為元件程式庫的 Bug。這次遇到出錯案例為 <span class="icon" /><span>xxx</span>,被瀏覽器解讀為 <span class="icon"><span>xxx</span></span>,等同 xxx 被包在 <span class="icon"> 裡,而 .icon 樣式有設定固定寬高及超出範圍隱藏(overflow: hidden),導致包在其中 xxx 無法完整顯示。

但,既然有錯,這麼多年下來為什麼沒爆?是因為該元件靠 jQuery append('<span class="icon" /><span>xxx</span>') 將 HTML 轉成 DOM,在 jQuery 1.X 的執行結果是 <span class="icon"></span><span>xxx</span>,陰錯陽差修正問題。但 jQuery 3.x 行為改變,會保留原有 <span class="icon" /><span>xxx</span> 格式,因而東窗事發。

找出問題根源,也確認 HTML5 對自閉標籤的規定,用下面的範例為本茶包劃上完美句點。
補充:程式包含一個較少用的技巧,網頁同時載入 jQuery 3.6 及 jQuery 1.12,靠 jQuery.noConflict() 讓二者並存,這個 API 十幾年前就學到,還真沒想過有派上用場的一天,哈。

<!DOCTYPE html>
<html>
<hea>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>var $jq36 = jQuery.noConflict();</script>
    <script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
    <script>var $jq112 = jQuery.noConflict();</script>
    <style>
        .square {
            display: inline-block;
            width: 20px;
            height: 20px;
            background-color: lightseagreen;
            overflow: hidden;
        }

        dd {
            padding: 6px; margin-left: 20px;
        }
    </style>
</hea>

<body>
    <dl>
        <dt>Normal SPAN</dt>
        <dd>
            <span class="square"></span>
            <span>Text</span>
        </dd>
    </dl>
    <dl>
        <dt>Self-Closed SPAN</dt>
        <dd>
            <span class="square" />
            <span>Text</span>   
        </dd>
    </dl>
    <dl>
        <dt>jQuery.append Self-Closed SPAN (v3.6)</dt>
        <dd class="jqtest3">
        </dd>
    </dl>
    <dl>
        <dt>jQuery.append Self-Closed SPAN (v1.12)</dt>
        <dd class="jqtest1">
        </dd>
    </dl>    
    <script>
        $jq36('.jqtest3').append('<span class="square" /><span>Text</span>');
        $jq112('.jqtest1').append('<span class="square" /><span>Text</span>');
    </script>
</body>

</html>

由上到下分別測試:正常 Span、自閉 Sapn、使用 jQuery 3.6 append() 轉換自閉 Span、使用 jQuery 1.12 轉換自閉 Span:

Fig1_638016108756047961.png


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK