1

我正在尝试将一个突出显示的菜单悬停在具有以下属性的选择上:

  • 它应该在进行选择时出现。
  • It should disappear when the selection is destroyed.

除了一件事之外,所有这些都很好地工作:如果单击现有选择,则选择消失,悬停菜单也应该消失。但无论出于何种原因,它都没有。

当您在现有选择之外单击时,如果您单击该选择,则选择类型将更改为“插入符号”或“无”。所以我尝试根据类型设置菜单的可见性。问题是,虽然选择的类型似乎在您通过window.getSelection()获得的对象中发生了变化,但如果您尝试从对象中获取类型,它不会发生变化。

我把这个jsfiddle放在一起来说明这个问题。https://jsfiddle.net/nxo2d7ew/1/

var el = document.getElementById("simple-text");
    el.addEventListener("mouseup", placeDiv, false);


    function placeDiv(x_pos, y_pos) {
        var sel = window.getSelection();
        var position = sel.getRangeAt(0).getBoundingClientRect();
        // console.log(sel)
        // console.log(position)

        var highlighter = document.getElementById('highlighter').offsetWidth

        var d = document.getElementById('highlighter');
        d.style.left = position.left+position.width*0.5-highlighter*0.5 +'px';
        d.style.top = position.top-50 +'px';

        // console.log('sel.type: ' + sel.type)
        var test = window.getSelection()
        console.log(test) // returns an object with "type: None"
        console.log(test.type) //returns "Range"
        if (test.type !== 'Range') {
            d.style.visibility = 'hidden';
        }
        else {
            d.style.visibility = 'visible';
        }
        var sel = ''
    }

谢谢 :-)

4

1 回答 1

2

对选择的真正改变并没有真正发生在mouseup事件上。之后还有一个步骤会更改选择,所以当mouseup被触发时,选择还没有改变。您在控制台中看到的并不是mouseup事件中选择对象的确切状态。

我不确定是否有一种跨浏览器的方式可以访问真正的选择更改事件,selectionchangeChrome 中有一个事件,据说在 IE 中(但我无法测试它)。但在 Firefox 中它不可用。也就是说,type您用来测试它是否为空选择的属性似乎也不适用于 Firefox。但你可以使用isCollapsed.

您可能可以解决问题的一种方法(虽然不是最优雅的)是使用超时,您只需要几毫秒来更新选择,然后您的逻辑将起作用 - 使用 isCollapsed 使其在 Firefox 上工作。像这样:

setTimeout(function(){
    var test = window.getSelection()
    console.log(test) // returns an object with "type: None"
    console.log(test.type) //returns "Range"
    if (test.isCollapsed) {
        d.style.visibility = 'hidden';
    }
    else {
        d.style.visibility = 'visible';
    }}, 25);

https://jsfiddle.net/q1f4xfw9/6/

或者使用selectionchangeChrome 中的事件,您将隐藏条件移动到此处理程序中。像这样:

document.addEventListener("selectionchange", function () {
    var d = document.getElementById('highlighter');
    var test = window.getSelection()
    if (test.type !== 'Range') {
        d.style.visibility = 'hidden';
    }
});

https://jsfiddle.net/q1f4xfw9/5/

编辑:

还有另一种解决问题的方法,您可以使用removelAllRanges. 然后选择更改事件将在mouseup. 由您来决定功能上的微小变化是否符合您的要求。像这样:

el.addEventListener("mousedown", function(e){
    window.getSelection().removeAllRanges()
}, false);

https://jsfiddle.net/q1f4xfw9/8/

于 2015-07-19T18:25:51.853 回答