如何将数组传递给用户定义的对象或将非OO代码转换为OO? JavaScript的

时间:2011-11-22 16:08:24

标签: javascript arrays oop object encapsulation

我在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编码的早期阶段,没有以正确的方式询问

2 个答案:

答案 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)

它不是转换为面向对象的风格,那里的代码需要什么。

以下是我看到的问题:

  • 全球范围的污染
  • 将固定的CSS规则与Javascript混合
  • 在循环中使用.length属性
  • 无事件委托
  • 错误放置<script>代码,导致使用window.onload
  • 在不需要时创建新的jQuery对象
  • 在jQuery调用中使用CSS3选择器
  • 不知道如何使用setTimeout()
  • 紧密耦合到HTML(每张幻灯片上的ID)