如何将处理程序绑定到窗口上的选择更改?

时间:2012-01-24 17:44:31

标签: javascript javascript-events selection

基本上我需要知道window.getSelection()何时发生了变化,并将处理程序绑定到此事件。想法?

OBS:请注意,我不打算在INPUT或TEXTAREA上绑定选择更改。我正在谈论窗口中的任何选择。

4 个答案:

答案 0 :(得分:17)

没有跨浏览器方式来检测选择的更改。 IE(我认为自5.5版本)和WebKit / Blink浏览器(例如,过去几年的Chrome,Safari和Opera版本)支持selectionchange上的document事件你想要的。

Firefox和pre-Blink Opera没有这样的事件,您所能做的就是检测通过键盘和鼠标事件进行的选择更改,这是不能令人满意的(无法从上下文或编辑菜单中检测到“全选”,示例),或者只是轮询Selection返回的window.getSelection()对象(检查选择的anchorNodeanchorOffsetfocusNodefocusOffset属性以前的值应该足够了。)

答案 1 :(得分:9)

没有跨浏览器事件。

但是,确实存在一个名为selectionchange的事件,该事件触发文档中选择的每个更改,但它仅在IE和最近的WebKit(Chrome / Safari)中受支持,因此没有Firefox / Opera

您可以使用selectionchange这样的事件:

$(document).on('selectionchange', function(e) {
    console.log('selectionchange', e.originalEvent); 
});

jsfiddle example

答案 2 :(得分:0)

我认为selectionchange事件过于贪婪,您想观看鼠标事件。 处理程序是简单的部分。 返回所选节点是重要的部分! 适应Tim Down's answer here,这是我的想法:

    $(document).on('mouseup', function(e) { 
    
            //cool! jQuery object containing all nodes (elements) that were just selected
            var $selNodes = $().getSelectedNodes();
            if ($selNodes.length)
                     alert('user selected something');
            
            //so now I can do work on just the elements I am interested in that were selected
            if($selNodes.filter('.justTheClassIwant').length)
                alert('user selected the elements I want to watch');
        });
    
    jQuery.fn.extend({
    getSelectedNodes: function() {
        if (window.getSelection) {
            var sel = window.getSelection();
            if (!sel.isCollapsed) {
                var range = sel.getRangeAt(0);
                var node = range.startContainer;
                var endNode = range.endContainer;

                // Special case for a range that is contained within a single node
                if (node == endNode) {
                    return [node];
                }

                // Iterate nodes until we hit the end container
                var rangeNodes = [];
                while (node && node != endNode) {
                    if (node.hasChildNodes()) {
                        node = node.firstChild;
                    } 
                    else {
                        while (node && !node.nextSibling) {
                            node = node.parentNode;
                        }
                        node = node.nextSibling;
                    }
    
                    rangeNodes.push(node);
                }

                // Add partially selected nodes at the start of the range
                node = range.startContainer;
                while (node && node != range.commonAncestorContainer) {
                    rangeNodes.unshift(node);
                    node = node.parentNode;
                }

                return jQuery(rangeNodes);
            }
        }
        return jQuery([]);
    }
});

答案 3 :(得分:-1)

我认为这会有所帮助

function foo() {
   var selObj = window.getSelection(); 
   alert(selObj);
   var selRange = selObj.getRangeAt(0);
   // work something with selObj
}