简体   繁体   中英

jQuery script works great with a click, doesn't work with keydown event

I'm a designer learning jQuery. So please forgive me my lack of understanding ;) I'm trying to put together a carousel kind of thing with one main slide visible and two other partially hidden slides that trigger the next/prev slide action.

I've approarched the topic like this: the partially visible prev/next li's rearrange the ul when a prev/next click is received, making the last li of the ul the first one and vice versa, animated with CSS. I've been able to respond correctly to li.next / li.prev clicks, but when I try to respond the same way to keypress left/right - it doesn't work.

Here's the HTML:

<ul>
    <li class="prev" data-id="1">

    </li><!--
    --><li class="main" data-id="2">

    </li><!--
    --><li class="next" data-id="3">

    </li><!--
    --><li data-id="4">

    </li><!--
    --><li data-id="5">

    </li>
</ul>

Then the CSS (I know it's lacking the wrapping overflow: hidden div, removed it for clarity):

ul {
    list-style-type: none;
    display: block;
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
    white-space: nowrap;
    position: absolute;
    bottom: 0;
}

ul li {
    position: relative;
    display: inline-block;
    width: 100%;
    height: 95%;
    margin: 0;
    padding: 0;
    -webkit-transition: all 0.5s ease-out;
    transition: all 0.5s ease-out;
    white-space: normal;
    background: #eee;
    cursor: pointer;
}

ul li.main {
    height: 80%;
    width: 70%;
    margin: 0 15%;
    z-index: 4;
}

ul li.prev {
    height: 75%;
    margin: 0 -8% 0.5% -92%;
    z-index: 1;
}

ul li.next {
    height: 75%;
    margin: 0 0 0.5% -8%;
    z-index: 1;
}

And now the half-working script:

    //this works great

    $('body').on('click', 'li.prev', function() {
        $("body").find( "li" ).eq( 2 ).removeClass("next");
            $(this).next().removeClass().addClass("next");
            $(this).removeClass("prev").addClass("main");
            $(this).prev().removeClass().addClass("prev");

            var $this = $(this), callback = function() {         
$this.siblings(':last()').insertBefore($this).addClass("prev");
                    };
                $this.fadeIn(100, callback).fadeIn(100);
            }); 

            $('body').on('click', 'li.next', function() {
                $("body").find( "li" ).eq( 0 ).removeClass();
                $(this).prev().removeClass().addClass("prev");
                $(this).removeClass().addClass("main");
                $(this).next().removeClass().addClass("next");

                var $this = $(this), callback = function() {            
$this.siblings(':first()').insertAfter($this.siblings(':last()'));
                    };
                    $this.fadeIn(100, callback).fadeIn(100);
                }); 



    // now the left-right keys control attempt

    $(document).keydown(function(e) {
        switch(e.which) {

            case 37: // key right
                $("body").find( "ul li" ).eq( 2 ).removeClass("next");
                $("li.prev").next().removeClass().addClass("next");
                $("li.prev").removeClass("prev").addClass("main");
                $("li.prev").prev().removeClass().addClass("prev");

                var $this = $("li.prev"), callback = function() {      
                  $this.siblings(':first()').insertAfter($this.siblings(':last()'));
                    };
                    $this.fadeIn(100, callback).fadeIn(100);
                break;


            case 39: // key left
                $(".body").find( ".view ul li" ).eq( 0 ).removeClass();
                $("li.next").prev().removeClass().addClass("prev");
                $("li.next").removeClass().addClass("main");
                $("li.next").next().removeClass().addClass("next");

                var $this = $("li.next"), callback = function() {      $this.siblings(':first()').insertAfter($this.siblings(':last()'));
                    };
                    $this.fadeIn(100, callback).fadeIn(100);
            break;

            default: return;
        }
    });

And here it is put together on fiddle:

https://jsfiddle.net/nfp828yc/

Could you please help me out and tell me what an I missing to make the left/right keys do the same as the li.prev / li.next clicks do?

A hughe thanks!

Your problem is that in keydown function you have an undeclared $this because you are not in the scope. The simplest way is triggering the click when keydown. Look at this:

$(document).keydown(function(e) {
    switch(e.which) {

        case 37: // key right
                $('li.next').trigger('click');
            break;


        case 39: // key left
                $('li.prev').trigger('click');
        break;

        default: return;
    }
});

So you are making the function NEXT / PREV only one time, and then when you press left and right key arrows, the click will be triggered in the correct <li>

See it working:

https://jsfiddle.net/nfp828yc/4/

Just trigger the click when hitting the key:

case 37: // key right
     $('li.prev').trigger('click');
  break;

case 39: // key left
     $('li.next').trigger('click');
  break;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM