Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Javascript Image zoom in on mouseover and zoom out on mouseout

Status
Not open for further replies.

User908

Programmer
Mar 1, 2013
6
AM
I have several thumbnails on my page which I would like to enlarge on mouseover and revert them to their initial position on mouseout. So when the user mouses over any of the aforementioned thumbnails onmouseover is called triggering MLTo function and when the mouse is out, onmouseout triggers MLFro function and reverts the image to its initial position.

This is the code that I've written, but it has several flaws!

Firstly, I've tested it in Opera,Chrome,Safari,IE and Firefox (all are the latest versions). In the first 4 browsers the script doesn't load the CPU, but in Firefox it loads the CPU up to 15%.

Secondly, sometimes the animation speeds up on mouseout.

So, how to eliminate The CPU load in Firefox and prevent the speeding of the animation on mouseout?

Thanks for any help!

P.S. English isn't my native language, so if something is unclear let me know and I'll clarify!


JavaScript:
<body style="margin:200px; background-color:#999">

<div style="width:100px; height:100px; border:1px #333 solid; position:relative"><img src="some.jpg" style="width:100px; height:100px;  position:relative" id="er" class="zoom"/></div> <br />


<div style="width:100px; height:100px; border:1px #333 solid; position:relative"><img src="some.jpg" style="width:100px; height:100px;  position:relative" id="er2"  class="zoom"/></div> <br />


<div style="width:100px; height:100px; border:1px #333 solid; position:relative"><img src="some.jpg" style="width:100px; height:100px;  position:relative " id="er3" class="zoom"/></div> <br />


<script type="text/javascript">

window.onload = function () {

    getIDWHMLMT();

    }

var getElements = document.getElementsByClassName("zoom");

var isIE = /MSIE/gi;
var regExpIEV = /MSIE \d+\.\d+/gi;
var regExpIEV2 = /\d+\.\d+/gi;

var IDWHMLMTA = [];
var IEVArray = [];  

function getIDWHMLMT()  {

    if(getElements.length > 0) {

    for(var i=0; i<getElements.length; i++) {

    getID = document.getElementById(getElements[i].id);

    defSize = navigator.userAgent.match(isIE) ? getID.currentStyle : window.getComputedStyle(getID);

    defImgSizeWidth = defSize.getPropertyValue('width');
        defImgSizeHeight = defSize.getPropertyValue('height');

        defImgSizeWidth = parseInt(defImgSizeWidth);
            defImgSizeHeight = parseInt(defImgSizeHeight);


    defImgSizeWidthDifFDec = defImgSizeWidth - defImgSizeWidthDif;
        defImgSizeHeightDifFDec = defImgSizeHeight - defImgSizeHeightDif;

    defImgSizeWidthDifFInc = defImgSizeWidth + defImgSizeWidthDif;
        defImgSizeHeightDifFInc = defImgSizeHeight + defImgSizeHeightDif;  


    defImgSizeML = parseInt(getID.style.marginLeft);
        defImgSizeMT = parseInt(getID.style.marginTop);


    defImgSizeML = defImgSizeML==null || isNaN(defImgSizeML) ? 0 : defImgSizeML;
        defImgSizeMT = defImgSizeMT==null || isNaN(defImgSizeMT) ? 0 : defImgSizeMT;

    defzIndex = defSize.getPropertyValue('z-Index');

IDWHMLMTA.push({id:getID.id, width:defImgSizeWidth, height:defImgSizeHeight, marginL:defImgSizeML, marginT:defImgSizeMT, ZIndex:defzIndex, WD:defImgSizeWidthDifFDec, HD:defImgSizeHeightDifFDec, WI:defImgSizeWidthDifFInc, HI:defImgSizeHeightDifFInc});

        }

        }

    }



function defIEVersion() {

    if(navigator.userAgent.match(isIE)) {

        IEversionDef = navigator.userAgent.match(regExpIEV) + "";
            IEversionDef2 = IEversionDef.match(regExpIEV2);
                IEversionDef3 = IEversionDef.replace(IEversionDef,IEversionDef2);
                    IEversionDef3 = parseInt(IEversionDef3);

                            IEVArray.push(IEversionDef3);


    }
    }

        defIEVersion();


function defChild(event) {

    evt = event || window.event;

    evtRel = evt.toElement || evt.relatedTarget;

    while(evtRel && evtRel.parentNode && evtRel.parentNode != window) {

    if (evtRel.parentNode == this || evtRel == this) {

        if(evtRel.preventDefault) evtRel.preventDefault();
        return false;

    }

    evtRel = evtRel.parentNode;

    }   




    }


var CheckLast = [];

var IncOrDec = "inc";

    var defImgSizeWidthDif = 100; 
    var defImgSizeHeightDif = 100;

    var sD = 30;

    var HMInc = 5;

    var IncTimes = HMInc * 2;

    var TimerTo;
    var TimerFro;

    var stepsInc = 0;
    var stepsInc2 = 0;



    for(var v=0;v<getElements.length;v++){

        if(navigator.userAgent.match(isIE) && IEVArray[IEVArray.length-1]<10) {

    getElements[v].attachEvent('mouseover',function(event) {

        IDChange = this;

            MLTo();     },false);



    getElements[v].attachEvent('mouseout',function(event) {

        defChild(event);

        IDChange2 = this;

            MLFro(event);   

        },false);

        }

        else {

        getElements[v].addEventListener('mouseover',function(event) {

        IDChange = this;

            MLTo();     },false);



    getElements[v].addEventListener('mouseout',function(event) {

        defChild(event);

        IDChange2 = this;

            MLFro(event);   

        },false);


        }

        }


function MLTo() { 

    if(CheckLast.length>0) {

        if(IDChange.id === CheckLast[CheckLast.length-1].id && IDChange.SF != "Started") {

        clearInterval(TimerFro);
        stepsInc2 = 0;  

        }

    }

    for(var y=0;y<getElements.length;y++){

        getElements[y].style.zIndex = defzIndex === 'auto' ? 0 : defzIndex;

        }

    IDChange.style.position = "absolute";

    IDChange.addEventListener('mouseout',function(event) {

        evt = event || window.event;

    if(evt.type=='mouseout') {

        clearInterval(TimerTo);
        stepsInc = 0;       
        }
        },false);

    defSize = navigator.userAgent.match(isIE) ? IDChange.currentStyle : window.getComputedStyle(IDChange);

    defImgSizeWidth = defSize.getPropertyValue('width');
        defImgSizeHeight = defSize.getPropertyValue('height');

    defImgSizeWidth = parseInt(defImgSizeWidth);
        defImgSizeHeight = parseInt(defImgSizeHeight);

    defImgSizeML = parseInt(IDChange.style.marginLeft);
        defImgSizeMT = parseInt(IDChange.style.marginTop);


    defImgSizeML = defImgSizeML==null || isNaN(defImgSizeML) ? 0 : defImgSizeML;
        defImgSizeMT = defImgSizeMT==null || isNaN(defImgSizeMT) ? 0 : defImgSizeMT;

    defzIndex = defSize.getPropertyValue('z-Index');



    IDChange.style.zIndex = 100;

    stepsInc+=0.1;

    TimerTo = setInterval(function() {


    if(IncOrDec === "dec") {    

    for(var i=0; i<IDWHMLMTA.length; i++) {

    if(IDChange.id == IDWHMLMTA[i].id) {

        if((defImgSizeWidth>IDWHMLMTA[i].WD && defImgSizeHeight>IDWHMLMTA[i].HD) && (defImgSizeML<defImgSizeWidthDif && defImgSizeMT<defImgSizeHeightDif)) {

            defImgSizeWidth = defImgSizeWidth - IncTimes;
            IDChange.style.width = defImgSizeWidth + "px";

            defImgSizeHeight = defImgSizeHeight - IncTimes;
            IDChange.style.height = defImgSizeHeight + "px";

            defImgSizeML = defImgSizeML + HMInc;
            IDChange.style.marginLeft = defImgSizeML + "px";

            defImgSizeMT = defImgSizeMT + HMInc;
            IDChange.style.marginTop = defImgSizeMT + "px";

        }
        else {

    clearInterval(TimerTo);
    stepsInc = 0;   
        }   

        }
            }

    }

if(IncOrDec === "inc") {    

    for(var i=0; i<IDWHMLMTA.length; i++) {

    if(IDChange.id == IDWHMLMTA[i].id) {

        if((defImgSizeWidth<IDWHMLMTA[i].WI && defImgSizeHeight<IDWHMLMTA[i].HI) && (defImgSizeML<defImgSizeWidthDif && defImgSizeMT<defImgSizeHeightDif)) {

            defImgSizeWidth = defImgSizeWidth + IncTimes;
            IDChange.style.width = defImgSizeWidth + "px";

            defImgSizeHeight = defImgSizeHeight + IncTimes;
            IDChange.style.height = defImgSizeHeight + "px";

            defImgSizeML = defImgSizeML - HMInc;
            IDChange.style.marginLeft = defImgSizeML + "px";

            defImgSizeMT = defImgSizeMT - HMInc;
            IDChange.style.marginTop = defImgSizeMT + "px";

        }
        else {

    clearInterval(TimerTo);
    stepsInc = 0;

        }   

        }
            }


    }

    },sD+stepsInc);




    }



function MLFro(event) {

    clearInterval(TimerFro);

    CheckLast.push({id:IDChange2.id,SF:"Started"});

    stepsInc2+=0.1;

    TimerFro = setInterval(function() {

    for(var w=0;w<CheckLast.length;w++){

        if(CheckLast[w].SF === "Started") {

    IDChange2 = document.getElementById(CheckLast[w].id);

    IDChange2.style.position = "relative";

    defSize2 = navigator.userAgent.match(isIE) ? IDChange2.currentStyle : window.getComputedStyle(IDChange2);

    defImgSizeWidth2 = defSize2.getPropertyValue('width');
        defImgSizeHeight2 = defSize2.getPropertyValue('height');

    defImgSizeWidth2 = parseInt(defImgSizeWidth2);
        defImgSizeHeight2 = parseInt(defImgSizeHeight2);


    defImgSizeML2 = parseInt(IDChange2.style.marginLeft);
        defImgSizeMT2 = parseInt(IDChange2.style.marginTop);

    defImgSizeML2 = defImgSizeML2==null || isNaN(defImgSizeML2) ? 0 : defImgSizeML2;
        defImgSizeMT2 = defImgSizeMT2==null || isNaN(defImgSizeMT2) ? 0 : defImgSizeMT2;    

    if(IncOrDec === "dec") {    

    for(var i=0; i<IDWHMLMTA.length; i++) {

    if(IDChange2.id == IDWHMLMTA[i].id) {

        if((defImgSizeWidth2<IDWHMLMTA[i].width && defImgSizeHeight2<IDWHMLMTA[i].height) && (defImgSizeML2>IDWHMLMTA[i].marginL && defImgSizeMT2>IDWHMLMTA[i].marginT)) { 

            defImgSizeWidth2 = defImgSizeWidth2 + IncTimes;
            IDChange2.style.width = defImgSizeWidth2 + "px";

            defImgSizeHeight2 = defImgSizeHeight2 + IncTimes;
            IDChange2.style.height = defImgSizeHeight2 + "px";

            defImgSizeML2 = defImgSizeML2 - HMInc;
            IDChange2.style.marginLeft = defImgSizeML2 + "px";

            defImgSizeMT2 = defImgSizeMT2 - HMInc;
            IDChange2.style.marginTop = defImgSizeMT2 + "px";

        }
        else {

                CheckLast[w].SF = "Finished";
            //clearInterval(TimerFro);
            CheckLast.slice(w);

        stepsInc2 = 0;

    IDChange2.style.zIndex = IDWHMLMTA[i].ZIndex;



        }   

        }
            }

    }

if(IncOrDec === "inc") {    

    for(var i=0; i<IDWHMLMTA.length; i++) {

    if(IDChange2.id == IDWHMLMTA[i].id) {

        if((defImgSizeWidth2>IDWHMLMTA[i].width && defImgSizeHeight2>IDWHMLMTA[i].height) && (defImgSizeML2<IDWHMLMTA[i].marginL && defImgSizeMT2<IDWHMLMTA[i].marginT)) { 

            defImgSizeWidth2 = defImgSizeWidth2 - IncTimes;
            IDChange2.style.width = defImgSizeWidth2 + "px";

            defImgSizeHeight2 = defImgSizeHeight2 - IncTimes;
            IDChange2.style.height = defImgSizeHeight2 + "px";

            defImgSizeML2 = defImgSizeML2 + HMInc;
            IDChange2.style.marginLeft = defImgSizeML2 + "px";

            defImgSizeMT2 = defImgSizeMT2 + HMInc;
            IDChange2.style.marginTop = defImgSizeMT2 + "px";

        }
        else {

                CheckLast[w].SF = "Finished";
            //clearInterval(TimerFro);
            CheckLast.slice(w);

        stepsInc2 = 0;

    IDChange2.style.zIndex = IDWHMLMTA[i].ZIndex;

    }   

        }
            }

    }
        }
    }           
    },sD+stepsInc2);



}
</script>


</body>
 
it seems that there are some business rules potentially missing.

for example if you leave the image in the flow, then there is a problem with the content reflowing in an inappropriate manner.
if you rescale the image outside of the flow, then there is the potential that as the mouse moves around it can also mouseover an underlying image.

I think my preferred method would be:

1. listen for mouseover events on all images with a class of zoom
2. on mouseover
a. turn off all listeners on the zoom class
b. clone the image
c. insert the image absolutely in the same location, floating above the flow
d. zoom the image the desired amount, using the top left as the origin. i would not animate the zoom
e. attach a mouse out even to the zoomed image
3. on mouseout,
a. remove the cloned image from the DOM,
b. turn on the listeners for the zoom class

I would _definitely_ insert a delay on mouseover too. it would be so annoying for images to be zooming all the time otherwise.

using jQuery, this would be done in a few lines. I guess with native javascript it would not be that long either.
you could leave the listeners in place and instead keep a boolean test of whether you are in a mouseover mode.

I cannot see anything obvious in your code that would cause processor issues. Typically the processor load would be in downscaling a large image for display in the flow. However as your code lacks commenting I have not spent a great deal of time trying to decipher it. I appreciate that the above is not an answer to your question, but hope it may be of use nonetheless.

 
Thanks jpadie for the reply.

I've already figured out how to solve the bugs in my script.

And you're right. I used large scale images (i.e. 1000x1000), which were scaled to 100x100 that caused the CPU load on Firefox.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top