阻止JavaScript window.getSelection()循环引用
查看此演示(取决于selectionchange事件,该事件目前仅在Chrome中起作用): 选择一些lorem ipsum文本,然后聚焦文本输入。在控制台日志中,您将看到有一个DOMSelection对象。 它的锚定节点值为阻止JavaScript window.getSelection()循环引用,javascript,selection,circular-reference,Javascript,Selection,Circular Reference,查看此演示(取决于selectionchange事件,该事件目前仅在Chrome中起作用): 选择一些lorem ipsum文本,然后聚焦文本输入。在控制台日志中,您将看到有一个DOMSelection对象。 它的锚定节点值为HTMLBodyElement,而它的锚定节点值应为Text 我不知道为什么会发生这种情况,直到我尝试对选择对象进行字符串化: 这会产生以下错误: 未捕获类型错误:将循环结构转换为JSON 您知道如何防止window.getSelection()引起的循环引用吗? 编辑 新
HTMLBodyElement
,而它的锚定节点值应为Text
我不知道为什么会发生这种情况,直到我尝试对选择对象进行字符串化:
这会产生以下错误:
未捕获类型错误:将循环结构转换为JSON
您知道如何防止window.getSelection()引起的循环引用吗?
编辑
新的演示也适用于其他浏览器,但仍然提供了错误的主播代码:
使用JSON.stringify:
Firefox似乎返回空的{},而不是抛出错误。您需要在
getSelection()上调用toString()
。我必须按照你的期望行事
var selection;
$('p').bind('mouseup', function() {
selection = window.getSelection().toString();
});
$('input').bind('focus', function() {
this.value = selection;
console.log(selection);
});
编辑:
无法获得正确的锚节点的原因是,DOMSelection
对象是通过引用传递的,当您关注输入时,选择将被清除,从而返回对应于无选择的默认选择。解决此问题的一种方法是将DOMSelection
属性克隆到一个对象并引用该对象。您将不再拥有原型DOMSelection
方法,但是根据您想要做的事情,这可能就足够了
var selection, clone;
$('p').bind('mouseup', function() {
selection = window.getSelection();
clone = {};
for (var p in selection) {
if (selection.hasOwnProperty(p)) {
clone[p] = selection[p];
}
}
});
$('input').bind('focus', function() {
console.dir(clone);
});
您的小提琴缺少json2 js库。JSON是ECMAScript 5中的本机对象。不需要包括图书馆。真的吗?我们都知道有多少浏览器支持这一点。。。不是吗?是的,我们有。然而,这不是重点。你真的对这个问题有答案吗?好的,在FF5和IE9上试过。无法复制。IE9返回空对象,FF日志未定义
。似乎是chrome唯一的问题。谢谢你的回答。通过从selection对象生成字符串,该对象将丢失,因此它不是一个合适的解决方案。然后存储getSelection()
,并在需要内容时调用toString()
。存储getSelection()正是我在演示中所做的()。如果您解释您试图用选择来完成什么,而不是什么出错,我们可能会有更好的帮助。我想要的输出是一个selection
变量,它包含完整的DOMSelection对象,带有selection.anchorNode.parentNode.nodeName
givingP
,而不是HTML
。