jQuery - using arrow keys to navigate grid of divs

你。 提交于 2019-12-09 19:08:17

问题


I'm pretty new to HTML, CSS and jQuery - and while my HTML and CSS are OK, my jQuery is not too good - and I think I'm trying to achieve something quite complicated.

As you can see in the code I have a calendar built, and I want people to be able to navigate around it using their arrow keys and press enter to highlight a square. The best example of what I want is this http://jsfiddle.net/BNrBX/ but it VERY confusing! As the html has noting but the container div, and I'm not good enough at understanding jQuery to really get what has been written.

Here is the HTML code for the calendar:

<div class="calander">

<div class="date"><div class="calandertext">&#60;</div></div>
<div class="month" id="month2"><div class="calandertext">April</div></div>
<div class="date"><div class="calandertext">&#62;</div></div>

<div class="day"><div class="calandertext">M</div></div>
<div class="day"><div class="calandertext">T</div></div>
<div class="day"><div class="calandertext">W</div></div>
<div class="day"><div class="calandertext">T</div></div>
<div class="day"><div class="calandertext">F</div></div>
<div class="day"><div class="calandertext">S</div></div>
<div class="day"><div class="calandertext">S</div></div>

<div class="date"><div class="calandertext"></div></div>
<div class="date"><div class="calandertext">1</div></div>
<div class="date"><div class="calandertext">2</div></div>
<div class="date"><div class="calandertext">3</div></div>
<div class="date"><div class="calandertext">4</div></div>
<div class="date"><div class="calandertext">5</div></div>
<div class="date"><div class="calandertext">6</div></div>

<div class="date"><div class="calandertext">7</div></div>
<div class="date"><div class="calandertext">8</div></div>
<div class="date"><div class="calandertext">9</div></div>
<div class="date"><div class="calandertext">10</div></div>
<div class="date"><div class="calandertext">11</div></div>
<div class="date"><div class="calandertext">12</div></div>
<div class="date"><div class="calandertext">13</div></div>

<div class="date"><div class="calandertext">14</div></div>
<div class="date"><div class="calandertext">15</div></div>
<div class="date"><div class="calandertext">16</div></div>
<div class="date"><div class="calandertext">17</div></div>
<div class="date"><div class="calandertext">18</div></div>
<div class="date"><div class="calandertext">19</div></div>
<div class="date"><div class="calandertext">20</div></div>

<div class="date"><div class="calandertext">21</div></div>
<div class="date"><div class="calandertext">22</div></div>
<div class="date"><div class="calandertext">23</div></div>
<div class="date"><div class="calandertext">24</div></div>
<div class="date"><div class="calandertext">25</div></div>
<div class="date"><div class="calandertext">26</div></div>
<div class="date"><div class="calandertext">27</div></div>

<div class="date"><div class="calandertext">28</div></div>
<div class="date"><div class="calandertext">29</div></div>
<div class="date"><div class="calandertext">30</div></div>
<div class="date"><div class="calandertext"></div></div>
<div class="date"><div class="calandertext"></div></div>
<div class="date"><div class="calandertext"></div></div>
<div class="date"><div class="calandertext"></div></div>

</div>

And heres the CSS:

.calander {
font-size: 0;
    width: 70%
}

.month {
position: relative;
height: 80px;
background-color: #FFE06B;
width: 71.4265%;
display: inline-block;
}

.day {
position: relative;
height: 50px;
background-color: #4DC3F0;
display: inline-block;
width: 14.2853%;
}

.date {
position: relative;
height: 80px;
background-color: #FFE06B;
display: inline-block;
width: 14.2853%;
-webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
}

.calandertext {
position: absolute;
bottom: 0;
left: 0;
right: 0;
top: 50%;
text-align: center;
line-height: 0;
font-size: 40px;
}

I've put both together in a jsfiddle: http://jsfiddle.net/9SVez/

Any help - or a pointer of where to go - would be simply fantastic.

Thanks! Josh


回答1:


var $date = $('.day.date').not(':has(:empty)'),
    o = {
       38: -7,
       40: 7,
       37: 'prev',
       39: 'next'
    };

$(document).on('keyup', function (e) {
    var dir = o[e.which],
        $active = $('.active').removeClass('active'),
        i = $date.index($active);

    // Enter Key
    if (e.which === 13) {
        $('.selected').removeClass('selected');
        $active.addClass('selected');
        return;
    }

    // Select the target element
    if (!$active.length) {
        $date.first().addClass('active');
        return;
    } else {
        if (dir === 'next' || dir === 'prev') {
            $active[dir]().addClass('active');
        } else {
            $date.eq(dir + i).addClass('active');
        }
    }
});

http://jsfiddle.net/eqrNT/




回答2:


It doesn't need to be as difficult as the example you're working off. That example is ridiculously verbose and isn't particularly very well designed.

In my example below I've hooked up the arrow events, the main part about what makes my code simple is the calendarMap variable. It's an array that holds all the divs in their x,y positions, this allows us to make moving around the map as simple as moving around the x,y values.

jsFiddle

var position = { x: 0, y: 0 };
var calendarMap = [];

$(document).ready(function () {
    $('.row').each(function () {
        calendarMap.push([]);
        $('.day, .date', this).each(function () {
            calendarMap[calendarMap.length - 1].push($(this));
        });
    });
    highlightCell();
});

$(window).on('keydown', function (e) {
    if (e.keyCode === 37) // left
        moveLeft();
    else if (e.keyCode === 38) // up
        moveUp();
    else if (e.keyCode === 39) // right
        moveRight();
    else if (e.keyCode === 40) // down
        moveDown();
    highlightCell();
});

function moveLeft() {
    position.x--;
    if (position.x < 0)
        position.x = 0;
}

function moveUp() {
    position.y--;
    if (position.y < 0)
        position.y = 0;
}

function moveRight() {
    position.x++;
    if (position.x >= calendarMap[0].length)
        position.x = calendarMap[0].length - 1;
}

function moveDown() {
    position.y++;
    if (position.y >= calendarMap.length)
        position.y = calendarMap.length - 1;
}

function highlightCell() {
    $('.day, .date').removeClass('selected');
    calendarMap[position.y][position.x].addClass('selected');
}

I've left getting the mouse events working and the top row as an exercise for you. For the mouse you want to handle mouseover, figure out which item in calendarMap is being hovered, set position and call highlightCell(). For the top row you probably want to add some custom attributes or something because it's a row with only 3 cells.




回答3:


I edited your code for left and right arrow: http://jsfiddle.net/9SVez/2/ It is not the "best" js, but it should give you a tip:)

var currentDay=0;
function doSelect(){
    $('#firstDay').nextAll().css({backgroundColor: '#FFE06B'});
   $('#firstDay').nextAll().slice(currentDay,currentDay+1).css({backgroundColor: 'blue'});

}
$(function () {
    $(document).keydown(function(e){
        if (e.keyCode == 37) { 
           //alert( "left pressed" );
            currentDay--;
        }

        if (e.keyCode == 39) { 
           //alert( "right pressed" );
            currentDay++;
        }
        doSelect();
        return false;
    });
   doSelect();

});


来源:https://stackoverflow.com/questions/15860188/jquery-using-arrow-keys-to-navigate-grid-of-divs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!