为什么 JQuery 在空的 JQuery 对象上使用时给出不同的结果 .text()、.html() 和 .val()

  • 本文关键字:JQuery 结果 text val html 对象 jquery html dom
  • 更新时间 :
  • 英文 :


这实际上不是一个实际的问题,更多的是理论性的,但它确实影响了我目前正在编写的一些代码,所以我会继续问。

我正在使用 JQuery 来解析 XML 提要并根据返回的 XML 元素构建页面元素。 XML被转换为JQuery对象,并且访问元素很好。

有一次,当我检索值时,我会测试一个元素是否存在并使用 .text() 检索它的内容。 我想小心检查以确保我的选择器在检查文本之前返回了一些东西,但注意到一些有趣的东西...... .text()似乎并不在乎。 如果选择器返回的 JQuery 对象为空,则在其上使用时.text()将返回""

"很酷",我想,直到我意识到.html().val()的行为是不同的...... .html()返回null.val()返回undefined(在 Firefox 中。在IE中,它们都返回undefined)。

试试看:

var tempVal = $("#noWayThisIsAnElement");
window.console.log(tempVal.text());          // returns ""
window.console.log(tempVal.html());          // returns null (undefined, in IE)
window.console.log(tempVal.val());           // returns undefined

那么,有谁知道这背后的原因是什么?

我问的主要原因是,考虑到他们正在寻找类似的价值观(概念上),你会认为"哎呀,不能那样做"的结果是相同的。

我想我可以看到.val()可能与其他两种不同,因为它可以返回三种数据类型之一,但即使你删除它,.text().html()都返回字符串,这些字符串代表 DOM 节点的内容......您可能会认为,当 JQuery 对象不保留对节点的引用时,它们都会给出类似的结果。

所以,我想我现在会针对这两种情况进行不同的编码,但是,与此同时,有人在这里有任何见解吗?


更新:Kevin B 提出了一个关于.val()的好点(不知道为什么我没有想到它,实际上是:D),因为它正在寻找未定义的 value 属性。 这也与.attr()在这种情况下的行为方式一致。

不过,.text().html()之间的差异仍然悬而未决。 :)

它来自实现:

瓦尔()

val: function( value ) {
        var ret, hooks, isFunction,
            elem = this[0];
        if ( !arguments.length ) {
            if ( elem ) {
                hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
                if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
                    return ret;
                }
                ret = elem.value;
                return typeof ret === "string" ?
                    // handle most common string cases
                    ret.replace(rreturn, "") :
                    // handle cases where value is null/undef or number
                    ret == null ? "" : ret;
            }
            return;
        }

如您所见,如果没有 elem (即空的 jquery 对象),函数直接return;:你得到了一个undefined

文本()

jQuery.fn.extend({
    text: function( value ) {
        return jQuery.access( this, function( value ) {
            return value === undefined ?
                jQuery.text( this ) :
                this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
        }, null, value, arguments.length );
    },

getTextjQuery.text()功能的实现

getText = Sizzle.getText = function( elem ) {
    var node,
        ret = "",
        i = 0,
        nodeType = elem.nodeType;
    if ( !nodeType ) {
        // If no nodeType, this is expected to be an array
        for ( ; (node = elem[i]); i++ ) {
            // Do not traverse comment nodes
            ret += getText( node );
        }
    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
        // Use textContent for elements
        // innerText usage removed for consistency of new lines (see #11153)
        if ( typeof elem.textContent === "string" ) {
            return elem.textContent;
        } else {
            // Traverse its children
            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                ret += getText( elem );
            }
        }
    } else if ( nodeType === 3 || nodeType === 4 ) {
        return elem.nodeValue;
    }
    // Do not include comment or processing instruction nodes
    return ret;
};

如您所见,对于空对象,我们不会在任何条件下输入。 ret初始化为 ",因此返回 "。

html()

html: function( value ) {
return jQuery.access( this, function( value ) {
    var elem = this[0] || {},
        i = 0,
        l = this.length;
    if ( value === undefined ) {
        return elem.nodeType === 1 ?
            elem.innerHTML.replace( rinlinejQuery, "" ) :
            undefined;
    }

在这里,您可以看到它也返回undefined。我不知道为什么它会返回空值,但你是对的,我在 Chrome 上测试了它。

如果其他人可以完成这篇文章。

最新更新