Почему был бы ниже устранять пробел вокруг подобранного текста ключевого слова при замене его ссылкой привязки? Отметьте, эта ошибка только происходит в 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);
Заранее спасибо за Вашу справку. Я почти готов запустить сценарий и с удовольствием прокомментирую в благодарности Вам для Вашей помощи.
Это не имеет ничего общего с функцией связывания; это случается с скопированными ссылками, которые уже есть на странице, и содержанием кредита
, даже если вызов 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 [
с тем же номером.
Я хотел бы помочь вам больше, но об этом сложно догадаться, не имея возможности проверить это, но я полагаю, вы можете обойти это, добавив пробелоподобные символы вокруг ваших ссылок, например .
.
Кстати, эта ваша функция, которая добавляет полезные ссылки на копирование, действительно интересна.