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

发布于 2024-12-07 21:01:47 字数 1784 浏览 0 评论 0原文

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

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

这是我到目前为止所拥有的。有问题的代码位于最后的 return 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)

任何帮助将不胜感激!

I am trying to edit the jQuery hightlight plug in to highlight multiple words. It works great until you hit the space bar, then it causes FF to freeze in an infinite loop.

FireBug reports that .toUpperCase is not a function, but when I change the same code back, so it is not altering an array element, it's fine, but does not highlight the two words, only the first one. When the space bar is hit all highlighting goes away.

Here is the what I have so far. The code in question is in the return this.each(function(){}) block at the end:

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

Here is the console output in 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)

any help would be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

非要怀念 2024-12-14 21:01:47

哦亲爱的。该插件使用未过滤的 for...in 循环来迭代数组。 这很糟糕:

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

因为迭代的顺序取决于实现,所以迭代
数组上的元素可能不会以一致的顺序访问。所以
迭代时最好使用带有数字索引的 for 循环
在访问顺序很重要的数组上。

如果只考虑对象的属性,则
应执行 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]);
}

Oh dear. That plugin is using an unfiltered for...in loop to iterate over an array. 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).


So, change this:

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

to this:

for (var i=0; i<parts.length; i++) {
    innerHighlight(this, parts[i].toUpperCase());
    console.log("parts["+i+"] >> " + parts[i]);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文