1

I am trying to get a set of page-specific icons to fade in when every their corresponding menu items are hovered over. I found few ways to do it, but I'm not too proud of them.

In plain english, you are on a page, so "us" – it has it's page-icon by default - and so, lets say a class of - .current-page on the menu item - and .active-page-icon on the current page's icon img. "When a menu item is hovered, assuming it's not the current page's menu item, simultaniously fade out the the current image and fade in the image associated with the menu item being hovered. On mouse out, fade out that image and fade back in the default image."

Any advice on how I could get this function smaller and more modular? I'm not used to working with things that are so far apart in the DOM and I would usually just use CSS for things like this. Should I be using some data attributes to connect these menu items with their images?

Here is the core parts of the code. I've simplified it for example purposes.

HTML

<div class="container splash">
  <div class="inner-w">

    <ul class="menu">
      <li><a href="#" id="us-hover" class="current-page">Us</a></li>
      <li><a href="#" id="work-hover">Work</a></li>
      <li><a href="#" id="books-hover">Books</a></li>
    </ul>

  </div>
</div>

<div class="page-icon">
  random place far away in the DOM
   <div class="image-w">

    <img class="us-image active-page-icon" src="http://placehold.it/400x400&text=Us" alt="" />
    <img class="work-image hide" src="http://placehold.it/400x400&text=Work" alt="" />
    <img class="books-image hide" src="http://placehold.it/400x400&text=Books" alt="" />

  </div>
</div>

CSS

.hide {
  opacity: 0;
}

jQuery

$("#us-hover").hover(
  function() {
    $(".active-page-icon").addClass("hide"),
    $(".us-image").removeClass("hide");
  }, function() {
    $(".us-image").addClass("hide");
    $(".active-page-icon").removeClass("hide");
  }
);

$("#work-hover").hover(
  function() {
    $(".active-page-icon").addClass("hide"),
    $(".work-image").removeClass("hide");
  }, function() {
    $(".work-image").addClass("hide");
    $(".active-page-icon").removeClass("hide");
  }
);

$("#books-hover").hover(
  function() {
    $(".active-page-icon").addClass("hide"),
    $(".books-image").removeClass("hide");
  }, function() {
    $(".books-image").addClass("hide");
    $(".active-page-icon").removeClass("hide");
  }
);

This *works ... but What if there were 100 items or something. I have a feeling that there is a super slick way of doing this. Please enlighten me. What is the best way to go about this? Also, is .hover() cool? I see a lot of hover styles out there - and no real evidence of which is preferred, should I be using .on() ?

Thank you for your time.

Oh, and here is a PEN

sheriffderek
  • 8,848
  • 6
  • 43
  • 70
  • I have seen building a jquery framework and then hooking everything together like in this post: http://stackoverflow.com/questions/4458970/cascading-drop-downs-in-mvc-3-razor-view towards the bottem – Zach M. Feb 11 '14 at 21:25
  • The title of my post is pretty terrible, if anyone thinks of a better one, let me know. – sheriffderek Feb 11 '14 at 21:38

1 Answers1

3

You can store what needs to be displayed along with anchor in data-* custom attributes

HTML

<ul class="menu">
  <li><a href="#" id="us-hover" data-display-item='.us-image' >Us</a></li>
  <li><a href="#" id="work-hover" data-display-item='.work-image' >Work</a></li>
  <li><a href="#" id="books-hover" data-display-item='.books-image' >Books</a></li>
</ul>

jQuery

$("#menu li a").hover(function() {
    $(".active-page-icon").addClass("hide"),
    $($(this).data('display-item')).removeClass("hide");
}, function() {
    $($(this).data('display-item')).addClass("hide");
    $(".active-page-icon").removeClass("hide");
});
Satpal
  • 132,252
  • 13
  • 159
  • 168
  • Wow. This is exactly what I was hoping for. Thank you very much. Can't wait to read more about this. Are there any caveats you know of? Support looks pretty solid: http://caniuse.com/#feat=dataset – sheriffderek Feb 11 '14 at 21:37
  • 1
    @sheriffderek, I have use combination of http://api.jquery.com/data/ and HTML5 custom data attributes. http://caniuse.com/dataset, Cheers all browser support it – Satpal Feb 11 '14 at 21:40