我正在尝试将一个突出显示的菜单放在一起,该菜单悬停在具有以下属性的选择上:
所有这一切都很有效,除了一件事:如果点击现有的选择,则选择消失,悬停菜单也应如此。但无论出于何种原因,它都没有。
当您单击现有选择的外部时,如果单击该选择,则选择类型将更改为“插入符号”或“无”。所以我尝试根据类型设置菜单的可见性。问题是虽然选择的类型似乎在你通过 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 = ''
}
谢谢: - )
答案 0 :(得分:2)
选择的真正变化并非在mouseup
事件中发生。之后还有另一个步骤会更改选择,因此当mouseup
被触发时,选择尚未更改。您在控制台中看到的不是mouseup
事件中选择对象的确切状态。
我不确定是否有跨浏览器方式可以访问真正的选择更改事件,Chrome中有selectionchange
个事件,据说可能在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/
或者在Chrome中使用selectionchange
事件,您可以将隐藏条件移动到此处理程序中。像这样:
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);