detecting events with custom jQuery slider and keyboard keys

- 1 answer

Ad

I've built a simple custom slider where the user can click a item from a grid and it will display the selected item content, and also it lets users navigate trough the other grid content items with the left and right keyboard arrows.

The HTML structure is the following:

<div class="grid-container"> <!-- this is the grid container -->

  <div class="grid-item" tabindex="1"> <!-- grid item -->
    <div class="grid-item-preview">    <!-- preview container -->
      <img class="grid-item-preview-image" src="http://placehold.it/360x240" />
    </div>
    <div class="grid-item-content">    <!-- content container, hidden at first and opens when the user clicks on the preview container -->
      <div class="grid-item-content-left">
        <img class="grid-item-original-image" src="http://placehold.it/640x480?text=Item1" />
      </div>
      <div class="grid-item-content-right">
        <h3 class="grid-item-title">
          This is a test item
        </h3>
        <p class="grid-item-text">
          This is some filler text
        </p>
      </div>
    </div>
  </div>
</div>

The problem is that, with the code I have, jQuery only traverses one time trough the HTML elements and if the user presses the arrow keys again, it just doesn't work again unless the user closes and opens a new grid item again.

My js/jQuery code is the following:

$( document ).ready( function() {
$( '.grid-item' )
.on( 'click', function() {
    $( this ).toggleClass( 'open-grid-item' );
    $( this ).find( '.grid-item-content' ).fadeToggle();
})
    .on( 'keydown', function( event ) {
    if( $( this ).hasClass( 'open-grid-item' ) ) {
    switch( event.keyCode ) {
        case 37: $( this )                  //User press left arrow  
        .removeClass( 'open-grid-item' )  //Removes class
        .find( '.grid-item-content' )      //Find the content container
        .fadeOut()                        //Fade out content container                      
        .parent()                         //Traverses to parent div .grid-item
        .prev( '.grid-item' )             //Traverses to previous div .grid-item
        .addClass( 'open-grid-item' )     //Add class open grid
        .find( '.grid-item-content' )      //Traverses to content container of the new div
        .fadeIn();                        //Shows content div
        break;
      case 39: $( this )
        .removeClass( 'open-grid-item' )  //Same as before, but traverses to next .grid-item 
        .find( '.grid-item-content' )
        .fadeOut()
        .parent()
        .next( '.grid-item' )
        .addClass( 'open-grid-item' )
        .find( '.grid-item-content' )
        .fadeIn();
        break;
    }
  }
});
});

I have a jsfiddle with a working demo here: https://jsfiddle.net/wuzrcnus/4/

How can I modify my code to enable the user to navigate to all grid items with the arrow keys? Thanks.

Ad

Answer

Ad

Set tabindex to -1 on all .grid-item and use focus() to bring the next or previous item into focus:

switch (event.keyCode)
{
    case 37:
        $(this)
            .removeClass('open-grid-item')
            .find('.grid-item-content')
            .fadeOut()
            .parent()
            .prev('.grid-item')
            .focus()
            .addClass('open-grid-item')
            .find('.grid-item-content')
            .fadeIn();
    break;
    case 39:
         $(this)
            .removeClass('open-grid-item')
            .find('.grid-item-content')
            .fadeOut()
            .parent()
            .next('.grid-item')
            .focus()
            .addClass('open-grid-item')
            .find('.grid-item-content')
            .fadeIn();
    break;
}

JSFiddle

Ad
source: stackoverflow.com
Ad