firefox中的Javascript事件范围问题

Javascript event scoping issues in firefox?

本文关键字:范围 问题 事件 Javascript 中的 firefox      更新时间:2023-09-26

在我们的应用程序中,我们试图通过变量作用域捕获所有ajax调用的e(事件)。例如:

function whatever (e) {
        stuff();
}
function stuff() {
        thingy();
} 
function thingy() {
        // I have access to e
}

如果不将e-through作为参数传递,子函数应该可以访问其父函数的事件。它在chrome和IE中工作,但在firefox中不工作,e在firebox中总是未定义的。我们不想在我们的应用程序中经历数百次ajax调用,并在每个地方传递e作为参数来实现这一点。还有别的办法吗?

否。分段e仅可用于直接在whatever()内部定义的代码或传递引用的任何函数。它不可用于从whatever()内部调用的函数,除非将其传递给它们。

以下是您问题中在所有浏览器中都失败的代码的确切实现:http://jsfiddle.net/jfriend00/ReNKU/

至于解决方案,您可以使用本地函数,然后e可以用于其他两个类似的函数,因为它们是在whatever():的范围内定义的

function whatever (e) {
    function stuff() {
        // e is available here
        thingy();
    } 
    function thingy() {
        // e is available here
    }
    // e is available here
    stuff();
}

或者,您可以将其作为参数传递给每个原始函数:

function whatever (e) {
        stuff(e);
}
function stuff(e) {
        thingy(e);
} 
function thingy(e) {
}

这个关于函数参数可用性的问题与Firefox无关,因为这是一个javascript实现选择,在任何地方都是一样的。

如果您的特定代码恰好在其他一些浏览器中工作,那么在它正在获取的其他父上下文中显然有一个名为ee的全局变量,而且它恰好具有正确的值,但它不是来自whatever(e)模型的e。无论如何,依赖这样一种隐含的行为是不好的。

如果您希望参数e可用于其他两个函数,那么您有两个不错的选择:

  1. 把它作为论据传给他们
  2. whatever(e)的范围内定义这些函数,以便它们可以直接查看参数

如果你真正想做的是访问事件处理程序中发生的事件,那么你只需要知道这一点:

如果使用.addEventListener(),则事件数据结构将作为第一个参数传递给事件处理程序。在所有支持.addEventListener()(包括IE9)的浏览器中都是如此。如果您在旧版本的IE中使用.attachEvent(),则事件数据结构位于全局变量window.event中,您可以在那里访问它。一旦事件处理程序启动,如果您想使此数据结构可用于您调用的其他函数,则应将其作为参数传递给它们。然后,他们的行为将完全是浏览器安全的。

这里有一个快速的跨浏览器事件注册功能,也可以处理事件差异:

// add event cross browser
function addEvent(elem, event, fn) {
    if (elem.addEventListener) {
        elem.addEventListener(event, fn, false);
    } else {
        elem.attachEvent("on" + event, function() {
            // set the this pointer same as addEventListener when fn is called
            // and get the event data structure from the global variable and
            // pass it to the event handler
            return(fn.call(elem, window.event));   
        });
    }
}

jfriend00不是100%正确的,它不是firefox。实际上,这一切都与萤火虫有关。在chrome和IE中,事件可以通过名称(只要你知道事件的名称)进行全局访问。然而,firefox处理事件的方式与IE/chrome不同。除了将事件作为参数传递到函数链之外,我不知道还有什么解决方案。

jsfiddle.net/LU4yT/2这个jsfiddle链接显然根据您使用的浏览器有不同的结果,所以我认为问题是特定于浏览器的。。。尽管我可能不得不同意jfriend00的观点,即虽然您可以访问全局事件,但最好(尽管更占用内存)将事件作为参数传递。