0

First keep in mind I'm new in web design, JS and all this, please. Any suggestion will be appreciated :) I have this img icons (serviceIcon) positioned 'absolute' with their particular class (serviceHardware, ...).

<div class="servicesBox">
    <img class="serviceIcon serviceHardware" />
    <img class="serviceIcon serviceSoftware" />
    <img class="serviceIcon serviceNetwork" />
</div>

It's simple: mouseover changes opacity in not hovered items and resizes the hovered one; mouseleave animates all to their previous state; a click animates the clicked img to the corner, SHOULD remove serviceIcon class (to avoid triggering mouseover/mouseleave, right?) and moves down (in the example) the non clicked img, and adding serviceSelected class to the clicked item.

$("img.serviceIcon").click(function(){

    $("img.serviceIcon").not(this)
        .animate({
            top:'45px',
        });

    $(this).removeClass("serviceIcon")
        .animate({
            left:'150px'
        }, 300, function(){
            origLeft = $(this).css('left');
            $(this).addClass("serviceSelected");
            //alert(origLeft);
        });
});

BUT as you can see right here (http://jsfiddle.net/rcvmQ/4/), the clicked img keeps triggering mouseover/mouseleave events corresponding to serviceIcon class (already removed when clicking), and if you inspect the element you will see it doesn't have serviceIcon class anymore. What am I doing wrong here? May be all? idk.

Actually, it adds the serviceSelected class, but if you click it, never triggers the click event of this class. Weird. I've tested this in firefox and safari and both behave the same.

I have added extra validation code checking in the click event of serviceItem whether it has serviceSelected class, wich is NOT LOGICAL at all. I refuse to use it even if it works!! Thank you!

Edit: Code about mouseover/mouseleave

$("img.serviceIcon").mouseover(function(){
    $(".serviceIcon").not(this)
                        .animate({
                            opacity:'0.3'
                        }, 100);
    $(this).animate({
        width   :'25px',
        height  :'40px',
        opacity :1
    },200);
});

$("img.serviceIcon").mouseleave(function(){
$("img.serviceIcon").stop(true,true)
                        .animate({
                            width   :'20px',
                            height  :'40px',
                            opacity :'1'
                        },100);
});
  • 3
    Removing a class does not remove event handlers. Those are two independent properties. You are using the class *initially* to find those specific elements but removing the class later on does not undo any modifications you did to them (e.g. binding event handlers). You'd have to explicitly remove the event handlers: http://api.jquery.com/off/. – Felix Kling Jan 25 '13 at 17:31
  • To further what @FelixKling said - you're binding the event handlers to the element using a class selector. You later move the class from the element, but the event handlers you bound to the element remain intact - they're tied to the element, not the class. – Madbreaks Jan 25 '13 at 17:37
  • Hmm ok. Then i should ask if this is the right or best way to archieve what im trying to do. I mean, should i add the off() to the logic of this code or find a better way to do this? Because i've seen similar uses of Jquery but i haven't seen the off() method on them. I'd like to understand this very well. – user2006467 Jan 25 '13 at 17:39
  • use delegation.. it should get rid of your problems :) – wirey00 Jan 25 '13 at 17:47
  • Post the rest of your code, the stuff around mouse enter/leave – Madbreaks Jan 25 '13 at 17:47
  • Code added. But all this is about bind or unbind events. – user2006467 Jan 25 '13 at 18:11

2 Answers2

0

Unbind the mouseover event

http://jsfiddle.net/rcvmQ/5/

   $(this).off('mouseover').removeClass("serviceIcon")
            .animate({
                left:'150px'
            },300, function(){
                origLeft = $(this).css('left');
                $(this).addClass("serviceSelected");
                //alert(origLeft);
            });
sdespont
  • 13,915
  • 9
  • 56
  • 97
0

After reading about .on() and .off(), i made some changes to the code and it seems to work. I created 2 functions:

function clickIcon(){ ... }
function restoreIcons(){ ... }

Basically, they contain the code for the click event for serviceIcon and serviceSelected classes. As you showed to me, i turn off the 'click' event when i click a serviceIcon, unbinding it, and then i turned on (binded) the 'click' event for serviceSelected class handled with the function restoreIcons().

function clickIcon(){
    leftPos = $(this).css('left');
    //alert(leftPos);
    $("img.serviceIcon").not(this)
                        .animate({
                            top     :'80px',
                        }); 
        //turning off 'click' for serviceIcon   
    $(this).off('click').removeClass("serviceIcon")
                    .animate({
                        left:'300px'
                    },200, function(){
                        $(this).addClass("serviceSelected");
                                            // turning on 'click' for serviceSelected
                    $('img.serviceSelected').on('click',restoreIcons);
                    });         
}

Inside of restoreIcon function i turned off the 'click' event of serviceSelected and turned on again the 'click' event for serviceIcon (handled by clickIcon()).

function restoreIcons(){
    $(this).animate({
            left    :leftPos
        },200, function(){
            $(this).off('click')
                    .removeClass('serviceSelected')
                    .addClass('serviceIcon');
            $('img.serviceIcon').animate({
                            top:'0px'
                        },100);
            $('img.serviceIcon').on('click', clickIcon);
        });
}   

You can see the full code here (http://jsfiddle.net/rcvmQ/9/).

This works perfect, at least the first time you click each icon. After that i notice serious delay if i start to click them repeatedly, and every time gets longer. For me seems to be like time for processing the on and off, may be? The other thing i think could be is that i haven't unbinded the mouseenter/mouseleave events so may be this keeps happening all at the same time. Any sugestions?