Это не имеет ничего общего с функциональностью связывания; это происходит со скопированными ссылками, которые уже есть на странице, и с содержимым credit
, даже если вызов processSel()
закомментирован.
Кажется, это странная ошибка в функции расширенного копирования текста Chrome. Содержание в holder
в порядке; если вы клонируете содержимое выбранного диапазона и в конце предупреждаете его 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);
}
но это довольно уродливо, должно быть ненужным и не исправляет другие встроенные элементы. Bad 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) { ...
1039 *
// 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');
, а затем для каждого совпадения в linkup
проверьте, какая группа совпадений имеет ненулевую длину, и укажите ссылку с hrefs[
того же номера.