Javascript:Chrome中删除了空白字符(但不是Firefox)

时间:2010-06-02 00:01:23

标签: javascript text whitespace

为什么在用锚链接替换它时,下面会消除匹配关键字文本周围的空白?请注意,此错误仅发生在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);

提前感谢您的帮助。我已经准备好发布剧本,并乐意向你发表评论,以求你的帮助。

2 个答案:

答案 0 :(得分:2)

这与链接功能无关;它恰好复制了页面上已有的链接以及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);
}

但这非常难看,应该是不必要的,并且不会修复其他内联元素。糟糕的Chrome!

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

依靠innerHTML从元素中获取文本是不明智的,因为浏览器可能会转义或不转义字符。最值得注意的是&,但无法保证浏览器的innerHTML属性将输出哪些字符。

由于您似乎已经在使用jQuery,请改为使用text()抓取内容。

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

每次都会失败,因为g lobal regexp会记住他们之前的状态(lastIndex):当与test这样的方法一起使用时,你应该继续调用反复,直到他们没有回来。

这里似乎不需要g(多个匹配)...但是,您似乎不需要regexp,因为简单的字符串indexOf会更可靠。 (在正则表达式中,域中的每个.都匹配链接中的任何字符。)

更好的是,使用Location上的URL分解属性来直接比较主机名,而不是整个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来电。你可以在this answer中获取函数的内部位(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[相关联。

答案 1 :(得分:0)

我想帮助你更多,但是如果不能测试它就很难猜测,但我想你可以通过在链接周围添加类似空格的字符来解决它,例如。 &nbsp;

顺便说一句,你的这个功能增加了有用的复制链接非常有趣。