약간 아름다운 JS를 만들기 위해 Revealing Module 패턴을 생성자 패턴과 함께 사용하려고합니다! 나는이 같은 "카운트 다운"만약 여러 인스턴스를 만들 수 있도록하려면 :this가 모듈 패턴으로 정의되지 않았습니다.
var c1 = new Countdown();
c1.init();
var c2 = new Countdown();
c2.init();
이 독립적이어야한다. 따라서 변수를 "var"로 선언하는 대신 프로토 타입에 "this"를 사용합니다. 함수 내에서 "this"를 참조하지만 정의되지는 않았습니다. "this"에 어떻게 액세스 할 수 있습니까? 당신이 당신 때문에 setInterval
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 내 updateView
를 호출하는 것
"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);
당신이'init' 함수 내에서'updateView'를 호출 할 의미합니까? 'updateView.call (this, 100)'을 사용하는 경우 –
간격 타이머 (코드 생략)로 매초마다 텍스트를 업데이트합니다. – olefrank
Countdown 생성자에서 this.init() 만 호출하면됩니다. 나는 당신이 성취하고자하는 것에 대해 확신하지 못한다. 왜냐하면 나에게 이것은 정의되어야하고, 나는 그것을 테스트하고 작동한다. ... –