博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

IE 6/7下自赋值导致 overflow 溢出

Posted on 2014-02-17 21:08  Object.prototype  阅读(459)  评论(0编辑  收藏  举报

情景是要限制一个textarea的最大输入字数(100字,  这字数限制也太少了点吧,不大气)

 

由于限制输入后需要允许 回退,全选等功能键,故放弃keyup, keydown组合

选用property 和 input事件, 由于ff 和 chrome支持maxlength,故这里就只为ie加事件处理

$addDescArea.on("propertychange", function (e) {
               
                if ($addDescArea.val().length >= 100) {
                    $addDescArea.val($addDescArea.val().substr(0, 100));
    
                }
            });

代码很简单,当>=100字时,截取前100个字符

 

但是在IE6/7 下会抛出如下异常

"Stack Overflow at line 0"

后来google之后,得到原因是触发了死循环

即:

$addDescArea.val($addDescArea.val().substr(0, 100));
上面代码中
$addDescArea.val 方法在反复的调用和递归,

于是我把代码改为
var text = $addDescArea.val();

if(text.length > 100)
{
     $addDescArea.val(text.substr(0, 100))
}

把原始value存到一个变量里,但是错误依旧, 

最后只能尝试 另外声明一个变量把当前的 value存放进去,然后再用这个新的变量赋值

 $addDescArea.on("propertychange", function (e) {
                var areaText = $addDescArea.val(),
                    maxLength = parseInt(e.target.getAttribute("data-maxlength") || 100, 10),
                    cutText = areaText.substr(0, maxLength);

                if (areaText.length >= maxLength) {
                    $addDescArea.val(cutText);
                }
            });

 

最后个bug的根本原因是:

在IE6/7 上

var text = $addDescArea.val()

是指向栈中的一块大小为$addDescArea.val()的string类型的空间(称为x)

而$addDescArea.value(aa) 则是将x修改为aa, 并非新开一块大小为aa的栈空间

 

所以

$addDescArea.val($addDescArea.val().substr(0, 100));
是在循环递归的操作这同一块栈空间,导致发生死循环

解决方法就是将textArea.val() 拷贝一份然后再赋值,
areaText.substr(0, maxLength); 
此处的substr就是创建了一个新的string