2012-10-25 27 views
2

我一直在使用基本的javascript下拉菜單,使用addEventListener和attachEvent來處理點擊和鼠標功能。 click事件subOpen調用的函數使用javascript「this」關鍵字來獲取被單擊元素的id。找到一個JavaScript「this」關鍵字替代Internet Explorer

樣品添加事件:使用「this」關鍵字

//add event listeners to menuitems 
for (var i=0; i < menuitems.length; i++) { 
    if (menuitems[i].addEventListener) { 
     menuitems[i].addEventListener('click', subOpen, false);  
     menuitems[i].addEventListener('mouseout', closeTimer, false); 
     menuitems[i].addEventListener('mouseover', cancelTimer, false); 
     menuitems[i].addEventListener('selectstart', menucursorselect, false); 
    } else if (menuitems[i].attachEvent) { 
     menuitems[i].attachEvent('onclick', subOpen);  
     menuitems[i].attachEvent('onmouseout', closeTimer); 
     menuitems[i].attachEvent('onmouseover', cancelTimer); 
     menuitems[i].attachEvent('onselectstart', menucursorselect);  
    } 
} 

的subOpen功能的示例:

function subOpen() { 
cancelTimer(); //stops the close timer 

if (submenudisplay) { 
    document.getElementById(submenudisplay).style.display = "none"; 
    activeSubMenu = false; 
} 
var curMenuId = this.id; 
var curSubMenuId = this.id + "submenu"; 

if (curSubMenuId) { 
    document.getElementById(curSubMenuId).style.display = "block"; 
    activeSubMenu = true; 
} 

submenudisplay = curSubMenuId; 

現在,一切工作在所有我只是測試的瀏覽器早期版本的Internet Explorer。對於舊版本的IE,調試器將「this.id」標記爲未定義,因此它不知道要打開哪個子菜單。我做了一些研究,發現舊的IE不會在附加事件時複製函數,而是引用它,所以我無法使用「this」關鍵字捕獲任何有用的數據。

我想知道是否有一個不同的關鍵字或功能,我可以使用它來完成與舊版IE瀏覽器相同的功能。

我的測試代碼完整版,可以發現here

+3

我討厭建議大的嚇人的框架,但是這是那種東西的jQuery擅長做的事情。這非常方便,它足夠好地處理Internet Explorer。 – zneak

+0

我將jQuery描述爲_warm和fuzzy_,而不是_big和scary_。在這個時代,幾乎可以理解你在使用JavaScript時使用jQuery。 – jahroy

+0

@jahroy:這是無稽之談。 –

回答

1

你應該使用jQuery綁定的,而不是直接調用addEventListenerattachEvents功能的事件。 jQuery將解決這些跨瀏覽器兼容性問題。

所以我在這裏的答案是不要這樣做。但是,如果你這樣做,知道由Internet Explorer調用的函數默認沒有this關鍵字。爲了訪問元素,您必須在window.event.srcElement中查找元素。在兼容W3C的瀏覽器上,您可以使用thisevent.target。您可以使用功能_addEventListener作爲W3C功能的跨瀏覽器版本。

var _addEventListener = function (obj, evt, ofnc, bubble) { 
    var fnc = function (event) { 
     if (!event || !event.target) { 
      event = window.event; 
      event.target = event.srcElement; 
     } 
     return ofnc.call(obj, event); 
    }; 
    // W3C model 
    if (obj.addEventListener) { 
     obj.addEventListener(evt, ofnc, !!bubble); 
     return true; 
    } 
    // M$ft model 
    else { 
     return obj.attachEvent('on' + evt, fnc); 
    } 
}; 

//add event listeners to menuitems 
for (var i = 0; i < menuitems.length; i++) { 
    _addEventListener(menuitems[i], 'click', subOpen, false); 
    _addEventListener(menuitems[i], 'mouseout', closeTimer, false); 
    _addEventListener(menuitems[i], 'mouseover', cancelTimer, false); 
    _addEventListener(menuitems[i], 'selectstart', menucursorselect, false); 
}​ 
+0

哇.... _使用jQuery沒有任何聲音聽起來像一場噩夢。 – jahroy

+0

@jahroy:完全沒有。這個答案看起來像是從互聯網上的其他地方抄襲。我可以找到相同的代碼示例,直至「// M $ ft模型」代碼註釋。 –

+1

@ user1689607它實際上是從我自己的代碼中複製和簡化的。原件[這裏](https://github.com/CardinalPath/gas/blob/master/src/helpers.js)。 – Eduardo

4

您可以使用您的調用處理程序,並手動設置this值的函數。

這裏我創建了一個bindHandler函數,該函數接收元素和處理程序,並返回一個新的處理程序,該處理程序調用原始處理程序,並將元素作爲this值。

它還將window.event對象傳遞給原始處理程序以獲得該一致性。

for (var i=0; i < menuitems.length; i++) { 
    if (menuitems[i].addEventListener) { 
     menuitems[i].addEventListener('click', subOpen, false); 
     menuitems[i].addEventListener('mouseout', closeTimer, false); 
     menuitems[i].addEventListener('mouseover', cancelTimer, false); 
     menuitems[i].addEventListener('selectstart', menucursorselect, false); 
    } else if (menuitems[i].attachEvent) { 
     menuitems[i].attachEvent('onclick', bindHandler(menuitems[i], subOpen)); 
     menuitems[i].attachEvent('onmouseout', bindHandler(menuitems[i], closeTimer)); 
     menuitems[i].attachEvent('onmouseover', bindHandler(menuitems[i], cancelTimer)); 
     menuitems[i].attachEvent('onselectstart', bindHandler(menuitems[i], menucursorselect)); 
    } 
} 

function bindHandler(elem, handler) { 
    return function() { 
     return handler.call(elem, window.event); 
    }; 
} 

FWIW,我想創建一個單一的綁定功能是負責爲你處理,以減少一些重複的代碼。

for (var i=0; i < menuitems.length; i++) { 
    bindHandler(menuitems[i], 'click', subOpen); 
    bindHandler(menuitems[i], 'mouseout', closeTimer); 
    bindHandler(menuitems[i], 'mouseover', cancelTimer); 
    bindHandler(menuitems[i], 'selectstart', menucursorselect); 
} 

function bindHandler(elem, type, handler) { 
    if (elem.addEventListener) 
     elem.addEventListener(type, handler, false); 
    else if (elem.attachEvent) 
     elem.attachEvent("on" + type, function() { 
      return handler.call(elem, window.event); 
     }; 
} 
1
function addHandler(elem, type, handler) { 
    elem.addEventListener(type, handler, false); 
} 
if (!document.addEventListener) 
    addHandler = function(elem, type, handler) { 
     elem.attachEvent('on'+type, function() { 
      handler.call(elem, window.event); 
     }); 
    }; 

然後使用

for (var i=0; i<menuitems.length; i++) { 
    addHandler(menuitems[i], 'click', subOpen); 
    addHandler(menuitems[i], 'mouseout', closeTimer); 
    addHandler(menuitems[i], 'mouseover', cancelTimer); 
    addHandler(menuitems[i], 'selectstart', menucursorselect); 
} 
相關問題