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

发布于 2024-12-17 14:24:43 字数 1780 浏览 0 评论 0原文

我在 js 中的 OO 编码方面确实遇到了麻烦。我编写了一段代码,它会旋转 3 个 div,并在悬停在任何 div 上时暂停。这段代码只是使用 array/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 编码的早期,没有以正确的方式询问

I really have trouble with OO coding in js. I have written a piece of code which rotates through 3 divs, and pauses on hover of any div. This code is just regular js using an array/json as the input. the code is a bit long so sorry about that. I just need some guidance on how I can convert this primitive code to a better form, as in OO and encap. When I tried myself I could not pass the slides array/json to my defined object. Is there a trick or guideline i can follow on how to rewrite this to a better form?

Edit - What is a good guideline to follow so I can rewrite this with objects instead of global variables and loose functions

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>

Edit: Early days in OO coding, not asked in the right way

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

征﹌骨岁月お 2024-12-24 14:24:43

好吧,你的“纯 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"]');
};

现在我们传入最小的配置,我们已经将幻灯片的标识分离到 HTML 中,并且我们已经为自给自足的对象提供了一个很好的模式。剩下的就是填写详细信息(完全未经测试,但类似这样)...

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);

请注意,我使用了旧版本 IE 尚不支持的 bind

Well your "plain javascript" code is already taking you part way there. The first function you have defined identies the domain object: Promo.

var Promo = function () { };

You have actions on an instance of promo, init, start, stop, resume, etc. These can be defined on the prototype of Promo.

Promo.prototype.init = function() {
  // ...
};

It could get a little annoying typing prototype each time, so we could bundle the prototype into a pointer that allows us a lot easier access...

var Promo = function () { };
(function(obj) {

    obj.init = function() {
        // ...
    };

})(Promo.prototype);

So we've got some structure but we need to now separate concerns. Throughout your plain javascript you've got config type data strewn through the code. It's generally a good idea to isolate these bits of data to a single entry point for your object.

obj.init = function(_el) {
     // where _el is the base element of this widget
};

I see you're also using jQuery which is good because it gives you a lot of power. One convention I like to use is instead of passing a huge amount of config data into a given widget, I like to give my objects minimal config and let them inspect the HTML to determine additional configuration data. This has the added advantage of if you wanted to add slides in the future or otherwise make changes to the slide content you need'nt worry about changing the JS.

Let's say we were to alter the slide HTML to look like...

<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>

Using jQuery we could identify how many slides are present.

obj.init = function(_el) {
    this.baseElement = $(_el);
    this.slides = this.baseElement.find('*[data-type="slide"]');
};

Now we're passing in minimal config, we've separated out the identification of the slides to the HTML, and we've got a nice pattern for a self-sufficient object. The rest would be to fill in the details (totally untested, but something like this)...

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);

Note that I made use of bind which isn't supported yet in older versions of IE.

合约呢 2024-12-24 14:24:43

这不是该代码所需的转换为面向对象的风格。

以下是我在那里看到的问题:

  • 全局范围
  • 混合固定CSS规则与Javascript
  • 的污染在循环中使用.length属性
  • 没有事件委托
  • 导致在不需要时
  • 创建新的 jQuery 对象在 jQuery 调用中使用 CSS3 选择器
  • 不知道如何使用 setTimeout()
  • 与 HTML 紧密耦合(每张幻灯片上的 ID)

Its not the converting to object oriented style what is needed for that code there.

Here are issues i see there:

  • pollution of global scope
  • mixing fixed CSS rules with Javascript
  • use of .length attribute within a loop
  • no event delegation
  • misplacement of <script> tag, resulting in use of window.onload
  • creating new jQuery object when it is not needed
  • use of CSS3 selectors in jQuery calls
  • no clue how to use setTimeout()
  • tight coupling to HTML ( id on each slide )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文