Làm cách nào để hủy liên kết người nghe đang gọi event.preventDefault () (sử dụng jQuery)?


128

jquery chuyển đổi các cuộc gọi notifyDefault () theo mặc định, vì vậy các mặc định không hoạt động. bạn không thể nhấp vào một hộp kiểm, bạn không thể nhấp vào một liên kết, v.v.

Có thể khôi phục trình xử lý mặc định?


Bạn có thể cho một số mã ví dụ?
Jojo

4
Câu hỏi trong tiêu đề là một câu hỏi tuyệt vời! Thật tệ là câu hỏi thực tế không phải là ... Tôi đã hy vọng tìm thấy ở đây, câu trả lời cho việc làm thế nào (nếu có thể) chúng ta có thể 'bỏ đặt' hiệu quả của preventDefaultnó sau khi nó được gọi. Hiện tại câu hỏi này thực sự là 'làm cách nào để hủy liên kết người nghe sự kiện với jQuery?'.
Stijn de Witt

Câu trả lời:


80

Trong trường hợp của tôi:

$('#some_link').click(function(event){
    event.preventDefault();
});

$('#some_link').unbind('click'); làm việc như là phương pháp duy nhất để khôi phục hành động mặc định.

Như đã thấy ở đây: https://stackoverflow.com/a/1673570/211514


2
Nếu phần tử này có trình xử lý nhấp chuột khác, bạn hủy liên kết tất cả các sự kiện được đính kèm không chỉ ngăn chặn trình xử lý ...
Aure77

56

Nó khá đơn giản

Hãy cho rằng bạn làm một cái gì đó như

document.ontouchmove = function(e){ e.preventDefault(); }

Bây giờ để hoàn nguyên nó về tình huống ban đầu, hãy làm như sau ...

document.ontouchmove = function(e){ return true; }

Từ trang web này .


Giải pháp này không hoạt động sau $ ('# a_link'). Click (function (e) {e.preventDefault ();}); sử dụng chức năng unbind.
Denis Makarskiy

2
Liên kết bạn cung cấp bị hỏng.
Xếp chồng

16

Không thể khôi phục preventDefault()nhưng điều bạn có thể làm là lừa nó :)

<div id="t1">Toggle</div>
<script type="javascript">
$('#t1').click(function (e){
   if($(this).hasClass('prevented')){
       e.preventDefault();
       $(this).removeClass('prevented');
   }else{
       $(this).addClass('prevented');
   }
});
</script>

Nếu bạn muốn tiến thêm một bước, bạn thậm chí có thể sử dụng nút kích hoạt để kích hoạt một sự kiện.


Tôi khá chắc chắn rằng nó - tôi đã làm điều này trên một thiết kế gần đây. Lúc đầu, chỉ cần nhấp vào nút, tôi đã ngăn cuộn trong iphone bằng cách thêm e.preventDefault vào sự kiện touchmove và sau khi hoạt ảnh xong tôi trở lại đúng và nó hoạt động như một bùa mê.
foxybagga

11
function DoPrevent(e) {
  e.preventDefault();
  e.stopPropagation();
}

// Bind:
$(element).on('click', DoPrevent);

// UnBind:
$(element).off('click', DoPrevent);

Cách nó hoạt động với tôi là: $ (tài liệu) .off ('touchmove'); $ (tài liệu) .on ('touchmove', function () {return true;});
rogervila

9

trong một số trường hợp * ban đầu bạn có thể return falsethay vì e.preventDefault()sau đó khi bạn muốn khôi phục lại mặc định return true.

* Có nghĩa là khi bạn không bận tâm đến sự kiện sủi bọt và bạn không sử dụng e.stopPropagation()cùng vớie.preventDefault()

Cũng thấy câu hỏi tương tự (cũng trong stack Overflow)

hoặc trong trường hợp hộp kiểm, bạn có thể có một cái gì đó như:

$(element).toggle(function(){
  $(":checkbox").attr('disabled', true);
  },
function(){
   $(":checkbox").removeAttr('disabled');
}) 

9

Bạn có thể khôi phục hành động mặc định (nếu đó là theo dõi HREF) bằng cách thực hiện việc này:

window.location = $(this).attr('href');


2
ý tưởng là đúng nhưng mã ra khỏi hộp không hoạt động với tôi (trừ khi nó chỉ là một thay đổi cú pháp trong jquery) tôi đã sử dụng: window.location = $ (this) .attr ('href');
Modika

3

nếu đó là một liên kết thì $(this).unbind("click");sẽ kích hoạt lại nhấp vào liên kết và hành vi mặc định sẽ được khôi phục.

Tôi đã tạo một fiddle JS demo để chứng minh cách thức hoạt động của nó:

Đây là mã của fiddle JS:

HTML:

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<a href="http://jquery.com">Default click action is prevented, only on the third click it would be enabled</a>
<div id="log"></div>

Javascript:

<script>
var counter = 1;
$(document).ready(function(){
$( "a" ).click(function( event ) {
  event.preventDefault();

  $( "<div>" )
    .append( "default " + event.type + " prevented "+counter )
    .appendTo( "#log" );

    if(counter == 2)
    {
        $( "<div>" )
    .append( "now enable click" )
    .appendTo( "#log" );

    $(this).unbind("click");//-----this code unbinds the e.preventDefault() and restores the link clicking behavior
    }
    else
    {
        $( "<div>" )
    .append( "still disabled" )
    .appendTo( "#log" );
    }
    counter++;
});
});
</script>

2

Kiểm tra mã này, tôi nghĩ giải quyết vấn đề của bạn:

event.stopPropagation();

Tài liệu tham khảo


bạn phải dừngPropagation trên một trình xử lý xảy ra trước trình xử lý ngăn chặn mặc định. Bạn có thể thực hiện việc này trên captPhase nếu trình xử lý khác của bạn được đăng ký trên pha bong bóng.
Vitim.us

2

Cách tốt nhất để làm điều này bằng cách sử dụng không gian tên. Đó là một cách an toàn và an toàn. Ở đây .rb là không gian tên đảm bảo chức năng hủy liên kết hoạt động trên phím tắt cụ thể đó nhưng không phải trên các phím khác.

$(document).bind('keydown.rb','Ctrl+r',function(e){
            e.stopImmediatePropagation();
            return false;
        });

$(document).unbind('keydown.rb');

ref1: http://idodev.co.uk/2014/01/safely-binding-to-events-USE-namespaces-in-jquery/

ref2: http://jqfundamentals.com/ch CHƯƠNG / event


1

Vô hiệu hóa:

document.ontouchstart = function(e){ e.preventDefault(); }

Cho phép:

document.ontouchstart = function(e){ return true; }

1

Phương thức notifyDefault () của giao diện Sự kiện cho tác nhân người dùng biết rằng nếu sự kiện không được xử lý rõ ràng, thì hành động mặc định của nó sẽ không được thực hiện như bình thường. Sự kiện tiếp tục lan truyền như bình thường, trừ khi một trong những người nghe sự kiện của nó gọi stopPropagation () hoặc stopImmediatePropagation (), một trong hai kết thúc việc truyền bá cùng một lúc.

Việc gọi ngăn chặnDefault () trong bất kỳ giai đoạn nào của luồng sự kiện sẽ hủy sự kiện, nghĩa là mọi hành động mặc định thường được thực hiện do thực hiện do kết quả của sự kiện sẽ không xảy ra.

Bạn có thể sử dụng Event.catteryable để kiểm tra xem sự kiện có thể hủy được không. Gọi ngăn chặnDefault () cho một sự kiện không thể hủy bỏ không có hiệu lực.

window.onKeydown = event => {
    /*
        if the control button is pressed, the event.ctrKey 
        will be the value  [true]
    */

    if (event.ctrKey && event.keyCode == 83) {
        event.preventDefault();
        // you function in here.
    }
}

0

Tôi đã gặp sự cố khi tôi chỉ cần hành động mặc định sau khi một số hành động tùy chỉnh (cho phép các trường nhập bị vô hiệu hóa khác trên một biểu mẫu) đã kết thúc. Tôi đã bọc hành động mặc định (submit ()) thành một hàm đệ quy riêng (dosubmit ()).

var prevdef=true;
var dosubmit=function(){
    if(prevdef==true){
        //here we can do something else first//
        prevdef=false;
        dosubmit();
    }
    else{
        $(this).submit();//which was the default action
    }
};

$('input#somebutton').click(function(){dosubmit()});

1
Lưu ý chung: Mặc dù một số lập trình viên cảm thấy if (predef == true)rõ ràng hơn, bạn không thêm 7 ký tự vào mã JS của mình. if (prevdef)chỉ là có thể đọc được. Ngoài ra, bạn đã thêm một trình xử lý sự kiện ẩn danh dự phòng khi .click(dosubmit)thực hiện điều tương tự .click(function(){dosubmit()})như không có tham số nào được thông qua.
Mã hóa

0

Sử dụng một boolean:

let prevent_touch = true;
document.documentElement.addEventListener('touchmove', touchMove, false);
function touchMove(event) { 
    if (prevent_touch) event.preventDefault(); 
}

Tôi sử dụng điều này trong Ứng dụng web lũy tiến để ngăn cuộn / phóng to trên một số 'trang' trong khi cho phép những người khác.


0

Bạn có thể thiết lập để tạo thành 2 lớp. Sau khi bạn đặt tập lệnh JS của bạn thành một trong số chúng, khi bạn muốn tắt tập lệnh của mình, bạn chỉ cần xóa lớp với tập lệnh được liên kết khỏi biểu mẫu này.

HTML:

<form class="form-create-container form-create"> </form>   

Mã não

$(document).on('submit', '.form-create', function(){ 
..... ..... ..... 
$('.form-create-container').removeClass('form-create').submit();

});

-3
$('#my_elementtt').click(function(event){
    trigger('click');
});

-10

Tôi không chắc bạn có ý gì: nhưng đây là một giải pháp cho một vấn đề tương tự (và có thể giống nhau) ...

Tôi thường sử dụng ngăn chặnDefault () để chặn các mục. Tuy nhiên: đó không phải là phương pháp đánh chặn duy nhất ... thường thì bạn có thể chỉ muốn có một "câu hỏi" theo sau hành vi nào tiếp tục như trước hoặc dừng lại. Trong một trường hợp gần đây tôi đã sử dụng giải pháp sau đây:

$("#content").on('click', '#replace', (function(event){ return confirm('Are you sure you want to do that?') }));

Về cơ bản, "ngăn chặn mặc định" có nghĩa là chặn và làm một việc khác: "xác nhận" được thiết kế để sử dụng trong ... xác nhận!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.