JS JQuery Highlight Plugin toUpperCase不是一个函数,导致无限循环

时间:2011-10-04 14:15:36

标签: javascript jquery plugins highlight

我正在尝试编辑jQuery hightlight插件以突出显示多个单词。它很有效,直到你击中空格键,然后它导致FF在无限循环中冻结。

FireBug报告.toUpperCase不是一个函数,但是当我更改相同的代码时,所以它没有改变数组元素,没关系,但是没有突出显示两个单词,只有第一个单词。当空格键被击中时,所有突出显示都会消失。

这是我到目前为止所拥有的。有问题的代码在最后返回this.each(function(){})块中:

jQuery.fn.highlight = function(pat) {
function innerHighlight(node, pat) {
    var skip = 0;

    if (node.nodeType == 3) {
        var pos = node.data.toUpperCase().indexOf(pat);
        if (pos >= 0) {
            var spannode = document.createElement('span');
            spannode.className = 'highlight';
            var middlebit = node.splitText(pos);
            var endbit = middlebit.splitText(pat.length);
            var middleclone = middlebit.cloneNode(true);
            spannode.appendChild(middleclone);
            middlebit.parentNode.replaceChild(spannode, middlebit);
            skip = 1;
        }
    } else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
        for (var i = 0; i < node.childNodes.length; ++i) {
            i += innerHighlight(node.childNodes[i], pat);
        }
    }

    return skip;    
}
return this.each(function() {
    var parts = pat.split(' ');
    console.log(parts);
    for (var i in parts) {
        innerHighlight(this, parts[i].toUpperCase());
        console.log("parts["+i+"] >> " + parts[i]);
    }
});
};

以下是FireBug中的控制台输出:

["guy"]                            jquery...ht-3.js (line 46)
parts[0] >> guy                    jquery...ht-3.js (line 49)
parts[i].toUpperCase is not a function
    [Break On This Error] innerHighlight(this, parts[i].toUpperCase());
                                   jquery...ht-3.js (line 48)

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:4)

亲爱的,亲爱的。该插件使用未经过滤的for...in循环来迭代数组。的 That's bad:

  

for...in不应该用于迭代索引的数组   订单很重要。数组索引只是可枚举的属性   整数名称,并且与一般对象相同   属性。无法保证for...in将返回   任何特定顺序的索引,它将返回所有可枚举的   属性,包括具有非整数名称和属性的属性   继承的。

     

因为迭代的顺序是依赖于实现的,所以迭代   在数组上可能无法以一致的顺序访问元素。因此   迭代时最好使用带有数字索引的for循环   在数组中,访问顺序很重要。

     

只应考虑对象的属性,a   应执行hasOwnProperty检查以确保仅   使用对象的属性而不是继承的属性   (propertyIsEnumerable也可以使用,但不直观)。


所以,改变一下:

for (var i in parts) {
    innerHighlight(this, parts[i].toUpperCase());
    console.log("parts["+i+"] >> " + parts[i]);
}

到此:

for (var i=0; i<parts.length; i++) {
    innerHighlight(this, parts[i].toUpperCase());
    console.log("parts["+i+"] >> " + parts[i]);
}