javascript - JS JQuery 高亮插件 toUpperCase 不是函数,导致无限循环

标签 javascript jquery plugins highlight

我正在尝试编辑 jQuery hightlight 插件来突出显示多个单词。它工作得很好,直到你按下空格键,然后它会导致 FF 卡住在无限循环中。

FireBug 报告 .toUpperCase 不是一个函数,但是当我更改相同的代码时,它不会更改数组元素,这很好,但不会突出显示这两个单词,仅突出显示第一个单词。当按下空格键时,所有突出显示都会消失。

这是我到目前为止所拥有的。有问题的代码位于末尾的 return this.each(function(){}) block 中:

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)

任何帮助将不胜感激!

最佳答案

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

for...in should not be used to iterate over an Array where index order is important. Array indexes are just enumerable properties with integer names and are otherwise identical to general Object properties. There is no guarantee that for...in will return the indexes in any particular order and it will return all enumerable properties, including those with non–integer names and those that are inherited.

Because the order of iteration is implementation dependent, iterating over an array may not visit elements in a consistent order. Therefore it is better to use a for loop with a numeric index when iterating over arrays where the order of access is important.

Where only the properties of the object should be considered, a hasOwnProperty check should be performed to ensure that only properties of the object and not inherited properties are used (propertyIsEnumerable can also be used but is not intuitive).


所以,改变这个:

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]);
}

关于javascript - JS JQuery 高亮插件 toUpperCase 不是函数,导致无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7649297/

相关文章:

javascript - 添加到集合时指定额外属性

javascript - Yii2 动态表单中的自定义字段

php - CakePHP 2.x 插件和插件文件夹之间有什么区别?

scala - 哪些scala编译器插件可用?

javascript - 在编写 jquery 插件时,如何从另一个方法调用我的主要插件方法之一?

javascript - 如何使文本可根据浏览器调整大小?

javascript - 为什么在逗号运算符中抛出异常不会停止其他操作数的求值?

javascript - 理解 bootstrap.js 变量声明

c# - WebMatrix 填充属性和 JavaScript 读取属性未产生预期结果

jquery - 在 JQuery 中连接 2 个表列