javascript类和鼠标点击问题

时间:2015-01-02 22:01:32

标签: javascript jquery

所以我试图对我的javascript代码进行分类。

我有一个名为node的类,它只包含一个整数,一个显示该整数的标签元素,以及一个用于递增整数的按钮元素。

当我通过代码调用incrementInteger函数时,一切都按预期工作。但是当我尝试使用鼠标单击事件监听器来调用incrementInteger函数时,事情就不起作用了。

这是我的代码:

$(document).ready(function() {
    var firstNode = new Node();
    firstNode.incrementInteger();
    var secondNode = new Node();
});

function Node() {
    this.integer = 0;
    this.incrementInteger = function() {
        this.integer++;
        this.label.innerHTML = this.integer;
    }
    this.addButton = document.createElement("button");
    this.addButton.addEventListener("mousedown", this.incrementInteger);
    this.container = document.createElement("div");
    this.label = document.createElement("div");
    this.label.innerHTML = this.integer;

    var bodyElement = document.getElementsByTagName("body")[0];
    this.container.appendChild(this.label);
    this.container.appendChild(this.addButton);
    bodyElement.appendChild(this.container);
}

3 个答案:

答案 0 :(得分:1)

this函数中的

incrementInteger不会引用对象上的属性。创建上下文参考:

var self = this;
this.integer = 0;
this.incrementInteger = function() {
    self.integer++;
    self.label.innerHTML = self.integer;
}

演示:http://jsfiddle.net/0bgjpp4w

答案 1 :(得分:0)

您应该将this绑定到incrementInteger,如下所示:

this.incrementInteger = function() {
    this.integer++;
    this.label.innerHTML = this.integer;
}.bind(this);

答案 2 :(得分:0)

如果您的incrementInteger()对于使用'Node'构造函数创建的每个'node'对象都相同,那么它应该是prototype!否则(在普通的javascript中)你不会有共享方法(和属性)。

使用addEventListener几乎做对了,但你传递了对象的本地函数而不是对象本身(从而失去了对{{}的正确引用1}}如其他答案中所述)。

我的想法是this可以将对象作为第二个参数,它将寻找一个名为handleEvent的方法并调用它!
无需绑定addEventListener;它将正确传递上下文:上下文是您刚刚设置为事件侦听器回调的对象。

这为我们提供了将(否则重复克隆的)this函数移动到构造函数incrementInteger的方法,包括prototype函数。 NICE

handleEvent


修改

或者(例如)你可以简单地写成:

function Node(){ 
    this.integer = 0;
    this.addButton = document.createElement('button');
    this.addButton.addEventListener('mousedown', this);
    this.container = document.createElement('div');
    this.label = document.createElement('div');
    this.label.innerHTML = this.integer;
    this.container.appendChild(this.label);
    this.container.appendChild(this.addButton);
    document.getElementsByTagName('body')[0].appendChild(this.container);
}

Node.prototype={
  incrementInteger: function(){
    this.integer++;
    this.label.innerHTML = this.integer;
  },
  handleEvent: function(){  // track event source-element to overload functionality.
    this.incrementInteger();  
  }
};

// avoiding the html jquery script load line for this snippet
window.onload=function(){          // $(document).ready(function() {
    var firstNode = new Node();
    firstNode.incrementInteger();
    var secondNode = new Node();
};                                 // });

在上面,您可以看到我们(仅在代码中)使用了标识符(window.Node = function(){ var d=document; this.container = d.createElement('div'); (this.label = this.container.appendChild(d.createElement('div')) ).innerHTML = this.integer = 0; (this.addButton = this.container.appendChild(d.createElement('button')) ).addEventListener('mousedown', this); d.getElementsByTagName('body')[0].appendChild(this.container); }).prototype={ incrementInteger: function(){ this.label.innerHTML = ++this.integer; } , handleEvent: function(){ this.incrementInteger(); } }; window.onload=function(){ var firstNode = new Node(); firstNode.incrementInteger(); var secondNode = new Node(); };一次,因此只有一个位置可以重命名您的标识符。
对象(由构造函数创建)共享的每个方法(或属性)都可以在Node下轻松查看 除了ES6 Classes之外,这是你可以在纯javascript中实现的最接近你实现的目的:一个代码块,其中一个标识符描述 unique shared 'class'的部分(因为'常见的'javascript没有类!)。

或者(例如)使用闭包将私有东西(共享)仅用于构造函数(第三部分):
(还将构造函数代码重新分解为2行,同时保留原始代码中的所有功能。)

prototype