OOP JavaScript -无法在页面加载时分配onclick事件处理程序

j13ufse2  于 2023-01-08  发布在  Java
关注(0)|答案(2)|浏览(109)

我正在尝试使用JavaScript做一个自定义标签系统。但是,为了重用代码,我想用面向对象的风格来写它。这是我目前所拥有的:

function Tabs()
{

    this.tabArray = new Array(arguments.length);
    this.tabArrayC = new Array(arguments.length);
    
    for(i=0;i<arguments.length;i++)
    {
        this.tabArray[i] = arguments[i];
        this.tabArrayC[i] = arguments[i]+'_content';
    }
    
    this.setClickable = setClickable;

    function setClickable()
    {   

        for(i=0;i<this.tabArray.length;i++)
        {
                        
                document.getElementById(this.tabArray[i]).onclick = function()
                {
                    
                    alert(this.tabArray[i]);
                                    
                }
            
        }
                
    }
    
}

function init()
{
    tab = new Tabs('tab1','tab2','tab3','tab4');
    tab.setClickable();
}

window.onload = init();

现在是这样的。我想把onclick事件处理器分配给每个标签,这些标签已经被传递到Tabs 'class'构造函数中。所以在后面的代码中,当我写这样的东西时:

<div id="tab1">Tab1</div>
<div id="tab2">Tab2</div>
<div id="tab3">Tab3</div>
<div id="tab4">Tab4</div>

之前设置的代码:

document.getElementById(this.tabArray[i]).onclick = function()
{
                    
                    alert(this.tabArray[i]);
                                    
}

......会被处决。我希望我解释得够清楚了。有什么想法吗?

qxgroojn

qxgroojn1#

setClickable函数(edit:以及如何调用init的问题):

  1. this在您生成的事件处理程序中的含义将与您预期的不同。You must remember this
    1.闭包(一个 * 关闭 * 数据的函数,比如你的i变量)有一个对变量的 * 持久 * 引用,而不是它的值的副本,所以所有的处理程序在运行时都会看到i,而不是在创建时。Closures are not complicated
    1.您没有声明i,因此您正在成为the Horror of Implicit Globals的牺牲品。
    下面是一种解决这些问题的方法:
function setClickable()
{   
    var i;           // <== Declare `i`
    var self = this; // <== Create a local variable for the `this` value

    for(i=0;i<this.tabArray.length;i++)
    {
                                                         // v=== Use a function to construct the handler
        document.getElementById(this.tabArray[i]).onclick = createHandler(i);
    }

    function createHandler(index)
    {
        // This uses `self` from the outer function, which is the
        // value `this` had, and `index` from the call to this
        // function. The handler we're returning will always use
        // the `index` that was passed into `createHandler` on the
        // call that created the handler, so it's not going to change.
        return function() {
            alert(self.tabArray[index]);
        };
    }
}

......正如goreSplatter和Felix指出的,这行代码:

window.onload = init();

... * 调用 * init函数并使用其返回值赋值给onload。您的意思是:

window.onload = init;

...它只将init分配给onload事件。

    • 离题**:您可以考虑使用更新的"DOM2"机制来附加事件处理程序,而不是使用旧的"DOM0"方法来使用onXYZ属性和特性。(但是它有非常相似的attachEvent)如果你使用像jQueryPrototypeYUIClosure或者any of several others这样的库,它们会为您消除这些差异(并提供许多其他有用的东西)。
8nuwlpux

8nuwlpux2#

问题:

function init()
{
    tab = new Tabs('tab1','tab2','tab3','tab4');
    tab.setClickable();
}

window.onload = init();

在本例中,window.onload将为undefined,因为init()不返回任何内容。

window.onload = init;

相关问题