在Google扩展程序中使用DOM
我正在创建 Google Chrome扩展程序,我需要在 gmail 窗口中插入一个链接。我能够在窗口顶部创建一个简单的扩展按钮,并执行替换电子邮件文档中元素的代码。
现在,我想在输入时在 contenteditable 部分添加链接。似乎应该有一种简单的方法用javascript文档对象模型中的链接替换文本。此外,这只需要适用于chrome,因为我不打算很快创建一个firefox或ie版本。
最初我尝试执行以下操作:
getSelection,不是那么快
我尝试在gmail上下文中使用 window.getSelection (这是一个设置为contenteditable并嵌入gmail选项卡中的iframe内部的body元素)来获取当前范围和位置。无论是否选择了文本,选择始终为空并且不包含范围。
我发现 getSelection 代码不起作用的原因是因为在错误的窗口上选择了 document.getSelection 。在gmail中创建新邮件时,有5个iframe(窗口)可用。在此框架内有一个名为嵌套深度的iframe,需要调用 getSelection 才能获得正确的文本选择。以下是一些代码,可让您在电子邮件消息的特定区域内获取所选的插入位置。
这是获取gmail文档窗口选择的一种方法
var mySelection = $("iframe")[4].contentDocument.
querySelector("iframe").contentDocument.getSelection();
第一次文字替换尝试
我现在有希望更接近解决方案了。对不起,如果它马虎,我找不到任何关于如何编写此代码的好文档。
// Select the keyword
var range = s.getRangeAt(0);
var keyEl = range.startContainer.splitText(index);
var newRange = doc.createRange();
newRange.selectNode(keyEl);
s.removeAllRanges();
newRange.setEnd(keyEl, length);
s.addRange(newRange);
// Insert the link
var newLink = document.createElement("a");
newLink.setAttribute("href", value);
s.removeAllRanges();
newRange.surroundContents(newLink);
// Set the position
newRange.setStartAfter(newLink);
newRange.collapse(true);
s.addRange(newRange);
这几乎完美无缺,但问题是文本插入符号位于链接内部,因此只需插入链接后输入的任何文本。这是个大问题。并且,尝试一些我能够使问题部分消失的事情。一个类似的新问题导致一些奇怪的链接延伸到下面的单词,但仅限于几个字符。
希望最后尝试更换文字
// find position in text
var index = s.focusNode.data.search(keyword);
var length = keyword.length;
var range = s.getRangeAt(0);
var keyEl = range.startContainer.splitText(index);
var newRange = doc.createRange();
newRange.selectNode(keyEl);
s.removeAllRanges();
newRange.setEnd(keyEl, length);
s.addRange(newRange);
var newLink = document.createElement("a");
newLink.setAttribute("href", value);
$(newLink).css("text-decoration", "none");
$(newLink).css("cursor", "pointer");
$(newLink).css("color", "color:#3366FF");
newRange.surroundContents(newLink);
newRange.collapse(false);
s.removeAllRanges();
s.addRange(newRange);
在我的许多试验中,有一个问题似乎已经普遍存在,现在已经消失了。这使得一些奇怪的链接延伸到下面的单词。
随时帮我清理代码,使其更简洁
答案 0 :(得分:0)
如果您确切知道要插入插入符号的位置,则应该这样做:
var node = someTextNode;
var caret = 10; // insert caret after the 10th character
var range = document.createRange();
range.setStart(node,caret);
range.setEnd(node,caret);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
但这仅适用于DOM文本节点。因此,如果你想操纵一个contenteditable div或类似的内容,你将不得不递归遍历其子元素并检查文本节点。
我最近写了一个Chrome扩展程序,在包括GMail在内的网站上进行文本替换 - 这里是相应jQuery插件的来源,如果它适合您的使用案例,请随意利用它:https://github.com/squidpeople/ASCIImoji/blob/master/asciimoji.jquery.js