Проверить, может ли элемент содержать текст

Есть ли чистый и надежный способ проверки (используя чистый javascript или jQuery), если элемент HTML может содержать некоторый текст?

Например, <br>, <hr> или <tr> не могут содержать текстовые узлы, тогда как <div>, <td> или <span> могут.

Самый простой способ проверить это свойство - управлять именами тегов. Но это лучшее решение? Я думаю, что это один из худших...

EDIT: Чтобы прояснить смысл вопроса, нужно указать, что идеальный ответ должен учитывать две проблемы:

  • В соответствии со стандартами HTML, может ли элемент содержать текст node?
  • Если элемент содержит некоторый текст, отобразится ли это?

Очевидно, что для каждой точки предыдущего списка есть суб-ответ.

Ответ 1

Стандарт W3 для "void elements" определяет:

Элементы Void
область, база, 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 (например, добавить <tr>, который официально не является элементом void, поскольку он не соответствует Элемент void - это элемент, модель содержимого которого никогда не позволяет ему иметь содержимое ни при каких обстоятельствах. Элементы Void могут иметь атрибуты.").

Ответ 2

Я считаю, что вы ищете список void HTML-тегов:

Ниже приведен полный список элементов void в HTML:

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

Оттуда вы просто проверите node, чтобы узнать, есть ли в списке. Например:

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

http://jsfiddle.net/3uQjH/

Ответ 3

Я в основном согласен со всеми, что черный список будет очень ортодоксальным способом сделать это, но если нам действительно нужно проверить способность, то это будет один из способов, я думаю (с некоторым 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

Я уверен, что это далеко от совершенства, но было интересно посмотреть.