JS JQuery Highlight Plugin toUpperCase не является функцией, вызывает бесконечный цикл - PullRequest
2 голосов
/ 04 октября 2011

Я пытаюсь отредактировать плагин 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)

anyПомощь будет принята с благодарностью!

1 Ответ

4 голосов
/ 04 октября 2011

О, дорогой.Этот плагин использует нефильтрованный цикл 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]);
}
...