2011-08-14 95 views
11

想象這個場景(它真的只是一個場景):射擊和捕獲自定義事件

  • 我有大幹快上每次鼠標點擊遞增全局計數器。
  • 當我到了50次,我想火命名的自定義事件「reachedCount」
  • 我要註冊我的窗口對象捕捉到的東西,事件像
    window.addEventListener('reachedCount', function(args){alert(args.count);}, false)

所以,我的問題是我不知道,也無法找到任何我可以傳遞給我的eventHandler的參數。此外,我曾嘗試Rikudo發佈的方法,但它在IE lt 9中不起作用。

這可能嗎?怎麼樣?

+1

我能問爲什麼編輯?爲什麼投票下來? –

+0

-1沒有研究。看到我的答案。 –

+1

另外,編輯是從標題中刪除Javascript。有標籤,不需要將其包含在標題中。 –

回答

4
function fireEvent(name, target) { 
    //Ready: create a generic event 
    var evt = document.createEvent("Events") 
    //Aim: initialize it to be the event we want 
    evt.initEvent(name, true, true); //true for can bubble, true for cancelable 
    //FIRE! 
    target.dispatchEvent(evt); 
} 

function foobar() { 
    alert("foobar"); 
} 

function testEvents() { 
    window.addEventListener("foobar", foobar, false); //false to get it in bubble not capture. 
    fireEvent("foobar", document); 
} 

找到此代碼與1分鐘的谷歌搜索。 http://the.unwashedmeme.com/blog/2004/10/04/custom-javascript-events/

+0

對不起,但如果你仔細閱讀我的問題,這個答案對我來說還不夠。我需要知道,如何傳遞參數。我研究過它,我找不到它。 –

+0

以及更多,你所做的「研究」甚至不完整,它不適用於IE,所以現在我必須多研究一下。感謝您的投票,雖然 –

+0

編輯您的答案(略),所以我可以刪除投票下來。但是,當下一次提問時,請告訴你嘗試了什麼;)@Andre –

15

使用Rikudo Sennin的答案,您可以通過將參數放入事件本身內部來傳遞參數給您的事件處理程序,就像DOM處理程序一樣!

function fireEvent(name, target, param1, param2) { 
    //Ready: create a generic event 
    var evt = document.createEvent("Events") 
    //Aim: initialize it to be the event we want 
    evt.initEvent(name, true, true); //true for can bubble, true for cancelable 
    evt.param1 = param1; 
    evt.param2 = param2; 
    //FIRE! 
    target.dispatchEvent(evt); 
} 

function foobar(ev) { 
    alert("foobar" + ' ' + ev.param1 + ' ' + event.param2); 
} 

function testEvents(param1) { 
    window.addEventListener("foobar", foobar, false); //false to get it in bubble not capture. 
    fireEvent("foobar", document, 'test', param1); 
} 
+0

謝謝,不錯的一個...唯一的問題是這不適用於IE ... –

+1

什麼版本,什麼不具體工作。自然,9之前的每個版本都有自己的 – HBP

+0

。 document.createEvent未定義。所以我試圖document.createEventObject(); target.fireEvent,因爲我在其他頁面看到的和「目標沒有fireEvent方法」 –

5

所有的參數 - 就像關於事件的所有其他信息 - 應該在Event Object本身中進行。完全獨立的事件對象攜帶全部關於該事件所需的信息。當新的自定義事件對象是創建的(不是事件被觸發時)時,通常會設置您的參數值。

所有的示例代碼下面完全匹配所有其他片段片段事實上,一些例子可能不是由自己多大意義;每當出現這種情況是指前面的例子片段)

對於自己的論點,在某些情況下,你可以重用現有的字段(或者甚至添加自己的新領域):

var newEvent = ... 
newEvent['scrollX'] = your-own-custom-value; 

究竟如何,這些會得到取決於您是否可以使用一套不同新的標準化HTML5的方式,或者必須回退到較舊的瀏覽器支持。 (甚至對根本沒有提供任何東西的舊瀏覽器添加自定義事件支持的各種「墊片」在這裏未被涵蓋 - 其中許多將提供他們自己的獨特方式來設置參數。)

The HTML5方法涉及「字典」(第二)參數給對象的構造,這樣的事情:

var newEvent = new CustomEvent('customname', { propertyname : propertyvalue, 
              anotherpropname : anotherpropvalue, 
               thirdpropname : thirdpropvalue, 
               etcpropname : etcpropvalue } ); 

相應的較舊的方法將看起來像這樣:

var newEvent = document.createEvent(); 
newEvent.initEvent('customname', true, true); 
newEvent['propertyname'] = propertyvalue; 
newEvent['anotherpropname'] = anotherpropvalue; 
newEvent['thirdpropname'] = thirdpropvalue; 
newEvent['etcpropname'] = etcprovalue; 

(上面的例子也可讓它更清楚HTML5 CustomEvent co nstructor實際上在做)

雖然使用現有的屬性名稱(或創建自己的屬性:-),但通常不推薦使用,因爲跨瀏覽器問題和調試麻煩可能非常嚴重。有一段時間,這將是必要的,它會起作用,但不要把它作爲一種通用技術。儘管某些類型的事件對象包含特定的命名屬性,但類似類型的事件對象可能不會。一些事件屬性可能是「只讀」的。從一個瀏覽器到另一個瀏覽器,甚至瀏覽器版本之間,事件對象內部高度可變創建自己的新屬性可能會混淆瀏覽器的Javascript實現。

取而代之,請使用「預留」的一個特定屬性,以用於自定義事件中,而不是其他任何內容:詳細信息

通常你會有幾個參數,但只有一個屬性留出供您使用。因此,傳統的方法是要始終讓所有的參數到只是一個「對象」,這樣的事情:

var myargs = { my : 1, 
       own : getElementById('foo'); 
      args : { X : 32, Y : 53 } }; 

設置這個變量的HTML5的方式將類似於:

var newEvent = new CustomEvent('customname', { bubbles : true, 
              cancelable : true, 
               detail : myargs }); 

老接口做同樣的事情會是這個樣子:

var newEvent = document.createEvent(); 
newEvent.initEvent('customname', true, true); 
newEvent['detail'] = myargs; 

(當然,如果你頻繁使用Javasript「文本對象」花括號語法來減少你的典型您的代碼可能與上述清晰度優先級示例略有不同)。

(無論設置了可能的自定義參數,必須始終爲每個事件設置兩個現有的事件屬性'bubbles'和'cancelable' 。如果正在使用新的HTML5方式,它們將始終顯示爲作爲CustomEvent構造函數第二個參數的對象中的另外兩行。如果使用較舊的方式,它們將成爲initEvent(...)調用的第二個和第三個參數。)

還提供了兩種不同的觸發自定義事件的方法。較新的HTML5方式使用object.dispatchEvent(newEvent)。舊的方法使用object.fireEvent('customname',newEvent,false)。這裏的「object」是指DOMObject/Element;如果「對象」是除DOM元素之外的東西,則究竟發生了什麼(如果有的話)。與本主題的其餘部分相比,元素更具有瀏覽器特定性。 (混合HTML5的方式和舊的方式通常是可行的,但可能會引起混淆,另一個常見的混淆之處是系統函數名爲fireEvent(...),同時也定義了自己的函數名稱)。

(在觸發自定義事件的兩種方式之間存在一些不同之處,舊的fireEvent(...)方法要求您重新指定事件的名稱,即使您已經在initEvent(...)中指定了它,並且舊的fireEvent(...)方法不會觸發「默認操作」[無論這意味着什麼)。)

另一方面,自定義參數以相同的方式訪問,無論HTML5還是使用了設置事件的老式方法。它會是這個樣子:

function customhandler(evt) { 
     alert(evt.detail.own); 

如果一些自定義的值實際上對象本身,點號能得到這麼長時間它可能看起來像一個錯字......但事實並非如此。例如:

function customhandler(evt) { 
     alert(evt.detail.args.X); 

看來一些,這可能在IE 9運作方式略有不同及以下,雖然。希望這些問題只是通常嘗試重新使用事件對象的甚至創建屬性的問題。如果問題更加普遍,你可以在你的網站上放一個「抱歉:-(」信息,或者你可以等待IE6/7/8/9死機,或者你可以嘗試跨瀏覽器自己破解它,或者你可以使用某種墊片/回退功能,但我不清楚是否最好找到與傳統界面「看起來完全相同」的墊片,或者使用墊片提供的備用界面作爲一切(即使傳統界面是可用)

(免責聲明:當然,我可能是錯的一些上面的... :-)

2

以上這些問題的答案似乎是過時

首先我不會使用匿名函數將參數傳遞給事件處理程序。並不是我見過任何人在他們的答案中提到這一點;你只需要避免它。這是因爲當你刪除事件監聽器時,你需要提到處理器。如果處理程序是匿名的,則不能刪除該偵聽程序。

創建一個新的CustomEvent。

var data = { x:20, y:30, rotationY: 60 }, 
    end = new CustomEvent('MOTION_FINISHED', { detail: data }); 
    this.dispatchEvent(end); 

它似乎只允許屬性'detail'傳遞參數。我還讀過'氣泡'和'可取消'(原文:討厭的美國拼寫)屬性,但你沒有在你的問題中提及這些屬性。

要找回您的參數:

function _handler(e){ 
    var x = (e.detail && e.detail.x) || 0; 
}