3

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

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

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

“很酷”,我想,直到我意识到.html()and的行为不同.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 提出了一个很好的观点(不知道为什么我没有想到它,实际上 :D ).val(),因为它正在寻找value未定义的属性。.attr()这也与在这种情况下的行为方式一致。

.text()但是,和之间的区别.html()仍然存在。:)

4

1 回答 1

1

它来自实现:

值()

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。我不知道为什么它会返回 null 但你是对的,我在 Chrome 上对其进行了测试。

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

于 2013-11-14T23:19:44.513 回答