【问题标题】:Using 'this' inside a link generated by a javascript object在 javascript 对象生成的链接中使用“this”
【发布时间】:2009-09-03 19:50:54
【问题描述】:

Javascript 对我来说非常不稳定,我似乎无法找到答案。我有一些类似于

的代码
var Scheduler = function(divid,startDate,mode){

    this.setHeader = function(){
          header.innerHTML = '<a href="#" onclick="this.showScheduler(1);">Show</a>';

    }

   this.showScheduler = function period(){

        ...
   }

};

我的问题是,如何将 onclick 放入 HTML 中,以便它为我正在使用的当前调度程序对象的适当实例正确调用 showScheduler 函数?

【问题讨论】:

    标签: javascript object yui


    【解决方案1】:

    我不会按照你的方式做任何事情,但是按照你的方式使用代码,我会这样做(很多事情和做 :)):

    var Scheduler = function(divid, startDate, mode){
        var that = this;
    
        this.setHeader = function(){
              header.innerHTML = '<a href="#">Show</a>';
              header.firstChild.onclick = function() { that.showScheduler(1); };
        }
    
       this.showScheduler = function period(){
    
            ...
       }
    };
    

    【讨论】:

    • 我对到目前为止的答案中关于 ol' school 事件处理程序和 DOM 元素缺乏明确性感到惊讶。你是第一个得到它的人。
    • @Zoidberg:它在 Firefox 中运行良好。实际上,它适用于自 1998 年以来制造的所有浏览器。
    • @Zoidberg - 如果您设置 onclick 属性是,但不是 onclick 属性。他们是两个不同的东西。 header.firstChild.onclick = function() { that.showScheduler(1); };与 header.firstChild.setAttribute("onclick", "function() { that.showScheduler(1); };"); 不是一回事
    • @Zoidberg:您正在考虑setAttribute 和事件处理程序(您是对的,在所有 IE 中都会失败)。见webbugtrack.blogspot.com/2007/08/…。然而onclick 属性将function 对象作为它的值并且适用于所有浏览器。见
    • @Zoidberg:that 不是全局变量。 nickyt 只是使用闭包来捕获Scheduler 的实例。这是一个众所周知的 JavaScript 习惯用法。
    【解决方案2】:

    您应该为这类事情使用框架。如果您不使用一个,那么您必须将每个 schedular 实例声明为全局对象,并且您需要实例的名称才能从链接中调用它。看下面的链接

    http://developer.yahoo.com/yui/examples/event/eventsimple.html

    它们只显示正在应用的功能,但您也可以执行类似的操作

    YAHOO.util.Event.addListener(myAnchorDom, "click", this.showScheduler,this,true);
    

    其中 myAnchorDom 是锚标记 dom 对象。这将使 showScheduler 函数在您的调度程序对象范围内执行。

    【讨论】:

    • 你不需要框架来设置myAnchorElement.onclick = ...
    • 否,但直接设置 onclick 是个坏主意,而且一直如此。这就是为什么每个知道自己在做什么的人都使用 add/attach 对的原因。
    • 你不需要...但是为什么要让自己处理跨浏览器问题变得困难。
    • 这实际上对我来说可能是最有用的,因为我在脚本的其他地方使用了 YUI。我要先玩这个,看看我是否不能让它工作。谢谢。
    • @Amy:你应该用你正在使用的任何框架来标记你的问题。这样一来,答案就不必像您目前得到的那样千差万别。
    【解决方案3】:

    使用 DOM 方法代替使用 innerHTML。

    尝试替换这个:

    header.innerHTML = '<a href="#" onclick="this.showScheduler(1);">Show</a>';
    

    用这个:

    var x = this; // create a closure reference
    var anchor = document.createElement('a');
    anchor.href= '#';
    anchor.innerHTML = 'Show';
    anchor.onclick = function() { x.showScheduler(1); }; //don't use onclick in real life, use some real event binding from a library
    header.appendChild(anchor);
    

    解释:

    原始代码中的“this”指的是触发事件的元素,即锚点(“this”对于像这样的事情是出了名的问题)。解决方案是在正确的方法(这就是为什么你必须创建类似于上面的 var x 的东西)然后只留下传递参数的问题,这是通过将方法包装在另一个函数中来完成的。

    严格来说,最好将事件处理程序与 addEventListener/attachEvent 对绑定(因为直接事件分配排除了将多个处理程序分配给一个事件的能力),但如果您是新手,最好使用 jquery 之类的库来处理还是 JS。

    【讨论】:

    • 为什么“使用库中的一些真实事件绑定”?
    • 因为对于新手来说,活动是最难理解的事情之一。我强烈建议您使用有效的东西,而不是花时间把它做好和/或重新发明轮子。
    • @annakata:非常好的观点。它也避免了这种情况:stackoverflow.com/questions/95731/…
    • 好吧,但是 setAttribute 还是有毒的 :)
    【解决方案4】:

    您可以直接向标头对象添加事件处理程序:

    var me = this;
    
    this.setHeader = function(){
              header.innerHTML = '<a href="#" onclick="this.showScheduler(1);">Show</a>';
    
    header.addHandler("click", function(e) { me.showScheduler(1); });
        }
    

    在传入的函数中,this 将引用标题元素。

    【讨论】:

    • 这是我的错误。我不确定确切的名称,但它是一个没有框架可用的函数,但是 IE 和 FF 的调用是不同的。
    【解决方案5】:
    var Scheduler = function(divid, startDate, mode)
    {
        var xthis = this;
    
        this.setHeader = function()
        {
              var lnk = document.createElement("a");
              lnk.addEventListener("click", xthis.showScheduler, false);
              lnk.innerText = "Show";
              lnk.setAttribute('href', "#");
              header.appendChild(lnk);
        }
    
       this.showScheduler = function period(){
    
            ...
       }
    };
    

    【讨论】:

    • lnk.addEventListener 不能在 IE 中工作,而lnk.innerText=在 IE 中工作。
    【解决方案6】:

    在 onclick 属性中使用“this”时,实际上是指锚标记对象。试试这个,看看它是否有效:

    this.setHeader = function(){
          header.innerHTML = '<a href="#" onclick="Scheduler.showScheduler(1);">Show</a>';
    }
    

    【讨论】:

    • 是的。也许我的假设很糟糕。
    猜你喜欢
    • 2023-03-03
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多