阻止JavaScript window.getSelection()循环引用

时间:2011-07-30 01:32:14

标签: javascript selection circular-reference

请参阅此演示(取决于此时仅在Chrome中有效的selectionchange事件):http://jsfiddle.net/fyG3H/

选择一些lorem ipsum文本,然后聚焦文本输入。在控制台日志中,您将看到有一个DOMSelection对象。 它的anchorNode值为HTMLBodyElement,而它应具有Text之一。

在我尝试对选择对象进行字符串处理之前,我不知道为什么会发生这种情况:http://jsfiddle.net/fyG3H/1/

这会出现以下错误:

  

未捕获的TypeError:将循环结构转换为JSON

你知道如何阻止window.getSelection()引起的循环引用吗?

修改

新的演示也可以在其他浏览器中使用,但仍然提供错误的anchorNode:http://jsfiddle.net/fyG3H/5/

使用JSON.stringify:http://jsfiddle.net/fyG3H/6/

Firefox似乎返回空{}而不是抛出错误。

1 个答案:

答案 0 :(得分:2)

您需要在toString()上调用getSelection()。我updated your fiddle表现得像你期望的那样。

var selection;

$('p').bind('mouseup', function() {
    selection = window.getSelection().toString();
});

$('input').bind('focus', function() {
   this.value = selection;
   console.log(selection); 
});

See demo


修改

您没有获得正确的锚节点的原因是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); 
});

See demo