我正在尝试编辑 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 thatfor...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/