F. *_*uri 7 javascript object javascript-objects
这项工作的目标是理解和发挥我听过的一些对象概念的含义.
有很多不同的方法/方法来做到这一点.
我的尝试并不是很干净:为了添加第二个时钟和另一个时区,我必须编辑3个不同的地方.这不太好(见答案的底部).
我怎么能做更有用的事情?
编辑后:最初的问题是关于在jquery和mootools之间进行选择,现在已经选择了; 我们的目标是通过使用mootools来改善这一点.
我用javascript和svg写了一个小样本/ demo:
var cx =128;
var cy =128;
var slen=120;
var mlen=116;
var hlen= 80;
var selem;
var melem;
var helem;
function setvars() {
selem=document.getElementById("seconds");
melem=document.getElementById("minutes");
helem=document.getElementById("hours");
drawtime();
};
function drawtime() {
var now=new Date();
var nows=now.getTime()%60000;
var nowm=now.getMinutes()*1.0+1.0*nows/60000;
var nowh=now.getHours()*1.0+1.0*nowm/60;
var sposx=cx + slen * Math.sin( nows / 30000 * Math.PI );
var sposy=cy - slen * Math.cos( nows / 30000 * Math.PI );
var mposx=cx + mlen * Math.sin( nowm / 30 * Math.PI );
var mposy=cy - mlen * Math.cos( nowm / 30 * Math.PI );
var hposx=cx + hlen * Math.sin( nowh / 6 * Math.PI );
var hposy=cy - hlen * Math.cos( nowh / 6 * Math.PI );
selem.setAttribute("x1",sposx);
selem.setAttribute("y1",sposy);
selem.setAttribute("x2",sposx);
selem.setAttribute("y2",sposy);
melem.setAttribute("x2",mposx);
melem.setAttribute("y2",mposy);
helem.setAttribute("x2",hposx);
helem.setAttribute("y2",hposy);
window.setTimeout(drawtime,80)
};
setvars();Run Code Online (Sandbox Code Playgroud)
#box1 { stroke: black; }
#minutes { stroke: #2266AA; }
#hours { stroke: #3388CC; }
#seconds { stroke: #CCCC22; }
line,circle {
opacity:0.65;
fill:none;
stroke-width:8;
stroke-linecap:round;
stroke-linejoin:round;
marker:none;
stroke-miterlimit:4;
stroke-dasharray:none;
stroke-opacity:1;
visibility:visible;
display:inline;
overflow:visible;
enable-background:accumulate
}Run Code Online (Sandbox Code Playgroud)
<svg xmlns="http://www.w3.org/2000/svg" id="svg2" width="100%"
height="100%" viewBox="0 0 900 256" version="1.0">
<title id="title1">Clock</title>
<circle id="box1" cy="128" cx="128" r="124" />
<line id="hours" x1="128" y1="128" x2="128" y2="48" />
<line id="minutes" x1="128" y1="128" x2="244" y2="128" />
<line id="seconds" x1="128" y1="8" x2="128" y2="8" />
</svg>Run Code Online (Sandbox Code Playgroud)
(最初发布在jsfiddle)因为我对javascript jquery和/或mootools不是很有经验,我想知道是否存在一些更简单的方法,可能是以不同的方式写这个.
如何使用jquery或mootools对固定中心进行简单的旋转:
var hposx=cx + hlen * Math.sin( nowh / 6 * Math.PI );
var hposy=cy - hlen * Math.cos( nowh / 6 * Math.PI );
helem.setAttribute("x2",hposx);
helem.setAttribute("y2",hposy);
Run Code Online (Sandbox Code Playgroud)
如何客观化这段代码?(即使它可能是一件好事)......
所有样品都使用面向对象,特定库,或者欢迎使用!
在阅读了pete(非常感谢!你给了我很好的研究方法)和SoonDead(也感谢第一步转换)的第一条评论后,我环顾四周, jquery和mootools代码,最后我选择了mootools为了减少我的代码,因为mootools让我提交一个arrayforobject.get和一个hash(关联数组)for objet.set:
(function () {
"use strict";
var Point = function(x,y) {
this.x=x;
this.y=y;
};
var Path = function(center,length,both) {
this.center = center;
this.length = length;
this.both = both;
this.end = function(alpha) {
var retx = 1.0*this.center.x +
this.length*Math.sin(alpha);
var rety = 1.0*this.center.y -
this.length*Math.cos(alpha);
if (typeof(this.both)!=='undefined')
return { x1:retx, x2:retx, y1:rety, y2:rety }
else return { x2:retx, y2:rety };
};
};
var Hand = function(svgline,both) {
this.elem = document.id(svgline);
var p = this.elem.get(['x1','y1','x2','y2']);
this.path = new Path (
new Point(p.x1,p.y1),Math.sqrt(
Math.pow(1.0*p.x2-1.0*p.x1,2) +
Math.pow(1.0*p.y2-1.0*p.y1,2)) ,both);
this.setPos = function(angle) {
this.elem.set(this.path.end(angle));
};
};
var Clock = function(hour,minute,second,refresh) {
this.hour = new Hand(hour);
this.minute = new Hand(minute);
this.second = new Hand(second,true);
this.refresh = refresh;
this.setTime = function(timePos) {
var self= this;
var tps = 1.0*timePos.getTime() % 60000;
var tpm = timePos.getMinutes()*1.0 +
1.0* tps/60000;
var tph = timePos.getHours()*1.0 + 1.0* tpm/60;
this.second.setPos(tps / 30000 * Math.PI);
this.minute.setPos(tpm / 30 * Math.PI);
this.hour .setPos(tph / 6 * Math.PI);
setTimeout(function() {
self.setTime(new Date())},this.refresh) };
};
var clock=new Clock('hours','minutes','seconds',120);
clock.setTime(new Date());
}());Run Code Online (Sandbox Code Playgroud)
#box1 { stroke: black; fill:#ccc }
#minutes { stroke: #2288AA; }
#hours { stroke: #3388CC; }
#seconds { stroke: #CCCC22; }
line,circle {
opacity:0.65;
fill:none;
stroke-width:8;
stroke-linecap:round;
stroke-linejoin:round;
marker:none;
stroke-miterlimit:4;
stroke-dasharray:none;
stroke-opacity:1;
visibility:visible;
display:inline;
overflow:visible;
enable-background:accumulate
}Run Code Online (Sandbox Code Playgroud)
<script
src="http://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-nocompat.js"
></script>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2" width="100%"
height="100%" viewBox="0 0 900 256" version="1.0">
<title id="title1">Clock</title>
<circle id="box1" cy="128" cx="128" r="124" />
<line id="hours" x1="128" y1="128" x2="128" y2="48" />
<line id="minutes" x1="128" y1="128" x2="244" y2="128" />
<line id="seconds" x1="128" y1="128" x2="128" y2="8" />
</svg>Run Code Online (Sandbox Code Playgroud)
好吧,现在我的新代码减少了 8 行,甚至始终可读。
这是一个步骤,但objectization意味着将其作为一个对象......目标是
一项中间个人结果,
但现在代码看起来像:
(function () {
"use strict";
var Point = function(x,y) {
this.x=x;
this.y=y;
};
var Path = function(center,length,both) {
this.center = center;
this.length = length;
this.both = both;
this.end = function(alpha) {
var retx=1.0*this.center.x+this.length*Math.sin(alpha);
var rety=1.0*this.center.y-this.length*Math.cos(alpha);
if (typeof(this.both)!=='undefined')
return { x1:retx, x2:retx, y1:rety, y2:rety }
else return { x2:retx, y2:rety };
};
};
var Hand = function(svgline,both) {
this.elem = document.id(svgline);
var p=this.elem.get(['x1','y1','x2','y2']);
this.path = new Path ( new Point(p.x1,p.y1),
Math.sqrt(Math.pow(1.0*p.x2-1.0*p.x1,2)+
Math.pow(1.0*p.y2-1.0*p.y1,2)),
both);
this.setPos = function(angle) {
this.elem.set(this.path.end(angle));
};
};
var Clock = function(hour,minute,second,refresh) {
this.hour = new Hand(hour);
this.minute = new Hand(minute);
this.second = new Hand(second,true);
this.setTime = function(timePos) {
var self= this;
var tps = 1.0*timePos.getTime() % 60000;
var tpm = timePos.getMinutes()*1.0 + 1.0* tps/60000;
var tph = timePos.getHours()*1.0 + 1.0* tpm/60;
this.second.setPos(tps / 30000 * Math.PI);
this.minute.setPos(tpm / 30 * Math.PI);
this.hour .setPos(tph / 6 * Math.PI);
};
};
var RefreshLoop = function(refresh) {
var newdate=new Date();
clock1.setTime(newdate);
newdate=newdate.getTime()+newdate.getTimezoneOffset()*60000;
clock2.setTime(new Date(newdate));
clock3.setTime(new Date(newdate+20700000));
clock4.setTime(new Date(newdate+28800000));
};
var clock1=new Clock('hours','minutes','seconds',120);
var clock2=new Clock('hours2','minutes2','seconds2',120);
var clock3=new Clock('hours3','minutes3','seconds3',120);
var clock4=new Clock('hours4','minutes4','seconds4',120);
RefreshLoop.periodical(500);
}());
Run Code Online (Sandbox Code Playgroud)
如果所有部分都保持很小,我的clock就是一个真正的可重用对象(现在可以工作 4 次)。
该函数setTime必须一起计算所有手牌,因为每个值都包含其他值的一部分,但每个操作只能完成一次。
对于我的时钟, a是由固定 a和 变量Path定义的,Path.end 是指定的计算终点start pointlengthdirectiondirection
aHand是一个给定的SVG line,其原始的Path,以及一个可选标志指定在设置时,起点和终点都必须定位在相同的值(零长度线,圆形终止给出一个圆形点)。
(备注(bug?):由于每个元素都是在 SVG 中定义的,并且 Path.length 是根据 Path 两端之间的距离计算的,因此seconds必须首先[x1,y1]在时钟中心绘制路径,! = [x2,y2]!)
希望有人想纠正/改进/讨论我的objectization......
更新2
我认为,这是现在的最终版本,其中对象很简单,使用了mootools(可能不是太多,欢迎评论),我的最终时钟可以多次使用来显示不同的时区。
(function () {
"use strict";
var Point = function(x,y) {
this.x=x;
this.y=y;
};
var Path = function(center,length,both) {
this.center = center;
this.length = length;
this.both = both;
this.end = function(alpha) {
var retx=1.0*this.center.x+this.length*Math.sin(alpha);
var rety=1.0*this.center.y-this.length*Math.cos(alpha);
if (typeof(this.both)!=='undefined')
return { x1:retx, x2:retx, y1:rety, y2:rety }
else return { x2:retx, y2:rety };
};
};
var Hand = function(svgline,both) {
this.elem = document.id(svgline);
var p=this.elem.get(['x1','y1','x2','y2']);
this.path = new Path ( new Point(p.x1,p.y1),
Math.sqrt(Math.pow(1.0*p.x2-1.0*p.x1,2)+
Math.pow(1.0*p.y2-1.0*p.y1,2)),
both);
this.setPos = function(angle) {
this.elem.set(this.path.end(angle));
};
};
var Clock = function(hour,minute,second,refresh) {
this.hour = new Hand(hour);
this.minute = new Hand(minute);
this.second = new Hand(second,true);
this.setTime = function(timePos) {
var self= this;
var tps = 1.0*timePos.getTime() % 60000;
var tpm = timePos.getMinutes()*1.0 + 1.0* tps/60000;
var tph = timePos.getHours()*1.0 + 1.0* tpm/60;
this.second.setPos(tps / 30000 * Math.PI);
this.minute.setPos(tpm / 30 * Math.PI);
this.hour .setPos(tph / 6 * Math.PI);
};
};
var RefreshLoop = function(refresh) {
var newdate=new Date();
clock1.setTime(newdate);
newdate=newdate.getTime()+newdate.getTimezoneOffset()*60000;
clock2.setTime(new Date(newdate));
clock3.setTime(new Date(newdate+20700000));
clock4.setTime(new Date(newdate+28800000));
};
var clock1=new Clock('hours','minutes','seconds',120);
var clock2=new Clock('hours2','minutes2','seconds2',120);
var clock3=new Clock('hours3','minutes3','seconds3',120);
var clock4=new Clock('hours4','minutes4','seconds4',120);
RefreshLoop.periodical(500);
}());
Run Code Online (Sandbox Code Playgroud)
(function () {
"use strict";
var Point = function(x,y) {
this.x=x;
this.y=y;
};
var Path = function(center,length,both) {
this.center = center;
this.length = length;
this.both = both;
this.end = function(alpha) {
var retx=1.0*this.center.x+this.length*Math.sin(alpha);
var rety=1.0*this.center.y-this.length*Math.cos(alpha);
if (typeof(this.both)!=='undefined')
return { x1:retx, x2:retx, y1:rety, y2:rety }
else return { x2:retx, y2:rety };
};
};
var Hand = function(svgline,both) {
this.elem = document.id(svgline);
var p=this.elem.get(['x1','y1','x2','y2']);
this.path = new Path ( new Point(p.x1,p.y1),
Math.sqrt(Math.pow(1.0*p.x2-1.0*p.x1,2)+
Math.pow(1.0*p.y2-1.0*p.y1,2)),
both);
this.setPos = function(angle) {
this.elem.set(this.path.end(angle));
};
};
var Clock = function(hour,minute,second,refresh) {
this.hour = new Hand(hour);
this.minute = new Hand(minute);
this.second = new Hand(second,true);
this.setTime = function(timePos) {
var self= this;
var tps = 1.0*timePos.getTime() % 60000;
var tpm = timePos.getMinutes()*1.0 + 1.0* tps/60000;
var tph = timePos.getHours()*1.0 + 1.0* tpm/60;
this.second.setPos(tps / 30000 * Math.PI);
this.minute.setPos(tpm / 30 * Math.PI);
this.hour .setPos(tph / 6 * Math.PI);
};
};
var RefreshLoop = function(refresh) {
var newdate=new Date();
clock1.setTime(newdate);
newdate=newdate.getTime()+newdate.getTimezoneOffset()*60000;
clock2.setTime(new Date(newdate));
clock3.setTime(new Date(newdate+20700000));
};
var clock1=new Clock('hours','minutes','seconds',120);
var clock2=new Clock('hours2','minutes2','seconds2',120);
var clock3=new Clock('hours3','minutes3','seconds3',120);
RefreshLoop.periodical(500);
}());Run Code Online (Sandbox Code Playgroud)
circle { stroke: black; }
.startbg { stop-color: #eeeeee; }
.endbg { stop-color: #777777; }
.box { fill:url(#grad0); }
.box1 { fill:url(#grad1); }
.box2 { fill:url(#grad2); }
.box3 { fill:url(#grad3); }
.label { stroke: #424242;fill:#eee;stroke-width:1; }
.minutes { stroke: #2288AA; }
.hours { stroke: #3388CC; }
.seconds { stroke: #CCCC22; }
line,circle,rect {
opacity:0.65;
fill:none;
stroke-width:8;
stroke-linecap:round;
stroke-linejoin:round;
marker:none;
stroke-miterlimit:4;
stroke-dasharray:none;
stroke-opacity:1;
visibility:visible;
display:inline;
overflow:visible;
enable-background:accumulate
}
text {
font-size:15px;
font-style:normal;
font-variant:normal;
font-weight:normal;
font-stretch:normal;
text-align:center;
line-height:100%;
writing-mode:lr-tb;
text-anchor:middle;
fill:#000000;fill-opacity:.7;
stroke:none;
font-family:Nimbus Sans L;
}Run Code Online (Sandbox Code Playgroud)
这使用momentjs来获取国际信息,但没有其他库。
"use strict";
var gv={ clockcount: 1,
svg:'http://www.w3.org/2000/svg',
xlnk:'http://www.w3.org/1999/xlink',
tzlist:['Local'].concat(moment.tz.names()),
vbox:document.getElementById('svg').getAttribute("viewBox").split(" ")
};
function mousepos(event) {
var minxy=innerWidth;
if (minxy > innerHeight) minxy=innerHeight;
return {
x:((event.clientX-(innerWidth-minxy)/2)/minxy)*(gv.vbox[2]-gv.vbox[0]),
y:((event.clientY-(innerHeight-minxy)/2)/minxy)*(gv.vbox[3]-gv.vbox[1])
};
};
function myClock(cx,cy,r,tz) {
var clock=this, elem;
this.cx=128;
if (typeof(cx)!=='undefined') this.cx=cx;
this.cy=128;
if (typeof(cy)!=='undefined') this.cy=cy;
this.r=100;
if (typeof(r)!=='undefined') this.r=r;
this.tz=new Date().getTimezoneOffset();
this.setTz=function(tz) {
if (typeof(tz)!=='undefined') {
this.label=tz;
if (tz!=="Local") {
var ndte=new Date();
var tzoff=moment(ndte).tz(tz).format('HH mm ss').split(' ');
var tznow=Math.floor(ndte/1000)%86400;
this.tz=(tznow-(tzoff[0]*3600+tzoff[1]*60+1*tzoff[2]))/60;
} else this.tz=new Date().getTimezoneOffset();
} else this.label="Local";
};
this.setTz(tz);
this.clkid=gv.clockcount++;
this.floor=0;
this.toggleFloor=function(e) { e.preventDefault();
clock.floor=1-clock.floor; };
this.toggleSecDraw=function(e) { e.preventDefault();
clock.secdraw=1-clock.secdraw; };
this.wheel=function(e) { e.preventDefault();
var sens=1;
if (typeof(e.detail)!=='undefined') {
if ( 0 > e.detail ) { sens=-1; }
} else if ( 0 > e.wheelDelta ) { sens=-1; };
var cidx=gv.tzlist.indexOf(clock.label)*1+1*sens;
if (cidx < 0) cidx=gv.tzlist.length-1;
if (cidx >= gv.tzlist.length) cidx=0;
clock.setTz(gv.tzlist[cidx]);
clock.draw=0; };
this.moused = function (evt) {
evt.preventDefault(); var m=mousepos(evt);
if ((clock.r/2 > Math.pow(Math.pow(Math.abs(clock.cx-m.x),2)+
Math.pow(Math.abs(clock.cy-m.y),2),.5))) {
clock.box.addEventListener("mousemove", clock.mousem, true);
} else {
clock.box.addEventListener("mousemove", clock.mouser, true);
};
clock.box.addEventListener("mouseup", clock.mouseu, true);
};
this.mouseu = function(evt) {
evt.preventDefault(); clock.draw=0;
clock.box.removeEventListener("mousemove", clock.mouser, true);
clock.box.removeEventListener("mousemove", clock.mousem, true);
clock.box.removeEventListener("mouseup", clock.mouseu, true);
};
this.mouser = function(evt) {
evt.preventDefault(); clock.draw=0;
var m=mousepos(evt);
clock.r=1.25*Math.pow(Math.pow(Math.abs(clock.cx-m.x),2)+
Math.pow(Math.abs(clock.cy-m.y),2),.5);
};
this.mousem = function(evt) { evt.preventDefault(); clock.draw=0;
var m=mousepos(evt); clock.cx=m.x; clock.cy=m.y; };
this.drop = function(evt) { evt.preventDefault();clearInterval(clock.loop);
clock.box.remove(); };
elem=document.createElementNS(gv.svg,'g');
elem.setAttribute('id','box'+this.clkid);
document.getElementById('myClock').appendChild(elem);
this.box=document.getElementById('box'+this.clkid);
this.box.addEventListener("mousedown", this.moused ,true);
this.box.addEventListener("click", this.toggleSecDraw,true);
this.box.addEventListener("dblclick", this.toggleFloor ,true);
this.box.addEventListener('mousewheel', this.wheel, true);
this.box.addEventListener('DOMMouseScroll',this.wheel, true);
this.box.addEventListener('contextmenu', this.drop, true);
elem=document.createElementNS(gv.svg,'circle');
this.fill='fill: url(#g'+this.clkid+');'+
'stroke: url(#gb'+this.clkid+');';
elem.setAttribute('style',this.fill);
elem.setAttribute('id','crc'+this.clkid);
this.box.appendChild(elem);
this.crc=document.getElementById('crc'+this.clkid);
this.ticks=[];
for (var i=0;i<60;i++) {
elem=document.createElementNS(gv.svg,'line');
elem.setAttribute('class','ticks');
elem.setAttribute('id','t'+i+'c'+this.clkid);
this.box.appendChild(elem);
this.ticks.push(document.getElementById('t'+i+'c'+this.clkid));
};
elem=document.createElementNS(gv.svg,'rect');
elem.setAttribute('class','label');
elem.setAttribute('id','r'+this.clkid);
this.box.appendChild(elem);
this.rct=document.getElementById('r'+this.clkid);
elem=document.createElementNS(gv.svg,'text');
elem.setAttribute('id','x'+this.clkid);
this.box.appendChild(elem);
this.tbx=document.getElementById('x'+this.clkid);
elem=document.createElementNS(gv.svg,'tspan');
elem.setAttribute('id','t'+this.clkid);
this.tbx.appendChild(elem);
this.txt=document.getElementById('t'+this.clkid);
elem=document.createElementNS(gv.svg,'line');
elem.setAttribute('id','hr'+this.clkid);
elem.setAttribute('class','hours');
this.box.appendChild(elem);
this.hhr=document.getElementById('hr'+this.clkid);
elem=document.createElementNS(gv.svg,'line');
elem.setAttribute('id','mn'+this.clkid);
elem.setAttribute('class','minutes');
this.box.appendChild(elem);
this.hmn=document.getElementById('mn'+this.clkid);
elem=document.createElementNS(gv.svg,'line');
elem.setAttribute('id','sc'+this.clkid);
elem.setAttribute('class','seconds');
this.box.appendChild(elem);
this.hsc=document.getElementById('sc'+this.clkid);
elem=document.createElementNS(gv.svg,'linearGradient');
elem.setAttribute('id','g'+this.clkid);
elem.setAttributeNS(gv.xlnk,'xlink:href','#g0');
document.getElementById('defs').appendChild(elem);
this.deg=document.getElementById('g'+this.clkid);
elem=document.createElementNS(gv.svg,'linearGradient');
elem.setAttribute('id','gb'+this.clkid);
elem.setAttributeNS(gv.xlnk,'xlink:href','#g0');
document.getElementById('defs').appendChild(elem);
this.dgb=document.getElementById('gb'+this.clkid);
this.getTZ=function() { return this.tz; };
this.setTZ=function(tz) { this.tz=tz; };
this.draw=0;
this.secdraw=1;
this.adjust=function() {
if (clock.draw!==1) {
clock.crc.setAttribute