首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模块模式中未定义的

模块模式中未定义的
EN

Stack Overflow用户
提问于 2016-07-26 09:10:36
回答 1查看 386关注 0票数 0

我正在尝试使用显示模块模式和构造器模式来创建一些漂亮的JS!如果像这样的“倒计时”,我希望能够创建多个实例:

代码语言:javascript
复制
var c1 = new Countdown();
c1.init();
var c2 = new Countdown();
c2.init();

它们应该是独立的。因此,我没有用"var“声明变量,而是在原型上使用"this”。我在函数中引用"this“,但它没有定义。我怎么才能接触到“这个”?

代码语言:javascript
复制
var Countdown = function() {};

Countdown.prototype = (function(doc) {

    return {
        init: init
    };

    function init() {
        // day
        this.d1 = doc.createElement('div');
        this.d1.setAttribute('class', 'day-1 elem');

        // ... more elements left out here
    }

    function updateView(time) {
        this.d1.textContent = getDays(secs)[0];
    }

    function getDays(secs) {
        var result = 0;
        if (secs > 0) {
            result = secs / (60 * 60 * 24);
        }

        return Math.floor(result);
    }

})(document);

编辑

这是我的完整代码:

代码语言:javascript
复制
"use strict";

var Countdown = function() {
    //this.self = this;
};

Countdown.prototype = (function(doc) {

    return {
        initialize: initialize
    };

    function createElements() {
        var countdown = doc.createElement('div');
        countdown.setAttribute('class', 'countdown');

        var heading = doc.createElement('h2');
        heading.textContent = 'Countdown';
        countdown.appendChild(heading);
        document.body.appendChild(countdown);



        // day
        var wrapDay = doc.createElement('div');
        wrapDay.setAttribute('class', 'wrap-day');
        countdown.appendChild(wrapDay);

        this.d1 = doc.createElement('div');
        this.d1.setAttribute('class', 'day-1 elem');
        wrapDay.appendChild(this.d1);

        this.d2 = doc.createElement('div');
        this.d2.setAttribute('class', 'day-2 elem');
        wrapDay.appendChild(this.d2);

        var lblDay = doc.createTextNode('dage');
        wrapDay.appendChild(lblDay);

        var sepDay = doc.createElement('div');
        sepDay.setAttribute('class', 'separator');
        sepDay.textContent = ':';
        countdown.appendChild(sepDay);



        // hour
        var wrapHour = doc.createElement('div');
        wrapHour.setAttribute('class', 'wrap-hour');
        countdown.appendChild(wrapHour);

        this.h1 = doc.createElement('div');
        this.h1.setAttribute('class', 'hour-1 elem');
        wrapHour.appendChild(this.h1);

        this.h2 = doc.createElement('div');
        this.h2.setAttribute('class', 'hour-2 elem');
        wrapHour.appendChild(this.h2);

        var lblHour = doc.createTextNode('timer');
        wrapHour.appendChild(lblHour);

        var sepHour = doc.createElement('div');
        sepHour.setAttribute('class', 'separator');
        sepHour.textContent = ':';
        countdown.appendChild(sepHour);



        // min
        var wrapMin = doc.createElement('div');
        wrapMin.setAttribute('class', 'wrap-min');
        countdown.appendChild(wrapMin);

        this.m1 = doc.createElement('div');
        this.m1.setAttribute('class', 'min-1 elem');
        wrapMin.appendChild(this.m1);

        this.m2 = doc.createElement('div');
        this.m2.setAttribute('class', 'min-2 elem');
        wrapMin.appendChild(this.m2);

        var lblMin = doc.createTextNode('minutter');
        wrapMin.appendChild(lblMin);

        var sepMin = doc.createElement('div');
        sepMin.setAttribute('class', 'separator');
        sepMin.textContent = ':';
        countdown.appendChild(sepMin);



        // sec
        var wrapSec = doc.createElement('div');
        wrapSec.setAttribute('class', 'wrap-sec');
        countdown.appendChild(wrapSec);

        this.s1 = doc.createElement('div');
        this.s1.setAttribute('class', 'sec-1 elem');
        wrapSec.appendChild(this.s1);

        this.s2 = doc.createElement('div');
        this.s2.setAttribute('class', 'sec-2 elem');
        wrapSec.appendChild(this.s2);

        var lblSec = doc.createTextNode('sekunder');
        wrapSec.appendChild(lblSec);
    }

    function initialize() {
        domReady(function() {

            // create DOM
            createElements();

            // get time
            var now = new Date();
            var year = now.getFullYear();
            var month = now.getMonth();
            var dateFinal = new Date(year, month + 1, 1, 0, 0, 0); // first day next month
            var seconds = getSecsLeft(dateFinal);
            var time = getTimeLeftObject(seconds);

            // update view every second
            setInterval(function() {
                seconds = getSecsLeft(dateFinal);
                time = getTimeLeftObject(seconds);
                updateView(time);
            }, 1000);

            // first time
            updateView(time);
        });
    }

    function updateView(time) {
        var days = zeroPadding(time.days);
        var hours = zeroPadding(time.hours);
        var mins = zeroPadding(time.mins);
        var secs = zeroPadding(time.secs);

        this.d1.textContent = days[0];
        this.d2.textContent = days[1];

        this.h1.textContent = hours[0];
        this.h2.textContent = hours[1];

        this.m1.textContent = mins[0];
        this.m2.textContent = mins[1];

        this.s1.textContent = secs[0];
        this.s2.textContent = secs[1];
    }

    function getDays(secs) {
        var result = 0;
        if (secs > 0) {
            result = secs / (60 * 60 * 24);
        }

        return Math.floor(result);
    }
    function getHours(secs) {
        var result = 0;
        if (secs > 0) {
            result = (secs / (60*60)) % 24;
            result = result === 24 ? 0 : result;
        }

        return Math.floor(result);
    }
    function getMins(secs) {
        var result = 0;
        if (secs > 0) {
            result = (secs / 60) % 60;
            result = result === 60 ? 0 : result;
        }

        return Math.floor(result);
    }
    function getSecs(secs) {
        var result = 0;
        if (secs > 0) {
            result = secs % 60;
            result = result === 60 ? 0 : result;
        }

        return Math.floor(result);
    }

    function zeroPadding(num) {
        var result;
        result = num < 10 ? "0" + num : num;

        return new String(result);
    }

    function getTimeLeftObject(seconds) {
        var secs = getSecs(seconds);
        var mins = getMins(seconds);
        var hours = getHours(seconds);
        var days = getDays(seconds);

        return {
            days: days,
            hours: hours,
            mins: mins,
            secs: secs
        };
    }

    function getSecsLeft(dateFinal) {
        var result = (dateFinal - new Date()) / 1000;
        return result < 0 ? 0 : result;
    }

    function domReady(callback) {
        document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback);
    }

})(document);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-26 09:23:05

您似乎是在setInterval中调用setInterval

代码语言:javascript
复制
function init() {
    // day
    this.d1 = doc.createElement('div');
    this.d1.setAttribute('class', 'day-1 elem');

    var update = updateView.bind(this); // you need to bind updateView context
    setInterval(function() {
       var time = ???
       update(time); // `this` will be current instance
    }, 1000)
}

UPD,因为您在domReady回调中设置间隔,所以需要绑定回调本身或先绑定updateView

代码语言:javascript
复制
function initialize() {
    domReady(function() {

        // create DOM
        createElements.call(this); // call with current context

        // get time
        var now = new Date();
        var year = now.getFullYear();
        var month = now.getMonth();
        var dateFinal = new Date(year, month + 1, 1, 0, 0, 0); // first day next month
        var seconds = getSecsLeft(dateFinal);
        var time = getTimeLeftObject(seconds);

        var update = updateView.bind(this); 

        // update view every second
        setInterval(function() {
            seconds = getSecsLeft(dateFinal);
            time = getTimeLeftObject(seconds);
            update(time);
        }, 1000);

        // first time
        update(time);
    }.bind(this)); //bind callback
}

代码语言:javascript
复制
function initialize() {
    var update = updateView.bind(this),
        create = createElements.bind(this); // prebind functions that use this
    domReady(function() {

        // create DOM
        create(); //call prebinded function

        // get time
        var now = new Date();
        var year = now.getFullYear();
        var month = now.getMonth();
        var dateFinal = new Date(year, month + 1, 1, 0, 0, 0); // first day next month
        var seconds = getSecsLeft(dateFinal);
        var time = getTimeLeftObject(seconds);

        // update view every second
        setInterval(function() {
            seconds = getSecsLeft(dateFinal);
            time = getTimeLeftObject(seconds);
            update(time);
        }, 1000);

        // first time
        update(time);
    });
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38585653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档