2

我正在尝试编写我的第一个自建 jQuery 脚本,作为一个超级简单的画廊。

CSS:

#gallery li{
        display:none;
    }

    #gallery li.current {
        display: block;
    }

HTML:

<div id="gallery">
    <li class="current"><img src="img/1.jpg" /></li>
    <li><img src="img/2.jpg" /></li>
    <li><img src="img/3.jpg" /></li>
    <li><img src="img/4.jpg" /></li>
</div>
<div id="controls">
    <span id="left">&#60;</span>
    <span id="right">&#62;</span>
</div>

查询:

$(function(){
    $('#controls #left').click(function(){
        var old = $('li.current');
        $('li.current').removeClass('current');
        if (old = $('#gallery:first-child')){
            $('#gallery:last-child').addClass('current');
        }else{
        $(old).prev('li').addClass('current');
        }
    });
    $('#controls #right').click(function(){
        var old = $('li.current');
        if (old = $('#gallery:last-child')){
            $('#gallery:first-child').addClass('current');
        }else{
        $('li.current').removeClass('current');
        $(old).next('li').addClass('current');
        }
    });
});

在我添加 if/else 语句来检查我们是否正在查看第一个/最后一个画廊图像之前,它工作得很好。我想要这个声明,以便画廊循环。无法弄清楚为什么它不起作用,并且调试没有给我任何东西。

我可以在正确的方向上得到一点推动吗?

编辑:使用下面的一些建议,这就是我所在的位置:

$(function(){
    $('#left').click(function(){
        var old = $('li.current');
        old.removeClass('current');
        if (old == $('#gallery li:first-child')){
            $('#gallery li:last-child').addClass('current');
        }else{
        old.prev('li').addClass('current');
        }
    });
    $('#right').click(function(){
        var old = $('li.current');
        old.removeClass('current');
        if (old == $('#gallery li:last-child')){
            $('#gallery li:first-child').addClass('current');
        }else{      
        old.next('li').addClass('current');
        }
    });
});

虽然仍然没有循环播放(在第一张图像上按“左”会使画廊空白,在最后一张图像上按“右”也是如此)

4

3 回答 3

1

您可能想要使用==

if (old == $('#gallery:first-child')){

if (old == $('#gallery:last-child')){

尽管这无论如何都行不通,正如Jack所指出的那样,因为它们是单独的 jQuery 调用,可以选择相同的元素并返回相似的 jQuery 对象,但不能用于比较,因为它们是 DOM 元素的单独集合. 正确的方法是.is像我在下面提供的那样使用...与以下内容进行比较:

if (old[0] == $('#gallery:first-child')[0]){

像这样对它们进行索引检索每个选定集中的第一项,这是实际的 DOM 元素,并且可以进行比较。可能不是首选,但它没有错。

这是证明这是真的一个例子:http: //jsfiddle.net/4adSj/

你也在做一些奇怪的事情。您不需要使用此选择器:$('#controls #right')-$('#right')由于应该如何使用而足够独特id

此外,您存储var old = $('li.current');,然后下一行您不费心使用old- 您重新获取它,如$('li.current').

此外,您将<li>元素嵌套在 a<div>中,而它们应该只嵌套在<ul><ol><menu>中。

还有一个 - 该变量old是一个 jQuery 对象,因此您不需要$(old)在声明它之后每隔一次就访问它。只需使用old.jQueryMethod().

最后,另一个问题是您的if语句选择器:

$('#gallery:last-child')

意味着找到具有id“画廊”并且是最后一个孩子的元素。你可能想要:

$('#gallery > li:last-child')

这意味着找到作为“画廊”li的父元素的最后一个子元素的子元素。id

所以这是我对您使用的最终代码的建议:

$(function(){
    $('#left').on("click", function () {
        var old = $('li.current');
        old.removeClass('current');
        if (old.is(':first-child')){
            $('#gallery > li:last-child').addClass('current');
        } else {
            old.prev('li').addClass('current');
        }
    });

    $('#right').on("click", function () {
        var old = $('li.current');
        old.removeClass('current');
        if (old.is(':last-child')){
            $('#gallery > li:first-child').addClass('current');
        } else {
            old.next('li').addClass('current');
        }
    });
});
于 2012-12-11T02:16:04.950 回答
0

您可以使用.is(':first-child)and.is(':last-child')来确定某物是第一个还是最后一个孩子:

$('#controls #left').click(function() {
    var old = $('li.current')
        .removeClass('current');

    if (old.is(':first-child')) {
        // search the siblings for the last child
        old.siblings(':last-child').addClass('current');
    } else {
        $(old).prev('li').addClass('current');
    }
});

$('#controls #right').click(function() {
    var old = $('li.current')
        .removeClass('current');

    if (old.is(':last-child')) {
        old.siblings(':first-child').addClass('current');
    } else {
        $(old).next('li').addClass('current');
    }
});

顺便说一句,我会将您的 HTML 更改为:

<div id="controls">
    <span class="left">&#60;</span>
    <span class="right">&#62;</span>
</div>

然后使用$('#controls .left')and$('#controls .right')来定位您的可点击元素。

编辑

一种更好的方法可能是这样的,值得深思:

// wrap the functionality inside an anonymous function
// localizing the gallery and controls blocks
(function($gallery, $controls) {
    var pos = 0;

    // this function performs the actual move left and right, based on event data being passed in via evt.data.delta
    function move(evt) {
        var $items = $gallery.children(), // if the gallery never changes size you should cache this value
        max = $items.length;

        $items.eq(pos).removeClass('current');
        pos = (pos + evt.data.delta) % max; // update the position
        $items.eq(pos).addClass('current');
    }

    // attach the controls
    $controls
        .on('click', '.left', {
            delta: -1 // left decreases the position
        }, move)
        .on('click', '.right', {
            delta: 1 // right increases the position
        }, move);

    // make sure the first is always selected
    $gallery.children().removeClass('current').eq(pos).addClass('current');

}($('#gallery'), $('#controls')));​​​​​​​​​ // immediate invocation
于 2012-12-11T02:21:10.393 回答
0

jsBin 演示

var c = 0; 
var imgN = $('#gallery li').length; // 4   
$('#left, #right').click(function(){
  c = this.id=='right' ? ++c : --c ;
  $('#gallery li').hide().eq( c%imgN ).show(); 
}); 

甚至:

var c = 0; 
$('#left, #right').click(function(){
  $('#gallery li').hide().eq( (this.id=='right'?++c:--c) % 4 ).show(); 
}); 

画廊演示

PS:代替.hide()你可以使用.removeClass('current')
,而不是.show()你可以使用.addClass('current')

于 2012-12-11T02:34:59.760 回答