在 google 扩展程序中使用 DOM
我正在创建一个Google Chrome 扩展程序,我需要在其中将链接插入到gmail窗口中。我能够在窗口顶部创建一个简单的扩展按钮并执行替换电子邮件文档中元素的代码。
现在,我想在我键入时在contenteditable部分中添加链接。似乎应该有一种简单的方法来用 javascript 文档对象模型中的链接替换文本。这也只需要为 chrome 工作,因为我不打算很快创作一个 firefox 或 ie 版本。
最初我试图做以下事情:
- 从当前插入符号位置插入文本
- 捕获插入符号位置。
- 通过偏移量设置插入符号的位置。
getSelection,没那么快
我尝试在 gmail 上下文中使用window.getSelection(这是一个设置为 contenteditable 并嵌入到 gmail 选项卡中的 iframe 中的正文元素)来获取当前范围和位置。无论是否选择了文本,选择始终为空且不包含任何范围。
我发现getSelection代码不起作用的原因是因为在错误的窗口上选择了document.getSelection 。当您在 gmail 中创建新消息时,有 5 个 iframe(windows)可用。在这个框架内部有一个称为嵌套的 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);
在我的许多试验中似乎普遍存在一个问题,现在已经消失了。这产生了一些奇怪的链接,这些链接延伸到以下单词。
随时帮我清理代码以使其更简洁