Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple selectors or multiple functions - any efficiency gains?

I'm wondering if its possible to make the following code more concise:

 $('#americasTrigger').hover(
  function () {
          $('#americasImg').fadeIn()
      },
  function(){
          $('#americasImg').fadeOut()
  }
  );

$('#europeTrigger').hover(
  function () {
      $('#europeImg').fadeIn();
  },
  function(){
      $('#europeImg').fadeOut();
  }
  );    

$('#middleEastTrigger').hover(
  function () {
      $('#middleEastImg').fadeIn();
  },
  function(){
      $('#middleEastImg').fadeOut();
  }
  );    

//More etc

The country name stays the same for each, with 'Trigger' or 'Img' added to the end. There's a lot of repetition here which indicates to me I'm not going about the this best way.

I had thoughts around:

  • Crearting a case scenario, or
  • Somehow getting the selector being used for a selection, making it a string, splitting it's name to capture the country in use and applying that to the nested fadeIn/Out function with 'Img' on the end.

Is this possible or am I being too fancy?

Edit 1: Thanks verymuch for all the responses, apologies for not posting the html, i've put this bellow. In short I'm using image maps over a bg image (of earth) as the hover triggers for fading in/out my absolutely positioned on-hover images.

<div class="mapTub"> 

  <img src="images/transparentPixel.png" class="mapCover" usemap="#worldMap" width="524px" height="273px"/>

  <map name="worldMap" id="worldMap">
    <area id="americasTrigger" shape="poly" coords="1,2,3" href="#americas" />
    <area id="europeTrigger" shape="poly" coords="4,5,6" href="#europe" />
    <area id="middleEastTrigger" shape="poly" coords="7,8,9" href="#middleEast" />
  </map>

<img src="images/International_americas_dark.png" class="americas" id="americasImg" />
<img src="images/International_europe_dark.png" class="europe" id="europeImg" />
<img src="images/International_middleEast_dark.png" class="middleEast" id="middleEastImg"  />

</div>

Reigel's answer seems like the way to go here, ill try it out report back, further comments welcome! :)

like image 310
demolish Avatar asked Jul 30 '10 06:07

demolish


People also ask

What are multiple selectors?

Description: Selects the combined results of all the specified selectors.

How do you select multiple selectors?

To select multiple elements of an html page using multiple elements selector, we pass the element names inside parenthesis, in double quotes, separated by commas. For example: $(“div, p, h2”) this will select all the div, p and h2 elements of a page.

What are selectors in Javascript?

Selectors are used to "find" (select) HTML elements based on their tag name, id, classes, types, attributes, values of attributes and much more.


2 Answers

Me, without knowledge of the html, suggest this...

$('#americasTrigger, #europeTrigger, #middleEastTrigger').hover(
    function () {
        var id = this.id;
        $('#'+id.replace('Trigger', 'Img')).fadeIn();
        //$('#'+id.slice('0',id.indexOf('Trigger'))+'Img').fadeIn();
    },
    function(){
        var id = this.id;
        $('#'+id.replace('Trigger', 'Img')).fadeOut();
        //$('#'+id.slice('0',id.indexOf('Trigger'))+'Img').fadeOut();
    }
);

You can also use .replace() as suggested by Anurag in the comment below...


id ='europeTrigger';
alert(id.slice('0',id.indexOf('Trigger'))); // alerts 'europe'
// '#'+id.slice('0',id.indexOf('Trigger'))+'Img' is '#europeImg'

demo

like image 108
Reigel Avatar answered Sep 27 '22 19:09

Reigel


Since it looks like you are accessing only unique ids, your best choice is to use a lookup table IMO.

var lookmeup = [  [$('#americasTrigger'), $('#americasImg')],
                  [$('#europeTrigger'), $('#europeImg')],
                  [$('#middleEastTrigger'), $('#middleEastImg')]
               ];

$.each(lookmeup, function(index, element){
    element[0].hover(function(){
      element[1].fadeIn();
    }, function(){ 
      element[1].fadeOut();
    });
});

DRY! all done!

Another way to do it in a more efficient manner would be to use event delegation.

If all of your hover elements have the same TAG, this approach could be useful:

$(document.body).delegate('div', 'mouseenter', function(e){
     $('#' + e.target.id.replace(/Trigger/, 'Img')).fadeIn();
});

$(document.body).delegate('div', 'mouseleave', function(e){
     $('#' + e.target.id.replace(/Trigger/, 'Img')).fadeOut();
});

Assuming that all your "hoverable" elements were DIVs. You still should give those elements a classname so that only those specific elements are targeted.

It makes a lot of sense to confine the root element for delegate(). Here I use document.body which would .live() do. The great thing about .delegate() is, that if your hover elements share one parent node, you can apply delegate() on that node. In that manner you reduce the number of event handlers bound

(2 instead of 6).

like image 27
jAndy Avatar answered Sep 27 '22 18:09

jAndy