Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery: <a> link click preventDefault() not working?

I'm trying to prevent a link click from firing if accidentally touched while scrolling in mobile? I have never tried something like this before and am having trouble getting it to work right. I am testing this on a desktop for the time being. My buttons are structured similar to:

<a href="http://www.google.com">
    <div style="width:100%;height:80px;margin-bottom:50px;">test</div>
</a>

I am trying to use the preventDefault() function to override default click actions and check if a the page is being scrolled, or it the click was accidental before allowing it to work. The logic to check seems to work, however the links navigate on click no matter what i do. I assume this has something to do with the links behaviour being propogated to the child div, but am not sure.

Below is my script, the problem is in the last $('a').click(); function.

UPDATE:

I still need a better way to do it using just the $('a') selector if anyone knows how. Kind of a hack but, if i change the selector to $('a>div') and change the 'targetLink' to $(this).parent().attr('href') it seems to work, Is there a way to do this using $('a') only because some of my buttons have more children.

//Mobile accidental scroll click fix:---
//- prevent clicked link from executing if user scrolls after mousedown, until next mousedown.
//- prevent clicked link from executing if user is still scrolling and mouse is down(for slow scrolls)

$(document).ready(function(){
    var self = this,
        scrolling = false,
        mouseDown = false,
        scrollAfterPress = false;
        scrollDelay = 1500,
        linkConditionCheckDelay = 700;

        $(window).scroll(function() {
            self.scrolling = true;
            console.log('scrolling:' + self.scrolling);
            clearTimeout( $.data( this, "scrollCheck" ) );
            $.data( this, "scrollCheck", setTimeout(function() {
                self.scrolling = false;
                console.log('scrolling:' + self.scrolling);
            }, scrollDelay) );

        });

        $(document).mousedown(function(){
                self.scrollAfterPress = false;
                int00 = setInterval(function() { checkScrollAfterPress(); }, 100);//execute every 100ms (while mouse is down)
                self.mouseDown = true;
                console.log('mousedown:'+ self.mouseDown);
            }).mouseup(function(){
                clearInterval(int00);
                self.mouseDown = false; 
                console.log('mousedown:'+ self.mouseDown);
            });

        function checkScrollAfterPress(){
            if(self.scroll === true){
                self.scrollAfterPress = true;
            }
        }

        $('a').click(function(e){
             //prevent default click event behaviour
            var targetLink = $(this).attr('href');
            console.log('clicked on:'+targetLink);
            setTimeout(function() {
                    if(!self.scrolling && !self.mouseDown && !self.scrollAfterPress && targetLink !== undefined){
                        window.location.href = targetLink;
                    }
                }, linkConditionCheckDelay); //add small delay to prevent immeditiate responses between mouse up and start of scroll.
            e.stopPropagation();
            e.preventDefault();
        });
});
like image 626
L457 Avatar asked Dec 04 '25 18:12

L457


1 Answers

You can use return false or e.preventDefault

But when you click on that link why your adding window.location.href = targetLink;?? which will redirect the user to the given location.Same as link

Try my code below i have removed it.

$(document).ready(function(){
    var self = this,
        scrolling = false,
        mouseDown = false,
        scrollAfterPress = false;
        scrollDelay = 1500,
        linkConditionCheckDelay = 700;

        $(window).scroll(function() {
            self.scrolling = true;
            console.log('scrolling:' + self.scrolling);
            clearTimeout( $.data( this, "scrollCheck" ) );
            $.data( this, "scrollCheck", setTimeout(function() {
                self.scrolling = false;
                console.log('scrolling:' + self.scrolling);
            }, scrollDelay) );

        });

        $(document).mousedown(function(){
                self.scrollAfterPress = false;
                int00 = setInterval(function() { checkScrollAfterPress(); }, 100);//execute every 100ms (while mouse is down)
                self.mouseDown = true;
                console.log('mousedown:'+ self.mouseDown);
            }).mouseup(function(){
                clearInterval(int00);
                self.mouseDown = false; 
                console.log('mousedown:'+ self.mouseDown);
            });

        function checkScrollAfterPress(){
            if(self.scroll === true){
                self.scrollAfterPress = true;
            }
        }

        $('a').click(function(e){
             //prevent default click event behaviour
            var targetLink = $(this).attr('href');
            console.log('clicked on:'+targetLink);
            setTimeout(function() {
                    if(!self.scrolling && !self.mouseDown && !self.scrollAfterPress && targetLink !== undefined){
                        //window.location.href = targetLink;
                    }
                }, linkConditionCheckDelay); //add small delay to prevent immeditiate responses between mouse up and start of scroll.
            return false;
        });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="http://www.google.com">
  <div style="width:100%;height:80px;margin-bottom:50px;">test</div>
</a>
like image 94
jlocker Avatar answered Dec 06 '25 09:12

jlocker