【问题标题】:event.preventDefault() in a href="#" doesn't prevent jumping to top of page in IE and Firefoxhref="#" 中的 event.preventDefault() 不会阻止在 IE 和 Firefox 中跳转到页面顶部
【发布时间】:2013-02-19 23:18:23
【问题描述】:

HTML:

<a href="#" class="button" onclick="sendDetails(\'Edu\')">

JS:

function sendDetails(type) {
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
    }
    names = $("#names" + type).val();
    Input = encodeURIComponent($("#Input" + type).val());
    ....

链接跳转到页面顶部。我尝试使用event.preventDefault() 停止跳转到页面顶部。但是,它仅适用于 Chrome,不适用于 IE 和 Firefox。我该如何解决?

【问题讨论】:

  • 如何在sendDetails(type) 中获得event
  • 尝试在函数末尾添加return false ...
  • 你从哪里打电话给sendDetails
  • event 来自哪里?你怎么打电话给sendDetails? jQuery提供统一的事件接口,可以放心调用event.preventDefault

标签: javascript jquery firefox


【解决方案1】:

你可以使用javascript:;而不是“#”,这样就不会跳转,请确保返回false以禁用链接行为

<a href="javascript:;" onclick="something();return false;">link</a>

【讨论】:

    【解决方案2】:

    您不能使用window.event 来控制事件。尝试像这样标准化它:

    function sendDetails(e, type) {
        var evt = window.event || e;
        if (evt.preventDefault) {
            evt.preventDefault();
        } else {
            evt.returnValue = false;
        }
        // ...
    }
    

    您的 HTML 必须是:

    <a href="#" class="button" onclick="sendDetails(event, 'Edu');">ASDF</a>
    

    另一种非 jQuery 解决方案是将您的 HTML 修改为:

    <a href="#" class="button" onclick="sendDetails(event, 'Edu'); return false;">ASDF</a>
    

    在这种情况下,您不必在 sendDetails 函数中使用任何处理 event 的东西。 return false; 将自动阻止默认行为。但请注意 - 如果您的 sendDetails 函数中出现任何异常,return false; 将不会执行并允许默认行为。这就是我喜欢使用preventDefault 的原因 - 您可以在函数中立即调用它以立即停止行为,然后执行您需要的操作。

    同时,如果你使用 jQuery,尝试像这样绑定点击事件:

    $(document).ready(function () {
        $(".button").on("click", function (e) {
            e.preventDefault();
            // Your sendDetails code (without the "event" stuff)
            // OR call sendDetails (and remove the "event" stuff in the sendDetails function)
        });
    });
    

    在这种情况下,您的 HTML 将是:

    <a href="#" class="button">ASDF</a>
    

    虽然使用我提供的.button 选择器而不是使用我提供的.button 选择器来定位适用于此的特定元素会容易得多。我确信“按钮”类不仅仅适用于这些目标&lt;a&gt;,但也许我错了:)

    在这种情况下使用 jQuery 很好,因为它已经标准化了 event 对象,您可以使用我在 click 回调中包含的 e 变量。我确信它不仅仅是window.event || e,所以我更喜欢/建议使用 jQuery 来处理事件。

    【讨论】:

    • 不错的回应,但我认为应该养成使用
    • @gaurav 好吧,阻止默认行为或返回 false 将阻止 "#" 实际发生。无论如何,这是一场大辩论(stackoverflow.com/questions/134845/…)。这取决于。我宁愿将"#" 用作href,因为如果确实发生了不好的事情(它不应该发生),那么我可以直观地看到它......这意味着代码有问题。如果您正确地处理事件,那么两者都应该没问题。另外,我不确定如果禁用 Javascript 并且您使用 void 东西会发生什么
    • 啊,明白了 :) 你写的东西不重要,重要的是你如何以干净的方式处理它
    • @gaurav:更好:使用链接达到预期目的,即链接到其他文档/文档部分。使用按钮进行用户交互。无论如何,您都可以根据需要设置任何样式。
    • @FelixKling 哈哈好点,我同意,虽然我有时会因为使用链接作为按钮而感到内疚......
    【解决方案3】:

    您已经在使用 jQuery,只需使用 jQuery 方式即可。 jQuery 包装了事件对象并提供了一个规范化的事件对象,因此您可以使用标准的preventDefault,您不需要根据浏览器支持的情况进行分叉。

    <button class="senddetail" data-type="edu">Education</button>
    <button class="senddetail" data-type="com">Commercial</button>
    <!-- why not just use a button instead of styling a link to look
         like a button? If it does need to be a link for some reason
         just change this back to an anchor tag, but keep the data
         attributes and change the class to "button senddetail" -->
    
    <script>
        function sendDetails(type) {
    
        // Assuming names and input are not globals you need to declare
        // them or they will become implicit globals which can cause
        // all sorts of strange errors if other code uses them too
        var names, input;
    
        names = $("#names" + type).val();
    
        // you should only use capitalized variables for
        // Constructor functions, it's a convention in JS
        input = encodeURIComponent($("#Input" + type).val());
    
        //....
        }
    
      // just calling $ with a function inside of the invocation
      // is the same as using $(document).ready
      $(function () {
        // instead of using onClick, use jQuery to attach the
        // click event in a less intrusive way
        $('.senddetail').on('click', function (event) {
          // no matter what browser this runs in jQuery will
          // provide us a standard .preventDefault to use
          event.preventDefault();
          // jQuery sets 'this' to the DOM element that the event fired on,
          // wrapping it in another jQuery object will allow us to use the
          // .data method to grab the HMLM5 data attribute
          var type = $(this).data('type');
          sendDetails(type);
        });
      });
    </script>
    

    【讨论】:

    • on("click", function(){...} 更好,因为 jQuery 使用事件委托并由他们建议
    • @FibreFoX 不正确。 .click(function () {});.on("click", function () {}); 是一样的——它只是一个捷径。实际的事件委托是通过使用on 来实现的,但是有3 个参数……而且它并不真正适用于这种情况。 api.jquery.com/on
    • @Ian 是的,它是一个快捷方式,但想象一下将您的方法导出到插件,而不是您可以将“命名空间”放入该事件名称(“click.yourNameSpace”)。激活/停用变得更加容易,顺便说一句:有 2 个参数(打开)或只有一个(点击)实际上并没有那么多代码
    • @FibreFoX 我并不反对他们应该使用on 而不是click。我不同意你关于 on 有两个参数使用事件委托的事实......它没有; on 带有三个参数。您认为on 是“更好”的。对于每种情况,这真的不重要。双方都有争论。
    • @FibreFoX 事件委托很棒,但并非在所有情况下都需要。例如,问题中的示例显示了一个“按钮”,您不需要为此委托。我确实怀疑实际的实现有多个按钮,在这种情况下委托可能是合适的。然而,提供的代码没有提供足够的上下文来知道将委托附加到哪里,将其附加到主体 à la .live() 会提供比仅附加几个单独的事件处理程序更差的性能。
    猜你喜欢
    • 2014-07-07
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    相关资源
    最近更新 更多