简体   繁体   中英

Type of selections

I am trying to but together a highlighting menu that hovers over a selection with the following properties:

  • It should appear when a selection is made.
  • It should disappear when the selection is destroyed.

All that works quite nicely except for one thing: If an existing selection gets clicked the selection disappears and so should the hovering menu. But for whatever reason it doesn't.

When you click outside of an existing selection the selection type changes to 'caret' or to 'none' if you click on that very selection. So I tried setting the visibility of the menu according to the type. The problem is though that although the type of the selection appears to change in the object you get by window.getSelection() , it does not if you try to get the type from the object.

I put this jsfiddle together to illustrate the problem. 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 = ''
    }

Thank you :-)

The real change to selection doesn't really happen on mouseup event. There is another step afterwards that changes the selection, so when mouseup is fired, the selection hasn't changed yet. What you see in your console is not the exact state of the selection object on the mouseup event.

I'm not sure there's a cross-browser way to have access to the real selection change event, there's a selectionchange event in Chrome, and supposedly in IE (but I couldn't test it). But in Firefox it's not available. That said, the type property you're using to test if it's an empty selection doesn't seem to work on Firefox either. But you could use isCollapsed .

One way you can maybe solve the problem, though not the most elegant, is using a timeout, you only need a few milliseconds for the selection to update, then your logic will work - using isCollapsed to make it work on Firefox. Like this:

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/

Or with selectionchange event in Chrome, you move the hide condition into this handler. Like this:

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/

EDIT:

There's another way to solve the problem, you could remove selection on mouse down using removelAllRanges . Then the selection change event would be triggered before the mouseup . Up to you to see if that little change in functionality works with what you want. Like this:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM