事件监听器没有绑定

时间:2015-03-05 16:47:38

标签: javascript jquery

我希望有人能够告诉我为什么调用TestProtObj.init并没有按预期工作 - 听众并没有全部工作。

$(document).ready(function () {
    //set TestProtObj properties in the constructor
    var TestProtObj = function (string, target, button) {
        this.testValue = string;
        this.target = $(target);
        this.button = $(button);
    }

    //add methods to the object prototype
    TestProtObj.prototype = {

        init: function () {
            this.button.on('click', function (e) {
                e.preventDefault;
                this.returnTest();
            });
        },

        returnTest: function () {
            this.target.append(this.testValue);
        }
    }

    //initialize client code
    var testString = 'It worked!',
        targetDiv = '#target',
        button = 'button.text-button';
    //call the returnTest() method and pass in params above
    var TestConcObj = new TestProtObj(testString, targetDiv, button);
    TestConcObj.init();
});

奇怪的是,以下代码有效:

$(document).ready(function () {
    var bindListener = function () {
        $('.test').on('click', function (e) {
            e.preventDefault;
            $('.target').append('It works!');
        })
    }

    bindListener();
})

似乎将函数放入对象文字是出于某种原因,导致它失败。 Chrome调试工具栏中没有任何错误。

非常感谢。

JSFiddles:

#1 #2

3 个答案:

答案 0 :(得分:2)

只需在此函数中创建一个私有变量,它使用关键字TestProtObj引用init函数内的this。您可以在函数self的整个范围内重用此变量(init)。

    init: function () {
        var self = this;
        this.button.on('click', function (e) {
            e.preventDefault(); //add () here.
            self.returnTest();
        });

由于JavaScript使用lexical scope,因此可以使用。

https://jsfiddle.net/p9fjamz3/14/

当你在事件处理程序this.button.on('click', ...中引用它时,实际上你指的是按钮而不是你的对象。

答案 1 :(得分:0)

您的课程编码不正确。试试这个:

var TestProtObj = function TestProtObj(string, target, button) {
    return this.prototype.init.call(string, target, button, this);
}

TestPrtoObj.prototype.testValue = null;
TestPrtoObj.prototype.target    = null;
TestPrtoObj.prototype.button    = null;

TestProtObj.prototype.init = function init(string, target, button) {
    vat self = this;

    this.testValue = string;
    this.target    = $(target);
    this.button    = $(button);

    this.button.on('click', function (e) {
        e.preventDefault;
        self.returnTest();
    });

    return this;
}

TestProtObj.prototype.returnTest = function returnTest() {
    this.target.append(this.testValue);
}


//initialize client code
var testString = 'It worked!',
    targetDiv = '#target',
    button    = 'button.text-button';

//call the returnTest() method and pass in params above
var instance = new TestProtObj(testString, targetDiv, button);

创建新实例时会自动调用init方法。现在按钮应该响应点击事件。

查看这个精彩的教程以获取更多信息: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

我建议命名这些函数,这将在调试时帮助您,如果抛出异常,您将在堆栈跟踪中看到函数的名称,而不仅仅是[Function]或[Function anonymous]。

希望这有帮助。

答案 2 :(得分:0)

我已经弄清楚了。我正在尝试.live(),直到我愚蠢地意识到它已被弃用。任何尝试我尝试过的人都应该使用jQuery docs中的技术,并使用以下代码段:

 AjaxProt.prototype = {

        init: function () {
            var thisObj = this;
            $(document).on(thisObj.event, thisObj.targetEl, function(e) {
                e.preventDefault();
                thisObj.ajaxCall();
            });
        },

这将阻止jQuery尝试在不存在的元素(动态加载)上绑定侦听器,直到它实际存在 - 通过巧妙地利用$(document)全局对象。

我希望这可以节省半天的调试时间,因为我刚试图愚蠢地做。干杯!

编辑:感谢Mouser和其他所有试图帮助我克服自己愚蠢的人。