jquery 获取textarea文本值详解

今天用jquery获取textarea文本值,遇到这么一个问题:

使用text(),可以运行,但是获取的值永远为空,最后再改成val(),可以正常使用。

于是乎:为了把这个问题弄清楚,开始了遥远的解读jQuery源码之旅

步骤:

1. 给textarea设置默认值,分别输出text()和value()值

2. 改变textarea的文本值,在分别输出text()和value()值

例子:

 
  1. <!doctype html>

  2. <html lang="en">

  3. <head>

    扫描二维码关注公众号,回复: 4286329 查看本文章
  4. <meta charset="utf-8">

  5. <title>dom属性测试</title>

  6. </head>

  7. <body>

  8. <div id="js-div">

  9. <textarea id="js-textarea" >hhhh</textarea>

  10. <button type="button" id="js-button">显示文本</button>

  11.  
  12. <input value="hello world" id="js-input">

  13. </div>

  14. <script type="text/javascript" src="../demo-plugin/public/js/jquery.js"></script>

  15. <script type="text/javascript">

  16. var $textArea = $('#js-textarea'),

  17. textArea = $textArea.val();

  18.  
  19. console.log('val:',textArea);

  20. console.log('text:',$textArea.text());

  21.  
  22. $('#js-button').click(function () {

  23.  
  24. console.log('changed val:',$textArea.val());

  25. console.log('changed text:',$textArea.text());

  26. });

  27. </script>

  28. </body>

  29. </html>

运行结果截图:

从上面的例子可以看出:

1. text()方法只能够获取到textarea的初始化文本值。

2. val() 方法不仅可以获取textarea的初始化文本值,当文本值改变时,也能正常获取到。

接下来,看jquery源码:

1. text()方法:

 
  1. text: function( text ) {

  2. if ( typeof text != "object" && text != null )

  3. return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );

  4.  
  5. var ret = "";

  6.  
  7. jQuery.each( text || this, function(){

  8. jQuery.each( this.childNodes, function(){

  9. if ( this.nodeType != 8 )

  10. ret += this.nodeType != 1 ?

  11. this.nodeValue :

  12. jQuery.fn.text( [ this ] );

  13. });

  14. });

  15.  
  16. return ret;

  17. },

从jquery源码中可以看出,text()方法是通过遍历元素的childNodes,获取每个子节点的nodeValue,拼接成字符串返回。

2. val()方法:

 
  1. val: function( value ) {

  2. if ( value == undefined ) {

  3.  
  4. if ( this.length ) {

  5. var elem = this[0];

  6.  
  7. // We need to handle select boxes special

  8. if ( jQuery.nodeName( elem, "select" ) ) {

  9. var index = elem.selectedIndex,

  10. values = [],

  11. options = elem.options,

  12. one = elem.type == "select-one";

  13.  
  14. // Nothing was selected

  15. if ( index < 0 )

  16. return null;

  17.  
  18. // Loop through all the selected options

  19. for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {

  20. var option = options[ i ];

  21.  
  22. if ( option.selected ) {

  23. // Get the specifc value for the option

  24. value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;

  25.  
  26. // We don't need an array for one selects

  27. if ( one )

  28. return value;

  29.  
  30. // Multi-Selects return an array

  31. values.push( value );

  32. }

  33. }

  34.  
  35. return values;

  36.  
  37. // Everything else, we just grab the value

  38. } else

  39. return (this[0].value || "").replace(/\r/g, "");

  40.  
  41. }

  42.  
  43. return undefined;

  44. }

  45.  
  46. return this.each(function(){

  47. if ( this.nodeType != 1 )

  48. return;

  49.  
  50. if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )

  51. this.checked = (jQuery.inArray(this.value, value) >= 0 ||

  52. jQuery.inArray(this.name, value) >= 0);

  53.  
  54. else if ( jQuery.nodeName( this, "select" ) ) {

  55. var values = value.constructor == Array ?

  56. value :

  57. [ value ];

  58.  
  59. jQuery( "option", this ).each(function(){

  60. this.selected = (jQuery.inArray( this.value, values ) >= 0 ||

  61. jQuery.inArray( this.text, values ) >= 0);

  62. });

  63.  
  64. if ( !values.length )

  65. this.selectedIndex = -1;

  66.  
  67. } else

  68. this.value = value;

  69. });

  70. },

这里由于是获取值,所以只需要看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文本节点,至于原理,还不是很清楚,等弄清楚了再说,哈哈。

转载自:https://www.cnblogs.com/i-jia/p/5944384.html

猜你喜欢

转载自blog.csdn.net/qq_35661171/article/details/84617546
今日推荐