这实际上不是一个实际的问题,更多的是理论性的,但它确实影响了我目前正在编写的一些代码,所以我会继续问。
我正在使用 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 );
},
getText
是jQuery.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 上测试了它。
如果其他人可以完成这篇文章。