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\$

3 Answers 3

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\$
2
  • \$\begingroup\$ ha ! i see we had the same idea at the same time :D \$\endgroup\$
    – m_x
    Commented May 31, 2013 at 16:57
  • \$\begingroup\$ Thanks very much! Worked beautifully. And I learned a great deal from it. \$\endgroup\$ Commented Jun 1, 2013 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\$
3
  • \$\begingroup\$ Thank you Andrew - In the above basic function, how do I grab the unique values of n1 and n2? \$\endgroup\$ Commented May 31, 2013 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
    Commented May 31, 2013 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\$ Commented May 31, 2013 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 and acknowledge you have read our privacy policy.

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