是否可以一次为元素的所有事件分配防止默认值?

时间:2012-08-31 10:59:50

标签: javascript jquery events

  

可能重复:
  jQuery - How can I bind all events on a DOM element?

想象一下,如果我们想让一些元素完全不可用。

我们当然可以为click事件绑定一个防止默认值,如下所示:

$('form *').bind('click', function(event) {
    event.preventDefault();
});

但这仅仅是一个事件,还有更多,例如悬停,焦点,选择启动等等。

我们可以在一行中指定它们,例如'click focus hover dblclick blur selectstart',但这没有多大意义,也不容易维护。

那么,是否可以绑定事件监听器而不区分事件的类型?也许一些原生的JavaScript听众允许它?

6 个答案:

答案 0 :(得分:3)

没有这种可能性,因为并非所有元素都支持相同的事件,并且并非所有事件都以相同的方式运行。您必须明确提供事件列表,无论是静态定义还是dynamically by a script都会发出事件名称。

即使我链接到创建事件名称数组的脚本,但这些只在一个元素上生成。当然,您应该使用更复杂,更慢的脚本生成此脚本,该脚本枚举所有相关元素并添加缺少的事件。使用Javascript对象作为关联数组,以便更快地搜索是否添加了特定事件。

更好的建议

您正在尝试做的事情可能是一个高度过度设计的解决方案。当我创建一个可以禁用某些元素(无论是链接,按钮还是其他任何元素)的演示可点击界面时,我宁愿通过定义一个禁用有问题元素的CSS类来实现它,并且有一个简单的脚本可以在之后禁用它。 / p>

您还可以通过提供您要在特定元素上禁用哪些事件(默认为click事件)来进一步利用此功能。

<!-- no events; use defaults -->
<a href="#" class="disable">No-follow link</a>
<button class="disable">Nothing happens</button>
<!-- provide events -->
<a href="#" class="disable" data-events="click blur">No-follow link</a>
<form class="disable" data-events="submit">...</form>

脚本

$(function() {

    var disable = function(evt) {
        evt.preventDefault();
        console.log("Prevented on " + evt.target.tagName);
    };

    $(".disable").each(function() {
        var ctx = $(this);
        ctx.bind(ctx.data("events") || "click", disable);
    });
});

使用智能默认值

上部示例定义了一个单一事件默认值。 click事件。这很好,适用于大多数情况,但不是全部。例如,form元素必须始终定义应禁用的提交事件。所以。然后智能默认。我们还应该考虑这样一个事实:需要抑制的列表事件通常很短。如果我们使用默认值覆盖大多数情况,我们对那些实际上与默认值有偏差的元素只有很小的开销

$(function() {

    // click is still default event
    // this object defines per element events that aren't just click
    var extraDefaults = {
        form: "submit"
    };

    var disable = function(evt) {
        evt.preventDefault();
        console.log("Prevented on " + evt.target.tagName);
    };

    $(".disable").each(function() {
        var ctx = $(this);
        ctx.bind(
            // use inline-defined events
            ctx.data("events") ||
            // use extra defaults if present
            extraDefaults[this.tagName.toLower()] ||
            // just use default click event
            "click",
            disable);
    });
});

答案 1 :(得分:1)

您可以绑定大多数jQuery事件,如下所示:

$("#elementID").on(Object.keys(jQuery.event.fixHooks).join(" "), function(e) { 
    e.preventDefault(); 
});

这将防止以下事件发生故障:

  

单击dblclick mousedown mouseup mousemove mouseover mouseout   mouseenter mouseleave keydown keypress keyup contextmenu

FIDDLE

答案 2 :(得分:1)

在考虑了所有选项之后,对于所有这些事件来说,它仍然看起来不方便。因为它还必须单独绑定每个事件的处理程序,所以脚本也会达到性能。

我将坚持使用更简单的解决方案,只需在顶部放置一个带透明bg的div来覆盖我们的元素。

$('form').css('position','relative').prepend($('<div class="mask" style="position:absolute;z-index:9000;height:100%;width:100%;background-image:url(1px_transparent.png);"></div>'));

这将自动填充元素的整个区域,或者,我们可以使用半透明图片,因此用户也会理解这是锁定元素,并且不会引起混淆。

要解锁,我们只需从元素中删除.mask div。

修改

新小提琴:http://jsfiddle.net/YAdXk/8/

实际上,我们可以通过将tabindex属性设置为-1

来停用标签
.find('input,textarea,select').attr('tabindex','-1');

更新的小提琴也可以防止标签。

<强> EDIT2

或者,我们可以扩展jQuery以在任何元素上使用我们的自定义lock()unlock()函数。

查看最后一个小提琴:http://jsfiddle.net/YAdXk/13/

(function($) {
$.fn.lock= function() {
    return this.each(function() {
        $(this).css('position','relative').prepend($('<div class="mask" style="position:absolute;z-index:9000;height:100%;width:100%;background-image:url('+transparent_picture+');"></div>')).find('input,textarea,select').attr('tabindex','-1');
    });
};   

$.fn.unlock= function() {
    return this.each(function() {
        $(this).find('*').removeAttr('tabindex').filter('.mask').remove();
   });
};

})( jQuery )

答案 3 :(得分:0)

var all_events = "click blur focus mouse"; //etc...

$('form *').bind(all_events, function(event) {
        event.preventDefault();
});

现在更容易维护;)

答案 4 :(得分:0)

jQuery定义了所有快捷方式事件类型here,因此您可以使用该字符串存储所有事件以供重用:

var events = "blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu";

$('button').bind(events, function() {
    // hey
});

答案 5 :(得分:0)

是的,可以同时捕获一种类型的所有事件!但是您需要明确指定所有事件类型。

"form *"的代码示例效率低下,并且不会捕获代码执行后添加的元素上的事件。

由于javascript事件的冒泡效应,您可以在最多父元素上分配catch all事件处理程序,eigther $("form")$("body"),并将preventDefault()添加到该元素。 / p>

示例代码:

$("a").on("click", function() {
    $("body").append("<p>Clicked...</p>");
});
$("body").on("click", function(e) {
  e.preventDefault();
});

使用:

<div>
    <p><a href="#" target="_blank">Click on me</a></p>
</div>​

在父元素上捕获所有事件的概念通常被称为事件委派