Search code examples
jquerymobile-safari

jQuery Chaining/Efficiency Advice


Ok, before you review the code below, I know that it is AWFUL. It's redundant and bloated and I am not asking for anyone to fix it :)

I am wondering what I need to study in order to fix it on my own. I'm working on a small project for my daughter, an interactive multiplication table that she can view in Mobile Safari.

I want to highlight the cells that lead to a selected number. So, I created this and I'm sharing it because I want to improve it, but I don't have enough knowledge yet.

What principles do I need to study to improve this kind of functionality?

You can see the whole thing here: http://dandenney.com/dev/jasmultiplication

The 100 (10 x 10) is an example of what I am trying to achieve, but I want to do it for every number:

// This starts base functionality of highlighting the involved numbers, 10x10=100
$(document).ready(function() {
    $(".tenxten").hover(function () {
            $("td").addClass("non-choice");
            }, function () {
            $("td").removeClass("non-choice");
    });
    $(".tenxten").hover(function () {
            $(".twoxten, .threexten, .fourxten, .fivexten, .sixxten, .sevenxten,  .eightxten, .ninexten").addClass("vertical-trail");
            }, function () {
            $(".twoxten, .threexten, .fourxten, .fivexten, .sixxten, .sevenxten, .eightxten, .ninexten").removeClass("vertical-trail");
    });
    $(".tenxten").hover(function () {
            $(".tenxtwo, .tenxthree, .tenxfour, .tenxfive, .tenxsix, .tenxseven, .tenxeight, .tenxnine").addClass("horizontal-trail");
            }, function () {
            $(".tenxtwo, .tenxthree, .tenxfour, .tenxfive, .tenxsix, .tenxseven, .tenxeight, .tenxnine").removeClass("horizontal-trail");
    });
    $(".tenxten").hover(function () {
            $(".vertical-ten, .horizontal-ten").addClass("choice");
            }, function () {
            $(".vertical-ten, .horizontal-ten").removeClass("choice");
    });
});                

Solution

  • To get the 10x10 effect you can use the row you're hovering, the index of the <td> in it, and .prevAll() for both to get the effect on the right cells, like this:

    $(function() {
      $("#multiplication").delegate("tr:gt(0) td:not(:first-child)", "hover", function() {
        $(this).toggleClass("choice").prevAll().toggleClass("horizontal-trail")
         .end().closest('tr').prevAll().find('td:nth-child('+($(this).index()+1)+')')
                                       .toggleClass('vertical-trail');
      });
    });
    

    You can give it a try here, this applies the horizontal class by just using .prevAll() to get the previous cells in the row. Then using .end() we go back to $(this) (the currently hovered cell), go up to it's <tr> using .closest(), again get all rows before that using .prevAll() and getting the cells at the same index in them using .find() and :nth-child(), then adding or removing the class on those cells.

    Since you're just toggling on and off, you can use one hover function which maps to both mouseneter and mouseleave combined with .toggleClass(). The .delegate() use is to have one hover handler here, instead of 100.

    The initial selector "tr:gt(0) td:not(:first-child)" is saying not the first row, and not the left most cells in other rows, so this prevents the main numbers from executing this function, so it'll only happen in the table.