2011-10-11 59 views
35

這個問題是爲了開發jQuery插件和其他自包含的JavaScript代碼片段,不需要修改其他腳本文件的兼容性。在調用event.preventDefault()之後是否有[通用]方法來調用默認操作?

我們都知道event.preventDefault()會阻止默認事件,所以我們可以運行一個自定義函數。但是如果我們想在調用它之前簡單地將延遲默認事件呢?我已經看到了各種各樣的特定於案例的忍者技巧和解決方法來重新調用默認動作,但就像我所說的,我的興趣在於以通用的方式重新觸發默認動作,而不是處理基於案例的默認觸發器,以個案爲基礎。

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

    e.preventDefault(); 

    // Do custom code here. 

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

即使像表單提交這樣簡單的事情,似乎沒有普遍的答案。 $(selector).closest("form").submit()解決方法假定默認操作是標準表單提交,並不像ASP.NET中的__doPostBack()函數那樣古怪。要調用ASP.NET回調的結束,這是我來的通用,設置它和忘記它的解決方案最接近:

$(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, "")); 
} 

我想我可以開始編寫特殊情況處理與一個window.location重定向的正常鏈接,但隨後我們打開了一個全新的蠕蟲罐 - 在越來越多的情況下爲缺省事件調用堆積創建比解決方案更多的問題。

那麼怎麼樣?誰有我一直在尋找的魔力子彈?

+1

我真的不明白你想做什麼......不活動處理程序代碼在默認動作發生之前運行*(例如,submit事件處理程序的代碼將在表單實際提交之前運行......是不是您要實現的目標?) –

+2

您的自定義代碼是異步的嗎?這也許可以解釋爲什麼你覺得你需要這樣一種方法,但即使有這種想象的方法也不能解決你的問題。 – agradl

+1

你一定需要更清楚你想要什麼。如果您想在處理程序中運行代碼,那麼該代碼無論如何都會在「默認」行爲之前運行。 –

回答

8

看看這個:

你可以嘗試

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); 
} 

使用這樣的回答:How to trigger event in JavaScript?和jQuery的事件參考:http://api.jquery.com/category/events/event-object/

標籤收到,所以如果你的事件對象再次接收它,你不會循環。

1

這不可能像JamWaffles已經證明的那樣。簡單的解釋爲什麼這是不可能的:如果你重新觸發默認動作,你的事件監聽器再次攔截,並且你有一個無限循環。

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

是這樣相同的(與你想象的功能)。

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

看來你想操縱你點擊的元素的網址。如果你這樣做,它可以正常工作。 Example

5

首先不要撥打preventDefault()。然後,默認操作將在您的事件處理程序之後發生。

+9

這是隻要您不需要在自定義處理後異步執行默認處理,就是正確的答案。 – Jacob

4

這應該工作。我只測試過Firefox。

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

當然,您也必須複製所有舊的事件變量屬性。我只是沒有編碼那部分,但它應該很容易。

+2

+1這是正確的方法。您應該嘗試創建正確類型的事件 - 請參閱https://developer.mozilla.org/en-US/docs/DOM/document.createEvent – chowey

0

我需要點擊後禁用按鈕,然後觸發違約事件,這是我的解決方案

$(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); 
}); 
相關問題