【问题标题】:Jquery: <a> link click preventDefault() not working?Jquery:<a> 链接单击 preventDefault() 不起作用?
【发布时间】:2016-01-02 18:39:09
【问题描述】:

如果在移动设备中滚动时意外触摸,我正在尝试防止触发链接点击?我以前从未尝试过这样的事情,并且无法使其正常工作。我暂时在桌面上测试这个。 我的按钮结构类似于:

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

我正在尝试使用 preventDefault() 函数来覆盖默认单击操作并检查页面是否正在滚动,或者在允许其工作之前单击是意外的。检查的逻辑似乎有效,但是无论我做什么,链接都会在点击时导航。我认为这与传播到子 div 的链接行为有关,但不确定。

下面是我的脚本,问题出在最后 $('a').click();函数。

更新:

如果有人知道怎么做,我仍然需要一个更好的方法来使用 $('a') 选择器。一种 hack 但是,如果我将选择器更改为 $('a>div') 并将 'targetLink' 更改为 $(this).parent().attr('href') 它似乎可以工作,有没有办法只使用 $('a') 来做到这一点,因为我的一些按钮有更多的孩子。

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

【问题讨论】:

  • 尝试在您的 .click 函数上返回 false。即返回false;
  • return false 仍然不会阻止它。如果我将选择器更改为 $('a>div') ,它会有点工作,这只会阻止链接工作。另外,我更喜欢只使用 $('a') 选择器,因为我的一些按钮可能有更多的子按钮。
  • 如果在台式机上进行测试,您是否考虑了移动触控内置的延迟?
  • 如果我将选择器更改为 $('a>div') 并将 'targetLink' 更改为 $(this).parent().attr('href') 它似乎工作,是有一种方法可以使用 $('a') 来做到这一点,只是因为我的一些按钮有更多的孩子。
  • 您可以使用它来获取没有任何子节点的“a”标签的子节点(是叶节点 - 最里面的子节点。)... $('a').children(':not(:has(*))') 这个有问题, 尽管。如果您的子层次结构不是严格线性的,那么每个链接可能有多个叶节点,并且您将在同一个“a”标签下有重复的事件。

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


【解决方案1】:

您可以使用return falsee.preventDefault

但是当您单击该链接时,为什么要添加 window.location.href = targetLink;??这会将用户重定向到给定的位置。与链接相同

试试我下面的代码,我已经删除了它。

$(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>

【讨论】:

  • window.location.href = targetLink;如果用户不滚动页面,则允许链接正常运行。 (即点击不是偶然的)
【解决方案2】:

我会建议另一种方法并使用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...
    }
});

文档/参考: scrollstart event scrollstop event tap event vclick event .click()

【讨论】:

    【解决方案3】:

    在您的$'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
        });
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多