• jquery 获取textarea文本值详解


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

    一开始用val()方法报错,后面使用text(),可以运行,但是获取的值永远为空,最后在改成val(),可以正常使用。

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

    步骤:

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

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

    例子:

    代码:

     1 <!doctype html>
     2 <html lang="en">
     3 <head>
     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>
    View Code

    运行结果截图:

    从上面的例子可以看出:

    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;
        },
    View Code

    从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(/
    /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;
            });
        },
    View Code

    这里由于是获取值,所以只需要看if(value == 'undefined'){...}分支,

    根据代码,可以知道,当元素为input时,走的是else 分支,由语句:

    return (this[0].value || "").replace(/ /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文本节点,至于原理,还不是很清楚,等弄清楚了再说,哈哈。

  • 相关阅读:
    VMware虚拟机安装
    软件测试面试题汇总
    软件测试步骤详解
    软件测试的分类&软件测试生命周期
    BUG 的生命周期
    Jmeter连接Mysql数据库
    Navicat连接Mysql报错:Client does not support authentication protocol requested by server;
    Mysql安装(win10 64位)
    Jmeter生成测试报告
    (转)Jmeter http请求之content-type
  • 原文地址:https://www.cnblogs.com/i-jia/p/5944384.html
Copyright © 2020-2023  润新知