jquery 获取textarea文本值详解
今天用jquery获取textarea文本值,遇到这么一个问题:
使用text(),可以运行,但是获取的值永远为空,最后再改成val(),可以正常使用。
于是乎:为了把这个问题弄清楚,开始了遥远的解读jQuery源码之旅
步骤:
1. 给textarea设置默认值,分别输出text()和value()值
2. 改变textarea的文本值,在分别输出text()和value()值
例子:
-
<!doctype html>
-
<html lang="en">
-
<head>
-
<meta charset="utf-8">
-
<title>dom属性测试</title>
-
</head>
-
<body>
-
<div id="js-div">
-
<textarea id="js-textarea" >hhhh</textarea>
-
<button type="button" id="js-button">显示文本</button>
-
<input value="hello world" id="js-input">
-
</div>
-
<script type="text/javascript" src="../demo-plugin/public/js/jquery.js"></script>
-
<script type="text/javascript">
-
var $textArea = $('#js-textarea'),
-
textArea = $textArea.val();
-
console.log('val:',textArea);
-
console.log('text:',$textArea.text());
-
$('#js-button').click(function () {
-
console.log('changed val:',$textArea.val());
-
console.log('changed text:',$textArea.text());
-
});
-
</script>
-
</body>
-
</html>
运行结果截图:
从上面的例子可以看出:
1. text()方法只能够获取到textarea的初始化文本值。
2. val() 方法不仅可以获取textarea的初始化文本值,当文本值改变时,也能正常获取到。
接下来,看jquery源码:
1. text()方法:
-
text: function( text ) {
-
if ( typeof text != "object" && text != null )
-
return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
-
var ret = "";
-
jQuery.each( text || this, function(){
-
jQuery.each( this.childNodes, function(){
-
if ( this.nodeType != 8 )
-
ret += this.nodeType != 1 ?
-
this.nodeValue :
-
jQuery.fn.text( [ this ] );
-
});
-
});
-
return ret;
-
},
从jquery源码中可以看出,text()方法是通过遍历元素的childNodes,获取每个子节点的nodeValue,拼接成字符串返回。
2. val()方法:
-
val: function( value ) {
-
if ( value == undefined ) {
-
if ( this.length ) {
-
var elem = this[0];
-
// We need to handle select boxes special
-
if ( jQuery.nodeName( elem, "select" ) ) {
-
var index = elem.selectedIndex,
-
values = [],
-
options = elem.options,
-
one = elem.type == "select-one";
-
// Nothing was selected
-
if ( index < 0 )
-
return null;
-
// Loop through all the selected options
-
for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
-
var option = options[ i ];
-
if ( option.selected ) {
-
// Get the specifc value for the option
-
value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
-
// We don't need an array for one selects
-
if ( one )
-
return value;
-
// Multi-Selects return an array
-
values.push( value );
-
}
-
}
-
return values;
-
// Everything else, we just grab the value
-
} else
-
return (this[0].value || "").replace(/\r/g, "");
-
}
-
return undefined;
-
}
-
return this.each(function(){
-
if ( this.nodeType != 1 )
-
return;
-
if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
-
this.checked = (jQuery.inArray(this.value, value) >= 0 ||
-
jQuery.inArray(this.name, value) >= 0);
-
else if ( jQuery.nodeName( this, "select" ) ) {
-
var values = value.constructor == Array ?
-
value :
-
[ value ];
-
jQuery( "option", this ).each(function(){
-
this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
-
jQuery.inArray( this.text, values ) >= 0);
-
});
-
if ( !values.length )
-
this.selectedIndex = -1;
-
} else
-
this.value = value;
-
});
-
},
这里由于是获取值,所以只需要看if(value == 'undefined'){...}分支,
根据代码,可以知道,当元素为input时,走的是else 分支,由语句:
return (this[0].value || "").replace(/\r/g, "");
可以看出,返回的元素的value值。
说了一堆,一定很疑惑分析这个有什么用,别走开,接下来更精彩:
页面初始化时:打印$('#js-textarea'),看看控制台都输出什么东西:
上面两张图可以看出,在为改变textarea的文本值时,textarea的value属性值=初始值,nodeValue值为null,text()方法返回的是childNodes里面每个节点的nodeValue值拼接起来的字符串,注意区分。
接着看childNodes里面的内容:
可以看出,textarea有一个text文本节点,这个文本节点的nodeValue = 初始值。
接下来:改变文本框的文本值,输出$('#js-textarea'),见证奇迹的时刻到了:
先看textarea的value属性值:
value值改变,那么子节点text的nodeValue值有没有变化呢,看截图
从上图可以看出:很遗憾,textarea的childNodes里面text文本节点的nodeValue值并没有发生变化。
为什么会出现这个现象,我也还不知道,不过这个测试结果说明了,为什么val()方法可以正常取值,而text()取值会出现问题。
后记:经过研究,发现自闭合标签childNodes长度为0,而其他标签至少有一个text文本节点,至于原理,还不是很清楚,等弄清楚了再说,哈哈。