How to detect mouseup on a scrollbar? (or “scrollE

2019-06-20 13:59发布

问题:

Anyone have any idea how to detect a mouseup event on a scrollbar? It works in FF, but not in Chrome or IE9.

I set up a quick demo: http://jsfiddle.net/2EE3P/

The overall idea is that I want to detect a scrollEnd event. There is obviously no such thing so I was going with a combination of mouseUp and timers, but mouseUp isn't firing in most browsers! The div contains a grid of items so when the user stops scrolling I want to adjust the scroll position to the nearest point that makes sense, e.g. the edge of the nearest cell. I don't, however, want to automatically adjust the position if they're in the middle of scrolling.

I'll also happily accept any answer that gives me the equivalent of scrollEnd

回答1:

found a solution that works without timers but only if you are scrolling the complete window.

switch(event.type){
            case 'mousedown':
                _btnDown = true;
                //THIS IS ONLY CAUSE MOUSEUP ON SCROLLBAR IS BUGGY
                $(document).bind('mousemove',function(event){
                    if(event.pageX < ($(window).width() - 30)){
                    //mouse is off scrollbar
                    $(this).unbind(event);
                    $(this).trigger('mouseup');
                }
               });
            break:
            case 'mouseup':
                //do whatever
                _btnDown = false;
            break;
}

pretty dirty .. but works.



回答2:

Using jquery there is a .scroll event you can use. Maybe use a global variable to keep track of when .scrollTop() (it returns the number of pixels there are above the screen) has stopped changing? Still creates a race condition, but it should work.



回答3:

Answering my own question so I can close it -- there is no good solution to this, so timers it is...



回答4:

I was handling the same problem. For me IE9 don't emit mouseup event for scrollbars. So, I checked and on IE9 when you "mouseup" it emits a mousemove event. So what I did was monitor scrolling, and monitor mousemove. When user is scrolling, and a mousemove event happens, then I understand it as a mouseup event. Only do this check for IE9, cheching the proto property availability. The code will also run for Opera, but Opera has the mouseup and then no problem for me when both events happens. Here is the code, I write AngularJS + ZEPTO code, so get the idea and write your own code, don't expect to copy&paste this code directly:

        // Global for scrolling timeout
        var q;

        // Action to do when stop scrolling
        var updatePosition = function() {
            // Put the code for stop scrolling action here  
        }

        $(document).on('mousemove', function(e) {

            console.log('MOUSE MOVE ' + e.pageX + ',' + e.pageY);

            if(!('__proto__' in {})) {
                // for IE only, because it dont have mouseup
                if($scope.scrolling && $scope.mouse_down) {

                    console.log('FAKE MOUSE UP FOR IE');

                    // Only simulate the mouseup if mouse is down and scrolling
                    $scope.scrolling = false;
                    $scope.mouse_down = false;
                    // Update Position is the action i do when mouseup, stop scrolling
                    updatePostition();
                }   
            }
        });


        $(window).on('scroll', function(){

            console.log('SCROLLING');

            // Set the scrolling flag to true
            if(!$scope.scrolling)  {
                $scope.scrolling = true;
            }

            // Stop if for some reason you disabled the scrolling monitor
            if(!$scope.monitor_scrolling) return;

            // Monitor scroll with a timeout
            // Update Position is the action i do when stop scrolling
            var speed = 200;
            $timeout.cancel(q);     
            q = $timeout(updatePostition, speed);

        });


        $(window).on('mousedown', function() {
            console.log('MOUSE DOWN');
            // Stop monitor scrolling
            $scope.monitor_scroll = false;
            // Set that user is mouse down
            $scope.mouse_down = true;
        });

        $(window).on('mouseup', function() {
            console.log('MOUSE UP');
            // Enable scrolling monitor
            $scope.monitor_scroll = true;
            // Change mouse state 
            $scope.mouse_down = false;
            // Action when stop scrolling
            updatePostition();
        });

Was fighting with this problem. My system also runs for mobile and I have a large horizontal scrolling, that always when user stop scrolling, it need to find the actual item the used is viewing and centralize this item on screen (updatePosition). Hope this can help you. This is to support IE9+, FF, Chorme and Opera, I'm not worrying with old browsers.

Best Regards



回答5:

Is very late but.... there are solution with any scroll in any part of your page.... I do it with the next code...

onScroll = function(){
  $(window).unbind("mouseup").one('mouseup',function(e) {
    alert("scroll up")
  });
}; 
$(window).bind("scroll", onScroll);
body{
  height:5000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>