• 3.2k

javascript for in 与 $().bind结合出现奇怪的问题!

问题

函数 bindInputBlur() 绑定输入框的输入内容格式限制,但是用了for in 来循环绑定 bind ,结果却发现 当触发 input.bind-emailonblur事件的时候,触发的是 arrRegExp 的最后一个 bind-hobby 而不是 bind-email

代码

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <!--<script src="/jquery.min.js"></script>-->
    <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
</head>
<body>
<input type="text" name="qq" class="bind-email" value="111"/>


<script>

    bindInputBlur();


    function bindInputBlur() {

        var arrRegExp = {
            'bind-email': ["[^a-zA-Z0-9\.@-]+", 20],
            'bind-qq': ['(^0|[\D]+)', 14],
            'bind-phone': ['(^0|[\D]+)', 11],
            'bind-mobile': ['(^0|[\D]+)', 11],
            'bind-vcode-4': ['[^a-zA-Z0-9]+', 4],
            'bind-vcode-sms': ['[\D]', 6],
            'bind-cardNo': ['[\D]+', 18],
            'bind-cardPwd': ['[\D]+', 18],
            'bind-username': ['[^a-zA-Z0-9]', 18],
            'bind-hobby': ['', 13]
        }


        var bindString = 'blur keyup keypress click';
        for (var i in arrRegExp) {
            $('.' + i).bind(bindString, function () {

                console.log(i, arrRegExp[i]);

                if (!this.value || !(i in arrRegExp)) return;
                var _regFind = arrRegExp[i][0] || '';
                var _maxLen = arrRegExp[i][1] || 0;

                if (_regFind) {
                    var regExp = new RegExp(_regFind, 'g');
                    if (regExp && regExp.test(this.value)) {
                        this.value = this.value.replace(regExp, '');
                    }
                }

                if (typeof _maxLen == 'number' && _maxLen && this.value.length > _maxLen) {
                    this.value = this.value.substring(0, _maxLen);
                }
            });
        }

    }


</script>



</body>
</html>
阅读 2.7k
评论
    2 个回答
    • 582

    教科书式的闭包问题+1

    因为是过来人,所以给你举个简单易懂的例子,如果你想了解闭包的更多知识,请阅读闭包在 JavaScript 中的解释。

    // 以下代码不会像你期望的那样工作,因为变量‘i’没有被锁定,每次点击
    // 时警示窗都会显示全部的元素数目,因为在那个点上它正是变量‘i’的值
    
    var elems = document.getElementsByTagName( 'a' );
    
    for ( var i = 0; i < elems.length; i++ ) {
    
    elems[ i ].addEventListener( 'click', function(e){
    e.preventDefault();
    alert( '我是链接 #' + i );
    }, 'false' );
    
    }
    
    // 以下的代码可以达到我们的目的,在这个 IIFE 闭包中,变量‘i’像一个
    // ‘锁定索引’被锁在其中。当循环结束执行时,尽管变量‘i’的值是元素的总数
    // 但在 IIFE 闭包中,‘锁定索引’的值总是当时方法被调用时传入的‘i’值,因此
    // 当一个链接被点击时,警示窗就会显示正确的值了。
    
    var elems = document.getElementsByTagName( 'a' );
    
    for ( var i = 0; i < elems.length; i++ ) {
    
    (function( lockedInIndex ){
    
    elems[ i ].addEventListener( 'click', function(e){
    e.preventDefault();
    alert( '我是链接 #' + lockedInIndex );
    }, 'false' );
    
    })( i );
    
    }
    
    // 你也可以像这样使用一个 IIFE,虽然效果相同,但我觉得上面的写法可读性更高。
    
    var elems = document.getElementsByTagName( 'a' );
    
    for ( var i = 0; i < elems.length; i++ ) {
    
    elems[ i ].addEventListener( 'click', (function( lockedInIndex ){
    return function(e){
    e.preventDefault();
    alert( '我是链接 #' + lockedInIndex );
    };
    })( i ), 'false' );
    
    }
    

    参考链接

      撰写回答

      登录后参与交流、获取后续更新提醒

      相似问题
      推荐文章