Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove highlighted text on Framework7 mobile web app when touch/tap on other elements?

For some reason, when I highlight text in the mobile web version of a Framework7 app and touch on other places I expect the highlight to be gone... it's being retained. However, on desktop web, when I highlight text and click somewhere else, the highlight is gone.

How can I make the mobile web behave like the desktop web when highlighting a text?

I tried to preventDefault on touchstart hoping it would prevent the default retention or events... but it could be something else I'm missing/not getting because with or without preventDefault it's still the same issue.

$('.content').on('touchstart', function(e) {
   e.preventDefault();
});

Thanks a lot!

like image 743
Woppi Avatar asked Oct 29 '22 19:10

Woppi


2 Answers

To clear all selections upon touchstart:

$(window).on('touchstart', function(){
    window.getSelection().removeAllRanges()
})

Edit: To only clear the selection if tapped outside of the current highlight, check to make sure the touch position doesn't fall in any selection client rects:

$(window).on('touchstart', function(e){
    var selection = window.getSelection();
    var tappedOnSelection = selection.rangeCount && Array.from(selection.getRangeAt(0).getClientRects()).some(function(rect){
        return e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top  && e.clientY <= rect.bottom;
    });
    if(!tappedOnSelection){
        selection.removeAllRanges();
    }
})
$(window).on('touchend', function(e){
    e.preventDefault();
})
like image 152
darrylyeo Avatar answered Nov 15 '22 06:11

darrylyeo


Had to modify the best answer I accepted above since the project I'm on is using ES5 (Array.from is not working) and also I had to replace e.clientX with e.touches[0].clientX, sames goes for e.clientY.

This is what worked for me.

$(window).on('touchstart', function(e){
    var selection = window.getSelection();
    var tappedOnSelection = false;

    if(selection.rangeCount) {
        var args = [].slice.call(selection.getRangeAt(0).getClientRects());

        tappedOnSelection = args.some(function(rect){
            var top = e.touches[0].clientY;
            var left = e.touches[0].clientX;

            return left >= rect.left && left <= rect.right && top >= rect.top  && top <= rect.bottom;
        });
    }


    if(!tappedOnSelection){
        selection.removeAllRanges();
    }
});

$(window).on('touchend', function(e){
    e.preventDefault();
});

NOTE: Tested on an android device

like image 20
Woppi Avatar answered Nov 15 '22 05:11

Woppi