JavaScript: Пробельные символы, Удаляемые в Chrome (но не Firefox)

Почему был бы ниже устранять пробел вокруг подобранного текста ключевого слова при замене его ссылкой привязки? Отметьте, эта ошибка только происходит в Chrome и не Firefox.

Для полного контекста файл расположен в: http://seox.org/lbp/lb-core.js

Для просмотра кода в действии (никакие ошибки, найденные все же), демонстрационная страница по http://seox.org/test.html. Копируйте/Вставляйте первый абзац в визуальный редактор (т.е.: dreamweaver или Gmail с включенным визуальным редактором), покажет проблему, со словами, сгруппированными вместе. Вставка его в редактора простого текста не будет.

// Find page text (not in links) -> doxdesk.com
function findPlainTextExceptInLinks(element, substring, callback) {
    for (var childi= element.childNodes.length; childi-->0;) {
        var child= element.childNodes[childi];
        if (child.nodeType===1) {
            if (child.tagName.toLowerCase()!=='a')
                findPlainTextExceptInLinks(child, substring, callback);
        } else if (child.nodeType===3) {
            var index= child.data.length;
            while (true) {
                index= child.data.lastIndexOf(substring, index);
                if (index===-1 || limit.indexOf(substring.toLowerCase()) !== -1)
                    break;
                // don't match an alphanumeric char
                var dontMatch =/\w/;
                if(child.nodeValue.charAt(index - 1).match(dontMatch) || child.nodeValue.charAt(index+keyword.length).match(dontMatch))
                    break;
                // alert(child.nodeValue.charAt(index+keyword.length + 1));
                callback.call(window, child, index)
            }
        }
    }
}

// Linkup function, call with various type cases (below)
function linkup(node, index) {

    node.splitText(index+keyword.length);
    var a= document.createElement('a');
    a.href= linkUrl;
    a.appendChild(node.splitText(index));
    node.parentNode.insertBefore(a, node.nextSibling);
    limit.push(keyword.toLowerCase()); // Add the keyword to memory
    urlMemory.push(linkUrl); // Add the url to memory
}

// lower case (already applied)
findPlainTextExceptInLinks(lbp.vrs.holder, keyword, linkup);

Заранее спасибо за Вашу справку. Я почти готов запустить сценарий и с удовольствием прокомментирую в благодарности Вам для Вашей помощи.

1
задан Matrym 2 June 2010 в 00:01
поделиться

2 ответа

Это не имеет ничего общего с функцией связывания; это случается с скопированными ссылками, которые уже есть на странице, и содержанием кредита , даже если вызов processSel () закомментирован.

Похоже, это странная ошибка в функции копирования форматированного текста Chrome. Содержимое держателя в порядке; если вы cloneContents выбранный диапазон и предупреждаете его innerHTML в конце, пробелы явно там. Но пробелы непосредственно перед, сразу после и по внутренним краям любого встроенного элемента (не только ссылок!) Не отображаются в форматированном тексте.

Даже если вы добавляете в модель DOM новые текстовые узлы, содержащие пробелы рядом со ссылкой, Chrome их проглатывает. Мне удалось заставить его выглядеть правильно, вставив неразрывные пробелы:

var links= lbp.vrs.holder.getElementsByTagName('a');
for (var i= links.length; i-->0;) {
    links[i].parentNode.insertBefore(document.createTextNode('\xA0 '), links[i]);
    links[i].parentNode.insertBefore(document.createTextNode(' \xA0), links[i].nextSibling);
}

, но это довольно некрасиво, должно быть ненужным и не исправляет другие встроенные элементы. Плохой Chrome!

var keyword = links[i].innerHTML.toLowerCase();

Неразумно полагаться на innerHTML для получения текста из элемента, поскольку браузер может экранировать или не экранировать символы в нем. В первую очередь и , но нет никакой гарантии, какие символы выведет свойство браузера innerHTML .

Поскольку вы, кажется, уже используете jQuery, вместо этого возьмите содержимое с помощью text () .

var isDomain = new RegExp(document.domain, 'g');
if (isDomain.test(linkUrl)) { ...

Это будет терпеть неудачу каждый раз, потому что g лобальные регулярные выражения запоминают свое предыдущее состояние ( lastIndex ): при использовании с такими методами, как test , вы должны продолжать звонить несколько раз, пока они не вернут ни одного совпадения.

Похоже, вам здесь не нужен g (несколько совпадений) ... но тогда вам, похоже, не нужно здесь регулярное выражение, поскольку простая строка indexOf будет более надежный. (В регулярном выражении каждый . в домене будет соответствовать любому символу в ссылке.)

Еще лучше использовать свойства разложения URL в Location для прямого сравнения имена хостов, а не грубое сопоставление строк по всему URL-адресу:

if (location.hostname===links[i].hostname) { ...

// don't match an alphanumeric char
var dontMatch =/\w/;
if(child.nodeValue.charAt(index - 1).match(dontMatch) || child.nodeValue.charAt(index+keyword.length).match(dontMatch))
    break;

Если вы хотите сопоставить слова на границах слов и без учета регистра, я думаю, вам будет лучше использовать регулярное выражение, а не простое сопоставление подстрок . Это также сэкономило бы четыре вызова findText для каждого ключевого слова, как оно есть в данный момент. Вы можете взять внутренний бит (в if (child.nodeType == 3) {... ) функции в этом ответе и использовать его вместо текущего сопоставления строк.

При создании регулярных выражений из строки раздражает то, что к знакам препинания добавляется множество обратных косых черт, поэтому вам понадобится функция для этого:

// Backslash-escape string for literal use in a RegExp
//
function RegExp_escape(s) {
    return s.replace(/([/\\^$*+?.()|[\]{}])/g, '\\$1')
};

var keywordre= new RegExp('\\b'+RegExp_escape(keyword)+'\\b', 'gi');

Для повышения эффективности вы даже можете сделать все замены ключевых слов за один раз:

var keywords= [];
var hrefs= [];
for (var i=0; i<links.length; i++) {
    ...
    var text= $(links[i]).text();
    keywords.push('(\\b'+RegExp_escape(text)+'\\b)');
    hrefs.push[text]= links[i].href;
}
var keywordre= new RegExp(keywords.join('|'), 'gi');

, а затем для каждого совпадения в ссылке , проверьте, какая группа совпадений имеет ненулевую длину, и свяжите с hrefs [ с тем же номером.

2
ответ дан 3 September 2019 в 00:08
поделиться

Я хотел бы помочь вам больше, но об этом сложно догадаться, не имея возможности проверить это, но я полагаю, вы можете обойти это, добавив пробелоподобные символы вокруг ваших ссылок, например . .

Кстати, эта ваша функция, которая добавляет полезные ссылки на копирование, действительно интересна.

0
ответ дан 3 September 2019 в 00:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: