Link to home
Start Free TrialLog in
Avatar of Pdesignz
PdesignzFlag for United States of America

asked on

How to add a hover state to an existing jquery function script

I have a script that has an on state and off state that are represented by images. What I would like to have is a 3rd image  state that is displayed when the user hovers, to show that the images are clickable, currently there is a div that changes content depending on the image that is selected.

Here is the current script

<script type="text/javascript">
            var preIndex = 0;
$("#divNavigate .imgNav").click(function() {
  var ix = $("#divNavigate .imgNav").index($(this));
  console.log(ix);
  $("#divContent .tab:eq('" + preIndex + "')").hide();
  $("#divContent .tab:eq('" + ix + "')").show();
  $("#divNavigate .imgNav:eq("+preIndex+")").attr("src","images/tab_"+preIndex+"_off.png");
$("#divNavigate .imgNav:eq("+ix+")").attr("src","images/tab_"+ix+"_on.png");
  preIndex = ix;
});

$("#divNavigate .imgNav:eq(0)").click();

        
        </script>

Open in new window

Avatar of zephyr_hex (Megan)
zephyr_hex (Megan)
Flag of United States of America image

I'm a little unclear as to whether you want a new / different result on hover, or whether you want the same result on hover a click.

If you want the same result, just include the hover event on your existing code:

$("#divNavigate .imgNav").on('click hover', function() {

Open in new window


If you want something different to happen on hover, then just add a new function that triggers on that event:

$("#divNavigate .imgNav").on('hover',function() {

Open in new window

Avatar of Pdesignz

ASKER

I want the same thing to happen, but what I want  is to show a hover state image so the user knows that the images are clickable or show some interactivity on the images...I am currently creating a hover state image that I can use...so nothing would change just that the images would show an alternate image on hover...I am a newbie or low skilled on jquery and not sure how to do this.  thanks
just do this:

var preImg;
$( "#divNavigate .imgNav" ).hover(
  function() { // hover in
    // change img "tab_x_off.png"/"tab_x_on.png" to "tab_x_hov.png"
    preImg = $(this).attr("src");
    $(this).attr("src", preImg.replace("_on.","_hov."),replace("_off.","_hov."));
  }, function() { // hove out
    // restore image somehow :)
    $(this).attr("src", preImg);
  }
);

Open in new window

Where in the current script would I add this new code or script

var preIndex = 0;
$("#divNavigate .imgNav").click(function() {
  var ix = $("#divNavigate .imgNav").index($(this));
  console.log(ix);
  $("#divContent .tab:eq('" + preIndex + "')").hide();
  $("#divContent .tab:eq('" + ix + "')").show();
  $("#divNavigate .imgNav:eq("+preIndex+")").attr("src","images/tab_"+preIndex+"_off.png");
$("#divNavigate .imgNav:eq("+ix+")").attr("src","images/tab_"+ix+"_on.png");
  preIndex = ix;
});

$("#divNavigate .imgNav:eq(0)").click();

Open in new window


Thanks
on top, after line1
after line 11
on bottom :)

anywhere you like...
There's no need to add another function.  Repeated / duplicated code is bad for maintainability and goes against good coding practices.  Just add the mouseover event (I got that wrong earlier and mixed up my css "hover" with the jQuery "mouseover" event) to your existing function, and then do your hover logic inside the existing function by checking for which event triggered the function.

$("#divNavigate .imgNav").on('click mouseover', function(e) {
//this will tell you what event triggered
	if(e.type === 'click') {
		var ix = $("#divNavigate .imgNav").index($(this));
		console.log(ix);
		$("#divContent .tab:eq('" + preIndex + "')").hide();
		$("#divContent .tab:eq('" + ix + "')").show();
		$("#divNavigate .imgNav:eq("+preIndex+")").attr("src","images/tab_"+preIndex+"_off.png");
		$("#divNavigate .imgNav:eq("+ix+")").attr("src","images/tab_"+ix+"_on.png");
		  preIndex = ix;
	}
	else if(e.type === 'mouseover') {
		//do something
	}
});

Open in new window


You might need to move the inspection for e.type to another part of that function, depending on what exactly needs to happen differently when it's a mouseover versus a click.  But the general idea is to have one function that fires on mouseover OR on click, and then look at e.type to see what event happened.
If I replace existing script with this, will this work or do I need to add to script. Currently I have 2 did, one for the images and one for content. There is a certain image and content loaded by default, when you click the image, the content corresponding to that div is then displayed and the image changes from an off state to a on state or selected state. I would like to have a hover state image that shows a highlight of a hover state that the images are clickable...so go from off to hover to on if clicked, if not go from off to hover then back to off state. Thanks
nope :)

 above function (combining click and mouseover) is bad for maintainability... :)

combining different events in one handler and then checking type and then using different codes in one handler is not something I porefer and never do that :)

also, we need mouseout event as well to restore the image...

maybe you save 1/23656 - 1/63000 = 2.64E-5 (0.0264 milliseconds)

(ie if will run 24000 times this way and 63000 times that way (? not sure though) per second)
and nobody can call these functions say more than 10 times per second... meaning, nobody will ever never notice anything!

but I never wrote such code to save such tiny speed gain :)

like: does a fly on a truck slows it down?
- yes, because of gravity, air friction etc, but how much? will you ever notice such thing?

like: dont use any modern language and write your code in machine language/assembly, it will be much faster :)

like: dont use "a=b+c+d+e" but use stringbuilder! (I made a test and to compare just  to show the folks and run it 100K times, and simple addition won the race :)

have a look at this, somebody made comparisons here

Multiple jquery events
https://jsperf.com/multiple-jquery-events
Thanks for clarifying...I have added the additional script to the existing script as you recommended and suggested, per your instructions I added to the bottom of the existing script. I also wanted to clarify that since we already have the existing images of tab_x_on and tab_x_off, I would just need to add an image of tab_x_hov, is that correct?

<script type="text/javascript">
            var preIndex = 0;
                $("#divNavigate .imgNav").click(function() {
            var ix = $("#divNavigate .imgNav").index($(this));
            console.log(ix);
                $("#divContent .tab:eq('" + preIndex + "')").hide();
                $("#divContent .tab:eq('" + ix + "')").show();
                $("#divNavigate .imgNav:eq("+preIndex+")").attr("src","images/tab_"+preIndex+"_off.png");
                $("#divNavigate .imgNav:eq("+ix+")").attr("src","images/tab_"+ix+"_on.png");
            preIndex = ix;
                });
            var preImg;
                $( "#divNavigate .imgNav" ).hover(
            function() { // hover in
            // change img "tab_x_off.png"/"tab_x_on.png" to "tab_x_hov.png"
            preImg = $(this).attr("src");
                $(this).attr("src", preImg.replace("_on.","_hov."),replace("_off.","_hov."));
            }, function() { // hove out
            // restore image somehow :)
                $(this).attr("src", preImg);
            }
            );            
            
                $("#divNavigate .imgNav:eq(0)").click();
        </script>

Open in new window


Thanks!
ASKER CERTIFIED SOLUTION
Avatar of HainKurt
HainKurt
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
for anyone to see what we are trying to do...
the site is here:

http://www.dev.pdesignz.com/web-design-development.html
Works great!!! Thanks :)
Thank you for your time, patience, and much needed assistance. Highly Recommended!!
I see you implemented all the things that I suggested in your previous question :)
looks clean and nice, with all paddings and alignments...
Yes, Thanks...I think it came out really nice and works great! I'll be sure to look for you on future projects or issues I might need assistance with. Thanks!!
Would it be possible to add a left and right arrow and upon clicking on the arrows the content and images would change...I am wondering as when I view this on a smartphone in landscape view there is scrolling between the images and the content that I am not wild for...therefore if we images that will scroll the images and content it would help on the landscape view...Thanks!
something like this may work...

https://jsfiddle.net/2u7tpp7q/

html
<div id="divNavigate">
  <img id="imgLeft" class="imgNavigators" src="left.png">
  <img class="imgNav" src="images/tab_0_off.png">
  <img class="imgNav" src="images/tab_1_off.png">
  <img class="imgNav" src="images/tab_2_off.png">
  <img class="imgNav" src="images/tab_3_off.png">
  <img class="imgNav" src="images/tab_4_off.png">
  <img class="imgNav" src="images/tab_5_off.png">
  <img id="imgRight" class="imgNavigators" src="left.png">
</div>

Open in new window


js
$("#imgLeft").on("click", function() {
  if (preIndex == 0) return;
  $("#divNavigate .imgNav:eq(" + (preIndex - 1) + ")").click();
});

$("#imgRight").on("click", function() {
  if (preIndex == $("#divNavigate .imgNav").count) return;
  $("#divNavigate .imgNav:eq(" + (preIndex + 1) + ")").click();
});

Open in new window


css
.imgNavigators {
  width: 60px;
  height: 60px;
  border: 1px dotted red;
  margin: 10px;
}

Open in new window

Can I call the arrows anything or do they need to named something specific as long as contained in specific div that is ok. Thanks
can call anything, as long as js and css will match to those...

check carefully the code above, @ ID: 42298927, see how I used id/class/css/js...
I will give it a try, thanks. On a side note, I am wondering if we should use a left and right arrow image or if better we use a glyphicon and call the class of the left and right arrows instead, what would you recommend?
use glyphicon...

<span id="imgLeft" class="glyphicons glyphicons-arrow-left"></span>
<span id="imgRight" class="glyphicons glyphicons-arrow-right"></span>

Open in new window


or

<span id="imgLeft" class="glyphicons glyphicons-circle-arrow-left"></span>
<span id="imgRight" class="glyphicons glyphicons-circle-arrow-right"></span>

Open in new window


http://glyphicons.com/

no other change is required other than use above htmls instead of images...
Would this be correct with the addition of the function and I can replace with image or glyphicon per your example

<script type="text/javascript">
            var preIndex = 0;
            var preImg;
                $("#divNavigate .imgNav").click(function() {
            var ix = $("#divNavigate .imgNav").index($(this));
            console.log(ix);
            $("#divContent .tab:eq('" + preIndex + "')").hide();
            $("#divContent .tab:eq('" + ix + "')").show();
            $("#divNavigate .imgNav:eq(" + preIndex + ")").attr("src", "images/tab_" + preIndex + "_off.png");
            $("#divNavigate .imgNav:eq(" + ix + ")").attr("src", "images/tab_" + ix + "_on.png");
            preIndex = ix;
            preImg = $(this).attr("src");
            });
            $("#divNavigate .imgNav").hover(
            function() { // hover in
            // change img "tab_x_off.png"/"tab_x_on.png" to "tab_x_hov.png"
            preImg = $(this).attr("src");
            console.log(preImg);
            $(this).attr("src", preImg.replace("_on.", "_hov.").replace("_off.", "_hov."));
            console.log("hover in - " + preImg + " -> " + $(this).attr("src"));
            },
            function() { // hover out
            // restore image somehow :)
            console.log("hover out - "+ $(this).attr("src") + " -> " + preImg);
            $(this).attr("src", preImg);
            }
            );
            $("#imgLeft").on("click", function() {
            if (preIndex == 0) return;
            $("#divNavigate .imgNav:eq(" + (preIndex - 1) + ")").click();
            });
            $("#imgRight").on("click", function() {
            if (preIndex == $("#divNavigate .imgNav").count) return;
            $("#divNavigate .imgNav:eq(" + (preIndex + 1) + ")").click();
            });
            $("#divNavigate .imgNav:eq(0)").click();
        </script>

Open in new window

looks good, just try it
I was looking at the code you sent and all looks good, but I believe the arrows are in the wrong place, currently they are in the navigate section and I was thinking of having them in the content section...this way if on a smartphone or tablet and are viewing the content, you can scroll through the content using the arrows...clicking the arrows will cycle through the content and will also cycle through the icons, the icon will be set to active state depending on the content that is cycled through or being displayed...here is a sample of where I was thinking of having the images

User generated image
add "navArrows" class to the icons and use


.navArrows {
    font-size: 2em;
    cursor: pointer;
    border: 2px dotted #0575e6;
    border-radius: 50%;
    padding: 10px;
    color: #0575e6;
}

Open in new window


User generated image
I am looking to have the arrows placed in the content section and not in the navigation section where the icons are, as this will allow user to scroll content from within the content section and not have to scroll back up to the navigation section, this will cut down on the scrolling between the two sections if browsing via a tablet or smartphone in a landscape view. Thanks

 User generated image
maybe something like this:

<div class="row">
<span id="imgLeft" class="col-md-1 glyphicon glyphicon-chevron-left" style="float: left;"></span>

<div class="col-md-10">
<div id="divContent">
  ...
</div>
</div>

<span id="imgRight" class="col-md-1 glyphicon glyphicon-chevron-right" style="float: right;"></span>
</div>

Open in new window

I added the new content to the page, but nothing happens when I click the arrows and content doesn't change.
Had to clear cache...working now...now I just need resize the arrows and place in vertical center rather than top...Thanks

Let me know if would like me to repost, so you can get rewarded...Thanks!
use this code:

<div class="row">
  <div class="col-md-1 text-center"><span id="imgLeft" class="glyphicon glyphicon-chevron-left"></span></div>

    <div class="col-md-10">

<div id="divContent">
...
</div>

    </div>

  <div class="col-md-1 text-center"><span id="imgRight" class="glyphicon glyphicon-chevron-right"></span></div>
</div>

Open in new window


you may remove "float:left" and "float:right" from imgLeft/imgRight classes...