dom加载后的Javascript调用方法

时间:2014-04-20 16:17:01

标签: javascript

目前,此对象中的id方法将在文档加载之前调用未定义的警报。我有一个方法来检查dom是否已加载,但我仍然坚持如何在dom加载时获取该方法来触发id方法。

我不能简单地在dom加载方法中添加对id方法的调用,因为它将用于其他不相关的任务。

function myHandler(sel) {
    function myObject(sel) {
        this.sel = sel;
        myObject.prototype.init = function () {
            this.ready();
        }
        myObject.prototype.id = function () {
            alert(document.getElementById(this.sel).id);
        }
        myObject.prototype.ready = function () {
            document.onreadystatechange = function () {
                var state = document.readyState
                if (state == 'interactive') {} else if (state == 'complete') {}
            }
        }
    }
    return newTask = new myObject(sel);
    newTask.init;
}
myHandler('element').id();

1 个答案:

答案 0 :(得分:0)

以下是您的代码的重写版本:

var MyObject = function MyObject(selector) {
    this.selector = selector;

    this.init();
};

MyObject.prototype.alertId = function alertId() {
    alert(this.selector);
};

MyObject.prototype.init = function init() {
    var that = this;

    // are we there already?
    if (document.readyState == "interactive" ||
        document.readyState == "complete") {

        // yes, fire immediately
        this.alertId();
    } else {

        // no, wait until the DOM is parsed
        document.addEventListener("DOMContentLoaded", function(event) {
            that.alertId();
        });
    }
};

var my_object = new MyObject('foo');

让我们来看看:

var MyObject = function MyObject(selector) {
    this.selector = selector;

    this.init();
};

这是MyObject对象的构造函数。作为惯例,构造函数通常在Javascript中大写,因此我重命名了它。

在构造函数中,我们通过调用MyObject设置您创建的每个new MyObject('selector string')副本的唯一属性。在这种情况下,它只是我们得到的selector参数。之后,我们在新对象上调用init()

您创建的每个MyObject都不需要自己的init()alertId() - 每个副本的行为都相同。因此,为了不浪费内存,我们在所有MyObjects共享的原型上创建它:

MyObject.prototype.alertId = function alertId() {
    alert(this.selector);
};

如果您将此脚本作为页面底部的最后一个元素,就在结束标记之前,我们可以确定我们的选择器已经可用。但更有力的方法是检查:

MyObject.prototype.init = function init() {
    var that = this;

    // are we there already?
    if (document.readyState == "interactive" ||
        document.readyState == "complete") {

        // yes, fire immediately
        this.alertId();
    } else {

        // no, wait until the DOM is parsed
        document.addEventListener("DOMContentLoaded", function(event) {
            that.alertId();
        });
    }
};

如果我们的DOM已经可用,我们会立即执行alertId()。如果没有,我们会等到注册DOMContentLoaded事件的回调。

请注意,我在回调中使用了that.alertId(),而不是this.alertId()。这是因为当执行我们的回调函数时,this将是window上下文,而不是我们当前的MyObject对象。

为了解决这个问题,我保存了当前this指向变量that中的对象。 that在我们的回调函数中仍然可用,因为Javascript有closures

请注意,上述代码仅适用于现代浏览器。如果您需要与Internet Explorer 8及更早版本兼容,则需要使用ContentLoaded之类的内容解决其对DOMContentLoaded的缺失支持。