0

我刚刚用 jQuery 做了一个幻灯片,查看了“下一张幻灯片”和“上一张幻灯片”按钮的代码,我意识到它们几乎是一样的,除了几个功能发生了变化。

我认为这可以被重构以提高效率,但我不确定如何。

有人可以告诉我怎么做吗?

//UI Binding
$nextbutton.on("click", function(){

    //Blocking control
    if (slideshowBlocked) return;
    slideshowBlocked = true;

    //Get active slide
    var $active = $slides.filter(".active");
    //Get new Slied
    var $newSlide = $active.next(".slide");
    if (!$newSlide.length){
        $newSlide = $slides.first();
    }

    //Prepare new slide beneath the active
    $newSlide.css({
        "z-index": 5,
        "display": "block"
    });

    //Fade out the active
    $active.fadeOut(function(){
        //Update states and CSS properties
        $(this).removeClass("active");
        $newSlide.addClass("active").css( "z-index", 10);;

        //Unblock slideshow
        slideshowBlocked = false;
    });
});
$prevbutton.on("click", function(){

    //Blocking control
    if (slideshowBlocked) return;
    slideshowBlocked = true;

    //Get active slide
    var $active = $slides.filter(".active");
    //Get new Slied
    var $newSlide = $active.prev(".slide");
    if (!$newSlide.length){
        $newSlide = $slides.last();
    }

    //Prepare new slide beneath the active
    $newSlide.css({
        "z-index": 5,
        "display": "block"
    });

    //Fade out the active
    $active.fadeOut(function(){
        //Update states and CSS properties
        $(this).removeClass("active");
        $newSlide.addClass("active").css( "z-index", 10);;

        //Unblock slideshow
        slideshowBlocked = false;
    });
});
4

3 回答 3

1

鉴于,正如您所说,这两个函数基本上都在做同样的事情,您可以使用工厂函数并传入您想要的选项。不需要基于字符串的逻辑 - 只需使用适当的函数名称。

function slide (direction, fallback) {
    return function () {
        //Blocking control
        if (slideshowBlocked) return;
        slideshowBlocked = true;

        //Get active slide
        var $active = $slides.filter(".active");

        //Get new slide
        var $newSlide = $active[direction](".slide");
        if (!$newSlide.length) {
            $newSlide = $slides[fallback]();
        }

        //Prepare new slide beneath the active
        $newSlide.css({
            "z-index": 5,
            "display": "block"
        });

        //Fade out the active
        $active.fadeOut(function(){
            //Update states and CSS properties
            $(this).removeClass("active");
            $newSlide.addClass("active").css( "z-index", 10);

            //Unblock slideshow
            slideshowBlocked = false;
        });
    }
}

$nextbutton.on('click', slide('next', 'first'));
$prevbutton.on('click', slide('prev', 'last'));
于 2013-04-16T10:17:23.407 回答
0

没有看到你的 DOM,我不能更精确,但它基本上是这样的:

与其使用 $nextbutton 和 $prevbutton,不如使用更通用的触发器。例如,如果两者都是按钮或链接,则在该级别的按钮或链接上触发。例如,如果您的触发器类似于

<ul class="controls">
    <li><a class="prev">Previous</a></li>
    <li><a class="next">Next</a></li>
</ul>

然后绑定到.controls a而不是.prevand .next

然后两者都可以使用完全相同的代码,除了:

//Get new Slide
var $newSlide = $active.next(".slide");
if (!$newSlide.length){
    $newSlide = $slides.first();
}

相反,您必须执行以下操作:

//Get new Slide
var isPrev = $(this).hasClass(theNameOfClassOnPrevControl);
var $newSlide = isPrev ? $active.prev(".slide") : $active.next(".slide");
if (!$newSlide.length){
    $newSlide = isPrev ? $slides.last() : $slides.first();
}

希望有帮助。让我知道是否有任何需要澄清的地方。

于 2013-04-16T09:59:51.253 回答
0

不是最优雅的方式,但这至少调用一个函数而不是两个。

var nextOrPrevious = function (nextOrPrevious) {
        if (slideshowBlocked) return;
        slideshowBlocked = true;

        //Get active slide
        var $active = $slides.filter(".active");
        //Get new Slied
        var $newSlide;
        if (nextOrPrevious === "next") {
            $newSlide = $active.next(".slide");
        } else if (nextOrPrevious === "previous") {
            $newSlide = $active.prev(".slide");
        } else {
            console.log("Wrong argument");
        }

        if (!$newSlide.length) {
            if (nextOrPrevious === "previous") {
                $newSlide = $slides.last();
            } else if (nextOrPrevious === "next") {
                $newSlide = $slides.next();
            }else {
            console.log("Wrong argument");
        }
        } 

        //Prepare new slide beneath the active
        $newSlide.css({
            "z-index": 5,
            "display": "block"
        });

        //Fade out the active
        $active.fadeOut(function () {
            //Update states and CSS properties
            $(this).removeClass("active");
            $newSlide.addClass("active").css("z-index", 10);;

            //Unblock slideshow
            slideshowBlocked = false;
        });
    };
$nextbutton.on("click", nextOrPrevious("next"));
$prevbutton.on("click", nextOrPrevious("previous"));
于 2013-04-16T10:07:37.410 回答