我在js中使用OO编码确实遇到了麻烦。我写了一段代码,它旋转了3个div,并在任何div的悬停时暂停。这段代码只是使用数组/ json作为输入的常规js。代码有点长,很抱歉。我只需要一些指导如何将这个原始代码转换为更好的形式,如在OO和encap中。当我尝试自己时,我无法将幻灯片数组/ json传递给我定义的对象。是否有一个技巧或指导我可以遵循如何将其重写为更好的形式?
编辑 - 有什么好的指导方针可以遵循,所以我可以用对象而不是全局变量和松散的函数重写它
var slideIndex = 0;
var prevIndex = 0;
var t;
function initPromo(){
sortSlides();
nextPromo();
addListeners();
}
function addListeners(){
for(var i=0; i<slides.length; i++)
$(slides[i].el).hover(function(){ stopPromo(); }, function(){ resumePromo(); });
}
function resumePromo(){ startTimer(); }
function stopPromo(){ clearTimeout(t); }
function nextPromo(){
if(slideIndex > 0 || prevIndex > 0) $(slides[prevIndex].el).css("display","none");
$(slides[slideIndex].el).css("display","block");
prevIndex = slideIndex;
slideIndex = (slideIndex<slides.length-1) ? slideIndex+1 : 0;
startTimer();
}
function startTimer(){ t = setTimeout("nextPromo()", 3000); }
function SortByWeight(a,b) { return b.weight - a.weight; }
function SortByWeightFr(a,b) { return b.frWeight - a.frWeight; }
function sortSlides(){
($("body.en").length > 0) ? slides.sort(SortByWeight) : slides.sort(SortByWeightFr);
}
var slides = [
{
el:'#ps1',
weight:1,
frWeight:3
},
{
el:'#ps2',
weight:0.5,
frWeight:6
},
{
el:'#ps3',
weight:4,
frWeight:9
}
];
window.onload = function () {
initPromo();
};
HTML
<body class="en">
<div id="homepageSlides">
<div id="promoSlides">
<div id="ps1">ps1</div><div id="ps2">ps2</div><div id="ps3">ps3</div>
</div>
</div>
</body>
编辑:OO编码的早期阶段,没有以正确的方式询问
答案 0 :(得分:1)
那么你的“普通javascript”代码已经带你去了。您定义的第一个函数标识域对象:Promo。
var Promo = function () { };
您可以对promo,init,start,stop,resume等实例执行操作。这些操作可以在Promo
的原型上定义。
Promo.prototype.init = function() {
// ...
};
每次都可能会有点烦人的打字原型,所以我们可以将原型捆绑成一个指针,让我们更容易访问......
var Promo = function () { };
(function(obj) {
obj.init = function() {
// ...
};
})(Promo.prototype);
所以我们有一些结构,但我们现在需要分开关注点。在整个普通的javascript中,你已经通过代码散布了配置类型数据。将这些数据位隔离到对象的单个入口点通常是个好主意。
obj.init = function(_el) {
// where _el is the base element of this widget
};
我看到你也在使用jQuery这很好,因为它给你很多力量。我喜欢使用的一个约定是,不是将大量的配置数据传递到给定的小部件,我喜欢给我的对象最小配置,让他们检查HTML以确定其他配置数据。如果您希望将来添加幻灯片或以其他方式更改幻灯片内容,则无需担心更改JS,这具有额外的优势。
假设我们要将幻灯片HTML更改为......
<div id="promoSlides">
<div data-type="slide" data-slide-id="1">ps1</div>
<div data-type="slide" data-slide-id="2">ps2</div>
<div data-type="slide" data-slide-id="3">ps3</div>
</div>
使用jQuery我们可以确定存在多少张幻灯片。
obj.init = function(_el) {
this.baseElement = $(_el);
this.slides = this.baseElement.find('*[data-type="slide"]');
};
现在我们传入最小配置,我们已经将幻灯片的标识分离出来,并且我们已经为自给自足的对象提供了一个很好的模式。其余的将是填写细节(完全未经测试,但这样的事情)......
var Promo = function () { };
(function (obj) {
obj.init = function(_el, _delay) {
// Initialize markup
this.baseElement = $(_el);
this.slides = this.baseElement.find('*[data-type="slide"]');
this.slideDelay = _delay;
// Sort slides
// (not sure what's going on here)
// Bind events
this.baseElement
.on('mouseenter', this.stop.bind(this))
.on('mouseleave', this.start.bind(this));
};
obj.start = function() {
this.timer = setInterval(this.advance.bind(this), this.slideDelay);
};
obj.stop = function() {
clearInterval(this.timer);
};
obj.advance = function() {
// Slide the visible slide off screen
// (note: the parent tag will need overflow:hidden)
var visible = this.baseElement.find('*[data-type="slide"]:visible');
visible.animate({ left: '-' + (visible.width()) + 'px' }, 1000);
// Slide the next slide in
var next = visible.next();
next.css('left', this.baseElement.width() + 1).animate({ left: '0' }, 1000);
};
})(Promo.prototype);
请注意,我使用的是bind
,旧版IE中尚不支持。
答案 1 :(得分:1)
它不是转换为面向对象的风格,那里的代码需要什么。
以下是我看到的问题:
.length
属性<script>
代码,导致使用window.onload
setTimeout()