Test if an element can contain text

前端 未结 3 1973
灰色年华
灰色年华 2020-12-05 12:02

Is there a clean and robust way in which I can test (using pure javascript or also jQuery) if an HTML element can contain some text?

For instance,

相关标签:
3条回答
  • 2020-12-05 12:27

    I believe you're looking for a list of void HTML tags:

    The following is a complete list of the void elements in HTML:

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

    From there you would just test the node to see if it is in the list. For example:

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

    http://jsfiddle.net/3uQjH/

    0 讨论(0)
  • 2020-12-05 12:40

    The W3 standard for "void elements" specifies:

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

    And apparently there's some unofficial tags as well.

    You can make a black list and use .prop('tagName') to get the tag name:

    (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
    

    Here you can also add your own tags to cannotContainText (eg. to add <tr> which is not officially a void element as it doesn't match the specification "A void element is an element whose content model never allows it to have contents under any circumstances. Void elements can have attributes.").

    0 讨论(0)
  • 2020-12-05 12:51

    I mostly agree with everybody that a blacklist would be a very orthodox way of doing it but if we are really required to test for the ability, then this would be one way I think (with some 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;}
    }
    

    I tested it on Chrome on various tags names and got these results:

        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
    

    We may also test some real tags using jquery "prop" on these two examples:

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

    Which gives:

    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
    

    I'm sure it is way away from perfect though, but it was fun to look into.

    0 讨论(0)
提交回复
热议问题