วิธีการยกเลิกการผูกฟังที่เรียก event.preventDefault () (ใช้ jQuery)?


128

jquery toggle การเรียก preventDefault () เป็นค่าเริ่มต้นดังนั้นค่าเริ่มต้นจะไม่ทำงาน คุณไม่สามารถคลิกที่ช่องทำเครื่องหมายคุณไม่สามารถคลิกลิงค์ ฯลฯ ได้

เป็นไปได้หรือไม่ที่จะกู้คืนตัวจัดการเริ่มต้น


คุณสามารถให้รหัสตัวอย่างได้ไหม
Jojo

4
คำถามในชื่อเป็นคำถามที่ยอดเยี่ยม! น่าเสียดายที่คำถามที่เกิดขึ้นจริงไม่ใช่ ... ฉันหวังว่าจะได้พบที่นี่คำตอบว่า (ถ้าเป็นไปได้ทั้งหมด) เราสามารถ 'ล้าง' ผลกระทบpreventDefaultหลังจากที่มันถูกเรียก ปัจจุบันคำถามนี้คือ 'ฉันจะยกเลิกการผูกผู้ฟังเหตุการณ์ด้วย jQuery ได้อย่างไร'
Stijn de Witt

คำตอบ:


80

ในกรณีของฉัน:

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

$('#some_link').unbind('click'); ทำงานเป็นวิธีเดียวในการกู้คืนการกระทำเริ่มต้น

เท่าที่เห็นที่นี่: https://stackoverflow.com/a/1673570/211514


2
หากองค์ประกอบนี้มีตัวจัดการคลิกอีกตัวคุณเลิกผูกเหตุการณ์ทั้งหมดที่แนบมาไม่เพียง แต่ป้องกันตัวจัดการ ...
Aure77

56

มันค่อนข้างง่าย

สมมติว่าคุณทำสิ่งที่ชอบ

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

ตอนนี้เปลี่ยนกลับเป็นสถานการณ์เดิมทำด้านล่าง ...

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

จากเว็บไซต์นี้


โซลูชันนี้ใช้ไม่ได้หลังจาก $ ('# a_link') คลิก (ฟังก์ชัน (e) {e.preventDefault ();}); ใช้ฟังก์ชั่นยกเลิกการผูก
เดนิส Makarskiy

2
ลิงก์ที่คุณระบุเสีย
ซ้อน

16

มันเป็นไปไม่ได้ที่จะกู้คืนpreventDefault()แต่สิ่งที่คุณทำได้คือหลอกมัน :)

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

หากคุณต้องการที่จะก้าวไปอีกขั้นคุณสามารถใช้ปุ่มทริกเกอร์เพื่อทริกเกอร์เหตุการณ์ได้


ฉันค่อนข้างแน่ใจว่ามันเป็น - ฉันทำสิ่งนี้ในการออกแบบเมื่อเร็ว ๆ นี้ ตอนแรกเมื่อคลิกปุ่มฉันป้องกันการเลื่อนใน iphone โดยการเพิ่ม e.preventDefault ไปที่เหตุการณ์ touchmove จากนั้นหลังจากที่ทำแอนิเมชั่นเสร็จแล้วฉันก็กลับมาจริงและมันทำงานได้อย่างมีเสน่ห์
foxybagga

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

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

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

วิธีการทำงานสำหรับฉันคือ: $ (document) .off ('touchmove'); $ (เอกสาร) .on ('touchmove', function () {return true;});
rogervila

9

ในบางกรณี * คุณสามารถเริ่มแรกreturn falseแทนจากนั้นเมื่อคุณต้องการที่จะเรียกคืนเริ่มต้นที่e.preventDefault()return true

* ความหมายเมื่อคุณไม่สนใจเหตุการณ์ที่เดือดดาลและคุณไม่ได้ใช้e.stopPropagation()ร่วมกับe.preventDefault()

ดูคำถามที่คล้ายกัน (เช่นใน Stack Overflow)

หรือในกรณีของช่องทำเครื่องหมายคุณสามารถมีสิ่งที่ชอบ:

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

9

คุณสามารถคืนค่าการกระทำเริ่มต้น (ถ้าเป็นการติดตาม HREF) โดยทำสิ่งนี้:

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


2
ความคิดนั้นถูกต้อง แต่โค้ดที่ออกมาจากกล่องไม่ได้ผลสำหรับฉัน (เว้นแต่จะเป็นการเปลี่ยนแปลงทางไวยากรณ์ใน jquery) ฉันใช้: window.location = $ (this) .attr ('href');
Modika

3

หากเป็นลิงก์ก็$(this).unbind("click");จะเปิดใช้งานการคลิกลิงก์อีกครั้งและพฤติกรรมเริ่มต้นจะถูกกู้คืน

ฉันได้สร้างซอซอเดเดเบียนขึ้นเพื่อสาธิตการทำงาน

นี่คือรหัสของซอ fiddle:

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

ทดสอบรหัสนี้ฉันคิดว่าแก้ปัญหาของคุณ:

event.stopPropagation();

การอ้างอิง


คุณต้องหยุดการขยายตัวในตัวจัดการที่เกิดขึ้นก่อนที่ตัวจัดการที่ป้องกันไม่ให้เริ่มต้น คุณสามารถทำสิ่งนี้กับ capturePhase ถ้าตัวจัดการอื่นของคุณลงทะเบียนในเฟสบับเบิล
Vitim.us

2

วิธีที่ดีที่สุดในการทำเช่นนี้โดยใช้เนมสเปซ มันเป็นวิธีที่ปลอดภัย ที่นี่. rb คือเนมสเปซที่ทำให้แน่ใจว่าฟังก์ชันการยกเลิกการผูกทำงานกับการกดคีย์เฉพาะนั้น แต่ไม่ได้อยู่ที่อื่น

$(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-using-namespaces-in-jquery/

ref2: http://jqfundamentals.com/chapter/events



1

เมธอด preventDefault () ของอินเทอร์เฟซเหตุการณ์จะบอกตัวแทนผู้ใช้ว่าหากเหตุการณ์ไม่ได้รับการจัดการอย่างชัดเจนการกระทำเริ่มต้นของมันไม่ควรดำเนินการตามปกติ เหตุการณ์ยังคงเผยแพร่ตามปกติยกเว้นกรณีที่หนึ่งในเหตุการณ์ของผู้ฟังเรียก stopPropagation () หรือ stopImmediatePropagation () ซึ่งทั้งสองอย่างนี้จะยุติการเผยแพร่ในครั้งเดียว

การเรียก PreventDefault () ในระหว่างระยะการไหลของเหตุการณ์ใด ๆ จะยกเลิกเหตุการณ์ซึ่งหมายความว่าการดำเนินการเริ่มต้นใด ๆ ที่ดำเนินการตามปกติโดยการใช้งานเป็นผลมาจากเหตุการณ์จะไม่เกิดขึ้น

คุณสามารถใช้ Event.cancelable เพื่อตรวจสอบว่าเหตุการณ์นั้นถูกยกเลิกหรือไม่ การเรียก PreventDefault () สำหรับเหตุการณ์ที่ไม่สามารถยกเลิกได้จะไม่มีผลกระทบใด ๆ

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

ฉันมีปัญหาที่ฉันต้องการการกระทำเริ่มต้นหลังจากการกระทำที่กำหนดเองบางอย่าง (เปิดใช้งานมิฉะนั้นปิดการใช้งานช่องป้อนข้อมูลในแบบฟอร์ม) ฉันห่อการกระทำเริ่มต้น (ส่ง ()) ลงในฟังก์ชั่นการเรียกซ้ำ (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
หมายเหตุทั่วไป: ในขณะที่ผู้เขียนโค้ดบางคนรู้สึกif (predef == true)ชัดเจนมากขึ้นคุณกำลังเพิ่มอักขระ 7 ตัวในรหัส JS ของคุณโดยไม่มีเหตุผล if (prevdef)สามารถอ่านได้ นอกจากนี้คุณได้เพิ่มตัวจัดการเหตุการณ์ที่ไม่ระบุชื่อที่ซ้ำซ้อนเมื่อ.click(dosubmit)ทำสิ่งเดียวกันกับที่.click(function(){dosubmit()})ไม่มีการส่งพารามิเตอร์
Gone Coding

0

ใช้บูลีน:

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

ฉันใช้สิ่งนี้ใน Progressive Web App เพื่อป้องกันการเลื่อน / ซูมบน 'หน้า' บางหน้าในขณะที่อนุญาตให้ใช้กับคนอื่น ๆ


0

คุณสามารถตั้งค่าเป็นรูปแบบ 2 คลาส หลังจากที่คุณตั้งค่าสคริปต์ JS ของคุณเป็นหนึ่งในนั้นเมื่อคุณต้องการปิดการใช้งานสคริปต์ของคุณคุณเพียงแค่ลบชั้นเรียนที่มีสคริปต์ผูกไว้จากแบบฟอร์มนี้

HTML:

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

JS

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

});


-10

ฉันไม่แน่ใจว่าคุณคือสิ่งที่คุณหมายถึง: แต่นี่คือทางออกสำหรับปัญหาที่คล้ายกัน (และอาจจะเหมือนกัน) ...

ฉันมักจะใช้ preventDefault () เพื่อดักจับรายการ อย่างไรก็ตาม: ไม่ใช่วิธีการสกัดกั้นเท่านั้น ... บ่อยครั้งที่คุณอาจต้องการ "คำถาม" ที่ตามมาซึ่งพฤติกรรมยังคงเหมือนเดิมหรือหยุด ในกรณีล่าสุดฉันใช้วิธีแก้ไขปัญหาต่อไปนี้:

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

โดยพื้นฐานแล้ว "การป้องกันค่าเริ่มต้น" หมายถึงการสกัดกั้นและทำอย่างอื่น: "การยืนยัน" ถูกออกแบบมาเพื่อใช้ใน ... ดี - ยืนยัน!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.