Javascript 选择的类型

Javascript 选择的类型,javascript,web-frontend,Javascript,Web Frontend,我正在尝试创建一个突出显示菜单,该菜单悬停在具有以下属性的选择上: 当进行选择时,它应该出现 当选择被销毁时,它应该消失 所有这些都很好地工作,除了一件事:如果单击现有的选择,则选择将消失,悬停菜单也将消失。但不管出于什么原因,它都没有 当您在现有选择之外单击时,如果您单击该选择,则选择类型将更改为“插入符号”或“无”。因此,我尝试根据类型设置菜单的可见性。问题是,尽管通过window.getSelection()获取的对象中的选择类型似乎发生了更改,但如果尝试从该对象获取类型,则不会发生更

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

  • 当进行选择时,它应该出现
  • 当选择被销毁时,它应该消失
所有这些都很好地工作,除了一件事:如果单击现有的选择,则选择将消失,悬停菜单也将消失。但不管出于什么原因,它都没有

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

我把这个jsfiddle放在一起来说明这个问题


谢谢:-)

mouseup
事件中,对选择的真正更改不会发生。之后还有另一个步骤更改选择,因此当触发
mouseup
时,选择尚未更改。您在控制台中看到的不是
mouseup
事件上选择对象的确切状态

我不确定是否有跨浏览器的方式来访问真正的选择更改事件,Chrome和IE中都有
selectionchange
事件(但我无法测试)。但在Firefox中它是不可用的。也就是说,您用来测试是否为空选择的
type
属性在Firefox上似乎也不起作用。但是您可以使用
isCollapsed

解决这个问题的一种方法,虽然不是最优雅的方法,就是使用一个超时,你只需要几毫秒的时间来更新选择,然后你的逻辑就会工作——使用iCollapsed使它在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);
document.addEventListener("selectionchange", function () {
    var d = document.getElementById('highlighter');
    var test = window.getSelection()
    if (test.type !== 'Range') {
        d.style.visibility = 'hidden';
    }
});
el.addEventListener("mousedown", function(e){
    window.getSelection().removeAllRanges()
}, false);

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

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);
document.addEventListener("selectionchange", function () {
    var d = document.getElementById('highlighter');
    var test = window.getSelection()
    if (test.type !== 'Range') {
        d.style.visibility = 'hidden';
    }
});
el.addEventListener("mousedown", function(e){
    window.getSelection().removeAllRanges()
}, false);

编辑:

还有另一种解决问题的方法,您可以使用
removelAllRanges
删除鼠标下的选择。然后,选择更改事件将在
mouseup
之前触发。这取决于您,看看功能上的微小变化是否符合您的要求。像这样:

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);
document.addEventListener("selectionchange", function () {
    var d = document.getElementById('highlighter');
    var test = window.getSelection()
    if (test.type !== 'Range') {
        d.style.visibility = 'hidden';
    }
});
el.addEventListener("mousedown", function(e){
    window.getSelection().removeAllRanges()
}, false);

多么详细的回答啊。万分感谢!:-)