1
\$\begingroup\$

I would like to see if the working code below can be written more elegantly. I am assuming there is a way to parse out the "r" and "h" to condense it down into a function. Any help is much appreciated for learning purposes. There are no parent/sibling relationships in the ID's.

    $('#r1_1').hoverIntent(function(){
        $('#h1_1').toggleClass('vis');
    });
    $('#r1_2').hoverIntent(function(){
        $('#h1_2').toggleClass('vis');
    });
    $('#r1_3').hoverIntent(function(){
        $('#h1_3').toggleClass('vis');
    });
    $('#r1_4').hoverIntent(function(){
        $('#h1_4').toggleClass('vis');
    });
    $('#r1_5').hoverIntent(function(){
        $('#h1_5').toggleClass('vis');
    });
    $('#r2_1').hoverIntent(function(){
        $('#h2_1').toggleClass('vis');
    });
    $('#r2_2').hoverIntent(function(){
        $('#h2_2').toggleClass('vis');
    });
    $('#r2_3').hoverIntent(function(){
        $('#h2_3').toggleClass('vis');
    });
    $('#r2_4').hoverIntent(function(){
        $('#h2_4').toggleClass('vis');
    });
    $('#r2_5').hoverIntent(function(){
        $('#h2_5').toggleClass('vis');
    });
    $('#r3_1').hoverIntent(function(){
        $('#h3_1').toggleClass('vis');
    });
    $('#r3_2').hoverIntent(function(){
        $('#h3_2').toggleClass('vis');
    });
    $('#r3_3').hoverIntent(function(){
        $('#h3_3').toggleClass('vis');
    });
    $('#r3_4').hoverIntent(function(){
        $('#h3_4').toggleClass('vis');
    });
\$\endgroup\$
2
\$\begingroup\$

Instead of using ids #r, let's include in the element the attribute data-something to differentiate the elements that must have the behavior setted by the function. Using a div, for instance:

<div data-something="1_1"></div>
<div data-something="2_2"></div>

We won't need the ids with #r anymore. Considering that you already have the elements #h* we just need to put the id number inside data-something of the corresponding element, so that the function can use it:

$("div[data-something]").hoverIntent(function() {
    var idNumber = $(this).data("something");
    $('#h' + idNumber).toggleClass('vis');
});

Now, you just need to use the data-something attribute.

\$\endgroup\$
  • \$\begingroup\$ ha ! i see we had the same idea at the same time :D \$\endgroup\$ – m_x May 31 '13 at 16:57
  • \$\begingroup\$ Thanks very much! Worked beautifully. And I learned a great deal from it. \$\endgroup\$ – user2440204 Jun 1 '13 at 14:37
1
\$\begingroup\$

A basic function for running it could be

function hi(n1, n2) {
   var r = '#r'+n1+'_'+n2;
   var h = '#h'+n1+'_'+n2;
   $(r).hoverIntent(function() {
      $(h).toggleClass('vis');
   });
}

However, it's possible to trim this down more by creating an array, and storing both r, and h in it. The array would look something like this: var arr = ["#r"+n1+"_"+n2, "#h"+n1+"_"+n2];, and then instead of inserting r and h into the hoverIntent function, you would use arr[0] and arr[1]. If they are all meant to be run at once, you could run a nested for loop so that r1_ - r3_ would be created, and then the secondary numbers would be populated.

\$\endgroup\$
  • \$\begingroup\$ Thank you Andrew - In the above basic function, how do I grab the unique values of n1 and n2? \$\endgroup\$ – user2440204 May 31 '13 at 16:29
  • \$\begingroup\$ @user2440204 n1 and n2 would be entered in as numbers. So for your first example, you would execute it as hi(1, 1). If you need those numbers back, you could either add them as index two and three in the array, or you could return a different array with those two numbers in it. \$\endgroup\$ – ayyp May 31 '13 at 16:31
  • \$\begingroup\$ Thanks again. I am having difficulty coding what you are describing, so I guess this goes beyond my skill level right now. I will do some more studying and research. \$\endgroup\$ – user2440204 May 31 '13 at 16:49
1
\$\begingroup\$

what about this?

$('.hover_intent').hoverIntent(function(){
     var id = $(this).attr( 'id' ); 
     var selector = '#' + id.replace( 'r', 'h' );
     $( selector ).toggleClass('vis');
});

The only inconvenients i see are :

  • you need to add a hover_intent css class or your rx_y elements. This can be avoided with a regex selector like $('[id^=r]') (which means: select all elements whose id starts with an 'r'), but you should then use a more verbose id to avoid selecting everything that starts with an 'r'...
  • selecting $(this) every time the event occurs can be bad performance-wise, especially if you have a lot of elements or if the event occurs a lot of times per second

Another option is to use a data attribute on your element :

<span class="hover_intent" data-target="#h1_1">Foo</a>
<script type="text/javascript">
  $('.hover_intent').hoverIntent( function(){
    $( $(this).data('target') ).toggleClass('vis') );
  });
</script>
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.