简体   繁体   中英

jQuery: How to navigate from one td to a specific other td in a table

I am new to jQuery so I might approach this the wrong way but hope someone here can help me.

I have a pretty large HTML table that is created dynamically. To help the user I would like to bind a navigation event to the arrow keys only for this table. In this example I would like to "jump" from on div to the next div (they also have the class "myClass" ). The table is larger than the example below but the structure always repeats so every third td has an (editable) div.

So far I couldn't get this to work but the function does catch the arrow press as I can show alerts this way.

My jQuery:

$(document).on('keydown', '#tblCalendar', function(e){
    switch(e.which) {
        case 37: // left
            // similar action to the left
            break;                  
        case 39: // right
            $(this).closest('td').next().next().next().find('div').focus();
            break;          
        default: return; // exit handler
    }
    e.preventDefault(); // prevent default action
});

My HTML (simplified):

<tbody>
    <tr>
        <td></td>
        <td></td>
        <td><div class="myClass"></div></td>
        <td></td>
        <td></td>
        <td><div class="myClass"></div></td>
        // ...
    </tr>
    // ...
</tbody>

Many thanks in advance, Mike

You should use nextUntil to find the next td with a div in it:

$(this).closest('td').nextUntil("td div").focus();

Although I'm not sure how a div can get focus

Since this is referring to the entire table, change the handler to watch for keypresses on the contenteditable div

$(document).on('keydown', '#tblCalendar tr td div', function(e){

I've rebuild your function a little bit. Now it would involves only one DOM request to collect all editable elements and stores them in a variable. You can rotate through all of them using the left and right arrow keys. If no element is selected, it gets the first one. I've added a class to demonstrate that behavior . To adjust this to your needs, simply replace .addClass('active') with .get(0).focus() .

Example of the principal with a class that toggles

var focusable = $('div.myClass');
var current = null;

$(document).on('keydown', function(event) {
    var next = null;

    if (37 == event.which || 39 == event.which) {
        if (null == current) {
            current = 0;
            focusable.eq(current).addClass('active');
            return;
        }

        if (37 == event.which) {
            next = current - 1;
            if (0 > next) {
                next = focusable.length - 1;
            }
        }

        if (39 == event.which) {
            next = current + 1;
            if (focusable.length == next) {
                next = 0;
            }
        }

        focusable.eq(current).removeClass('active');
        focusable.eq(next).addClass('active');
        current = next;
    }
});

Reduced code when there's no class toggle involved

var focusable = $('div.myClass');
var current = null;

$(document).on('keydown', function(event) {
    if (37 == event.which || 39 == event.which) {
        if (null == current) {
            current = 0;
            focusable.eq(current).get(0).focus();
            return;
        }

        if (37 == event.which) {
            --current;
            if (0 > current) {
                current = focusable.length - 1;
            }
        }

        if (39 == event.which) {
            ++current;
            if (focusable.length == current) {
                current = 0;
            }
        }

        focusable.eq(current).get(0).focus();
    }
});

Demo

Try before buy
Try before buy with focusable divs

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