我正在尝试使用Javascript替换Chrome中任意选定的TEXTAREA节点中的所选文本(!不是内容可编辑的div!)我看到在很多地方重复替换所选文本的代码片段基本上是这样的:
var sel = window.getSelection();
var range = sel.getRangeAt(0);
range.insertNode( document.createTextNode("test "));
但是,这不适用于TEXTAREA或INPUT TYPE = TEXT等输入字段。文本在TEXTAREA之前而不是在其中插入。
有一种替代方法可以使用textarea.selectionStart和textarea.selectionEnd修改文本区域内的选择文本。然而,这些需要确定哪个textarea元素实际上是活动/选择的。 Chrome / Webkit document.activeElement似乎已被打破并且已经被打破了很长时间。我找不到任何解决方法来找到“当前选择的textarea”。看到这里的错误......
http://code.google.com/p/chromium/issues/detail?id=14436
你可以在这里看到我试图解决的问题的微型演示。
http://dj1.willowmail.com/~jeske/_drop/insertIssue/1.html
http://ajaxandxml.blogspot.com/2007/11/emulating-activeelement-property-with.html
对此有何想法?
鉴于在任意TEXTAREA节点中选择了任意位文本的网页,如果不提前知道焦点所在的textarea,如何找到活动文本区域并用其他文本替换所选文本?
((仅供参考:我在Chrome扩展程序中使用此代码。页内javascript内容脚本正在扩展页面javascript,所以我不知道页面结构是什么。它需要工作任何网页。))
答案 0 :(得分:2)
我认为您可能遇到的问题是,在代码运行之前单击按钮会导致活动元素发生更改。如果您改为使用mousedown
事件并阻止默认按钮操作,则可以在Chrome中正常运行:
答案 1 :(得分:0)
截至2012年8月23日,似乎Chrome does not properly support activeElement,因为它通常设置为“正文”时不应该。
可能还存在一些挑战,因为在我的Chrome扩展程序中,右键单击以获取上下文菜单可能会改变activeElement。
解决方案是提供focus
处理程序以在Chrome中创建更可靠的activeElement,然后使用与TEXTAREA的直接交互来处理选择替换。
var dActiveElement = null;
function _dom_trackActiveElement(evt) {
if (evt && evt.target) {
dActiveElement = evt.target;
console.log("focus on: " + dActiveElement.nodeName +
" id: " + dActiveElement.id);
} else {
console.log("focus else..");
}
}
if (document.addEventListener) {
document.addEventListener("focus",_dom_trackActiveElement,true);
}
function insertTextAtCursor(text) {
console.log("insertTextAtCursor : " + text);
if (dActiveElement.nodeName.toUpperCase() == "TEXTAREA") {
console.log("selection in textarea! id: " + dActiveElement.id);
var ta = dActiveElement;
var saveSelectionStart = ta.selectionStart;
var newvalue = ta.value.slice(0,ta.selectionStart) +
text + ta.value.slice(ta.selectionEnd,ta.length);
console.log("output : " + newvalue + ", len : " + newvalue.length);
var newSelectionEnd = ta.selectionStart + text.length;
ta.value = newvalue;
ta.selectionStart = ta.selectionEnd = (newSelectionEnd);
}
}