10

如果 HTML 元素可以包含一些文本,是否有一种干净而强大的方法可以测试(使用纯 javascript 或 jQuery)?

例如<br>,, <hr>or<tr>不能包含文本节点,while <div>, <td>or <span>can。

测试此属性的最简单方法是控制标签名称。但这是最好的解决方案吗?我认为这是最糟糕的之一...

编辑:为了澄清问题的意义,需要指出完美的答案应该考虑两个问题:

  1. 根据 HTML 标准,元素可以包含文本节点吗?
  2. 如果元素包含一些文本,它会被显示吗?

显然,上一个列表的每个点都有一个子答案。

4

3 回答 3

5

“空元素”的 W3 标准规定:

空元素
area, base, br, col, embed, hr, img, input, keygen, link, menuitem, meta, param, source, track, wbr

显然也有一些非官方的标签。

您可以制作一个黑名单并用于.prop('tagName')获取标签名称:

(function ($) {
    var cannotContainText = ['AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX'];

    $.fn.canContainText = function() {
        var tagName = $(this).prop('tagName').toUpperCase();

        return ($.inArray(tagName, cannotContainText) == -1);
    };
}(jQuery));

$('<br>').canContainText(); //false
$('<div>').canContainText(); //true

在这里,您还可以添加自己的标签cannotContainText(例如添加不是正式的 void 元素,因为它与规范<tr>不匹配“ void 元素是其内容模型在任何情况下都不允许它具有内容的元素。Void元素可以有属性。 ”)。

于 2013-11-05T13:57:16.900 回答
1

我相信您正在寻找无效 HTML 标记的列表:

以下是 HTML 中 void 元素的完整列表:

area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr

从那里您只需测试节点以查看它是否在列表中。例如:

var voidNodeTags = ['AREA', 'BASE', ...];
var isNodeVoid = function (node) {
    return voidNodeTags.indexOf(node.nodeName) !== -1;
};

http://jsfiddle.net/3uQjH/

于 2013-11-05T13:57:16.800 回答
0

我基本上同意每个人的观点,黑名单将是一种非常正统的方式,但如果我们真的需要测试能力,那么这将是我认为的一种方式(使用一些jquery):

isTextContainerTag=function(tagName){
    try{       
        var test = $('<'+tagName+'></'+tagName+'>');
        test.html(123);
        if(test.html()=='123'){
            return true;   
        }else{
            return false;   
        }
    }
    catch(err){return false;}
}

我在 Chrome 上对各种标签名称进行了测试,得到了以下结果:

    console.log('input',isTextContainerTag('input'));//answer:false
    console.log('textarea',isTextContainerTag('textarea'));//true
    console.log('option',isTextContainerTag('option'));//true
    console.log('ul',isTextContainerTag('ul'));//true
    console.log('li',isTextContainerTag('li'));//true
    console.log('tr',isTextContainerTag('tr'));//true
    console.log('td',isTextContainerTag('td'));//true
    console.log('hr',isTextContainerTag('hr'));//false
    console.log('br',isTextContainerTag('br'));//false
    console.log('div',isTextContainerTag('div'));//true
    console.log('p',isTextContainerTag('p'));//true
    console.log('html',isTextContainerTag('html'));//false
    console.log('body',isTextContainerTag('body'));//false
    console.log('table',isTextContainerTag('table'));//false
    console.log('tbody',isTextContainerTag('tbody'));//true

我们还可以在这两个示例中使用 jquery "prop" 测试一些真实标签:

<div id="A">AAAAAA</div>
<br id="B">

这使:

var obj1 = $('#A').prop('tagName');
var obj2 = $('#B').prop('tagName');
console.log('id:A (div)',isTextContainerTag(obj1));//true
console.log('id:B (br)',isTextContainerTag(obj2));//false

我敢肯定它远非完美,但研究起来很有趣。

于 2013-11-05T15:56:46.710 回答