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

时间:2015-10-06 00:26:51

标签: javascript jquery html jquery-mobile responsive-design

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();
        });
});

4 个答案:

答案 0 :(得分:1)

您可以使用return falsee.preventDefault

但是当你点击该链接时为什么要添加window.location.href = targetLink;?这将把用户重定向到给定的位置。作为链接

尝试我的代码,我已删除它。

&#13;
&#13;
$(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;
        });
});
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

$'a'.click(function(e){...}部分return false;中使用,以防止出现默认行为。

在你的情况下:

$('a').click(function(e){
        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); 
        return false;//Stops default behavior
    });

答案 2 :(得分:0)

也许有一些我缺少的东西,但我不明白为什么你的代码不能像下面那样简单:

$(document).ready(function () {
    var is_scrolling = false;
    var timeout = null;

    $(window).scroll(function () {
        is_scrolling = true;
        if (timeout) {
            clearTimeout(timeout);   
        }
        timeout = setTimeout(function () {
            is_scrolling = false;
        }, 1500);
    });

    $('a').click(function (e){
        if (is_scrolling) {
            e.preventDefault();
        }
    });
});

答案 3 :(得分:0)

我会建议另一种方法并使用jQuery Mobile Events。这样的事情:
*未经测试,但是想法是

// set global var 'locked'
var locked = false;

// locked var true while scrolling
jQuery(document).on('scrollstart', function() { locked = true; });

// locked var back to false when finish
jQuery(document).on('scrollstop', function() { locked = false; });

// bind 'tap' & 'click' events to 'a' tag
jQuery(document).on('tap click', 'a', function(event) {
    // But before proceed, check locked var
    if (locked) {
        event.preventDefault;
        return false;
    } else {
        // ok, proceed with the click and further events...
    }
});

文档/ REF: scrollstart event scrollstop event tap event vclick event .click() 功能