2011-10-11 30 views
35

Câu hỏi này nhằm mục đích phát triển các plugin jQuery và các đoạn mã JavaScript khép kín khác mà không yêu cầu sửa đổi các tệp kịch bản khác để tương thích.Có cách [phổ quát] để gọi hành động mặc định sau khi gọi event.preventDefault() không?

Chúng ta đều biết event.preventDefault() sẽ ngăn sự kiện mặc định để chúng tôi có thể chạy chức năng tùy chỉnh. Nhưng điều gì sẽ xảy ra nếu chúng tôi muốn đơn giản là trì hoãn sự kiện mặc định trước khi gọi nó? Tôi đã nhìn thấy nhiều thủ thuật ninja và các cách giải quyết khác nhau để gọi lại hành động mặc định, nhưng như tôi đã nói, sở thích của tôi là theo cách phổ quát để kích hoạt lại mặc định và không xử lý các trình kích hoạt mặc định theo từng trường hợp.

$(submitButton).click(function (e) { 

    e.preventDefault(); 

    // Do custom code here. 

    e.invokeDefault(); // Imaginary... :(
}); 

Ngay cả đối với một cái gì đó đơn giản như gửi biểu mẫu, có vẻ như không có câu trả lời chung. Cách giải quyết $(selector).closest("form").submit() giả định rằng hành động mặc định là một biểu mẫu tiêu chuẩn gửi và không phải là một cái gì đó lập dị như hàm __doPostBack() trong ASP.NET. Để kết thúc cách gọi callbacks ASP.NET, đây là gần nhất tôi đã đi đến một vũ trụ, set-it-và-quên-nó giải pháp:

$(submitButton).click(function (e) { 

    e.preventDefault(); 

    // Do custom code here. 

    var javascriptCommand = e.currentTarget.attributes.href.nodeValue; 
    evalLinkJs(javascriptCommand); 
}); 


function evalLinkJs(link) { 
    // Eat it, Crockford. :) 
    eval(link.replace(/^javascript:/g, "")); 
} 

Tôi cho rằng tôi có thể bắt đầu viết các trường hợp đặc biệt để xử lý các liên kết bình thường với một chuyển hướng window.location, nhưng sau đó chúng tôi đang mở một thùng hoàn toàn mới của các sâu - chồng chất ngày càng nhiều trường hợp để yêu cầu sự kiện mặc định tạo ra nhiều vấn đề hơn các giải pháp.

Vì vậy, làm thế nào về nó? Ai có viên đạn ma thuật mà tôi đang tìm kiếm?

+1

tôi không thực sự có được những gì bạn đang cố gắng để làm ... không làm sự kiện mã handler chạy * trước * hành động mặc định xảy ra (ví dụ: mã trình xử lý sự kiện 'submit' sẽ chạy trước khi biểu mẫu thực sự được gửi ... không phải là những gì bạn đang cố gắng đạt được?) –

+2

Mã tùy chỉnh của bạn có đồng bộ không? điều này có thể giải thích lý do tại sao bạn cảm thấy bạn cần một phương pháp như vậy, nhưng thậm chí có phương pháp tưởng tượng đó sẽ không giải quyết được vấn đề của bạn. – agradl

+1

Bạn chắc chắn cần phải rõ ràng hơn về những gì bạn muốn. Nếu bạn muốn chạy mã trong trình xử lý, mã đó sẽ chạy trước hành vi "mặc định". –

Trả lời

8

Hãy xem cái này:

Bạn có thể thử

if(!event.mySecretVariableName) { 
    event.preventDefault(); 
} else { 
    return; // do nothing, let the event go 
} 

// your handling code goes here 
event.originalEvent.mySecretVariableName = "i handled it"; 

if (document.createEvent) { 
    this.dispatchEvent(event.originalEvent); 
} else { 
    this.fireEvent(event.originalEvent.eventType, event.originalEvent); 
} 

Sử dụng câu trả lời này: How to trigger event in JavaScript? và tài liệu tham khảo sự kiện jQuery: http://api.jquery.com/category/events/event-object/

Tag các đối tượng sự kiện bạn nhận được vì vậy nếu bạn nhận lại nó, bạn không lặp lại.

1

Không thể như JamWaffles đã được chứng minh. Giải thích đơn giản tại sao nó không thể: nếu bạn kích hoạt lại hành động mặc định, trình nghe sự kiện của bạn sẽ chặn lại và bạn có một vòng lặp vô hạn.

Và đây

click(function (e) { 
    e.preventDefault(); 
    // Do custom code here. 
    e.invokeDefault(); // Imaginary... :(
}); 

cũng giống như thế này (với chức năng tưởng tượng của bạn).

click(function (e) { 
    // Do custom code here. 
}); 

Dường như bạn muốn thao tác url của phần tử được nhấp. Nếu bạn làm nó như thế này nó chỉ hoạt động tốt. Example.

5

Không gọi số preventDefault() ngay từ đầu. Sau đó, hành động mặc định sẽ xảy ra sau khi trình xử lý sự kiện của bạn.

+9

Đây là câu trả lời đúng miễn là bạn không cần phải thực hiện xử lý mặc định không đồng bộ sau khi xử lý tùy chỉnh của bạn. – Jacob

4

Điều này sẽ hiệu quả. Tôi đã chỉ được thử nghiệm trong firefox mặc dù.

<html> 
<head> 
<script> 
    window.addEventListener("click",handleClick,false); 
    function handleClick(e){ 
     if (e.useDefault != true){ 
      alert("we're preventing"); 
      e.preventDefault(); 
      alert(e.screenX); 
      //Firing the regular action 
      var evt = document.createEvent("HTMLEvents"); 
      evt.initEvent(e.type,e.bubbles,e.cancelable); 
      evt["useDefault"] = true; 
      //Add other "e" attributes like screenX, pageX, etc... 
      this.dispatchEvent(evt); 
     } 
     else{ 
      alert("we're not preventing"); 
     } 
    } 
</script> 
</head> 
<body> 

</body> 
</html> 

Tất nhiên, bạn cũng phải sao chép tất cả các thuộc tính biến sự kiện cũ. Tôi chỉ không viết mã phần đó, nhưng nó phải đủ dễ dàng.

+2

+1 Đây là phương pháp chính xác. Bạn nên cố gắng tạo đúng loại sự kiện - xem https://developer.mozilla.org/en-US/docs/DOM/document.createEvent – chowey

0

tôi cần phải vô hiệu hóa một nút sau khi nhấp chuột và sau đó bắn các sự kiện mặc định, đây là giải pháp của tôi

$(document).on('click', '.disabled-after-submit', function(event) { 
    event.preventDefault(); 
    $(event.currentTarget).addClass('disabled'); 
    $(event.currentTarget).removeClass('disabled-after-submit'); 
    $(event.currentTarget).click(); 
    $(event.currentTarget).prop('disabled', true); 
}); 
Các vấn đề liên quan