Home >Web Front-end >JS Tutorial >jQuery: mouseenter event and mouseleave event cause flickering problem

jQuery: mouseenter event and mouseleave event cause flickering problem

黄舟
黄舟Original
2017-06-28 10:11:033360browse

Hello everyone. Today I am making a jquery plug-in for image magnifier. It is similar to the magnifying glass for product pictures on JD.com.

I found that after I bound mouseenter and mouseleave to the image object, when the mouse moves on the image, mouseenter and mouseleave will be triggered at the same time, causing flickering. But I don't expect mouseenter and mouseleave to be called repeatedly, or even at the same time. How to solve it? I have tried several methods online but to no avail.

Thank you all.

$.fn.magnify = function() {
    //var glassBox = options.glassBox || {};
    //var detailBox = options.detailBox || {};

    var glassBox = $(&#39;<span></span>&#39;);

    glassBox.css({
        "width": this.width() / 2 + &#39;px&#39;,
        "height": this.height() /2 + &#39;px&#39;,
        "background-color": &#39;grey&#39;,
        "position": "absolute",
        "left" : &#39;0px&#39;,
        "top": &#39;0px&#39;,
        &#39;opacity&#39;: &#39;0.2&#39;,
        &#39;display&#39;: &#39;none&#39;,
        &#39;border&#39;: &#39;1px solid blue&#39;,
        &#39;z-index&#39;: 10

    });

    $(this).after(glassBox);
    //glassBox.hide();

    var detailBox = $(&#39;<div></div>&#39;);
    var detailImage = $(&#39;<img></img>&#39;);
    
    detailBox.css({
        "width": this.width(),
        "height": this.height(),
        "display": &#39;none&#39;,
        "position": &#39;relative&#39;,
        "overflow": &#39;hidden&#39;
        //"background-color": &#39;lime&#39;
    });
    detailImage.css({
        "position": &#39;absolute&#39;
    });
    detailImage.attr("src", this.attr("src"));
    detailBox.append(detailImage);
    this.after(detailBox);


    this.mouseenter(function(event){
        //event.stopPropagation();
        glassBox.get(0).style.display = &#39;block&#39;;
        detailBox.get(0).style.display = &#39;block&#39;;
        
        

    });
    this.mouseleave(function(event){    
        //event.stopPropagation();
        if (event.relatedTarget !== "span") {
            glassBox.get(0).style.display = &#39;none&#39;;
        detailBox.get(0).style.display = &#39;none&#39;;
        }
        
    });

    this.mousemove(function(event) {
        /* Act on the event */
        var x = event.pageX - this.offsetLeft - glassBox.width() / 2;
        var y = event.pageY - this.offsetTop - glassBox.height() /2;
        if (x < 0 ) {
            x = 0;
        } else if ( x > this.offsetWidth - glassBox.width()) {
            x = this.offsetWidth - glassBox.width();
        }
        if (y < 0) {
            y = 0;
        } else if (y > this.offsetHeight - glassBox.height()) {
            y = this.offsetHeight - glassBox.height();
        }
        glassBox.css({
            left: x + &#39;px&#39;,
            top:  y + &#39;px&#39;
        });

        detailImage.css({
        "left": -3.5 * (event.pageX - this.offsetLeft) + &#39;px&#39;,
        "top": -3.5 * (event.pageY - this.offsetTop) + &#39;px&#39;
    });
    });
}

HTML is as follows:

<html>
    <head>
        <script src="jquery-1.11.3.js"></script>
        <script src="magnify.js"></script>
    </head>
    <style>
        #imgTarget{
            width: 300px;
            height: 200px;
        }
        #imageArea{
            position: relative;
        }
    </style>
    <body>
        <div id="imageArea">
            <img id="imgTarget" src="car.jpg"/>
        </div>

        <script>
            $( document ).ready( function(){
                $("#imgTarget").magnify();
            } );

        </script>


    </body>


</html>

The reason for flickering is as follows:

You bound the mouseenter mouseleave event to img

when mouseenter img , you generated another glassBox

glassBox on the upper layer of img, thus blocking img and the mouse cursor, so a mouseleave

was generated for img, so the code set glassBox display=none again , the mouse can re-enter to img

Solution 1
Instead of using mouseenter mouseleave, directly judge whether the mouse position is within the range of img in mousemove.

Solution 2
Create an overlay with the same size as img:

<div id="imageArea">
 <img id="imgTarget" src="card.jpg"/>
 <div id="overlay"></div>
</div>
#overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 300px;
  height: 200px;
  background: red;
  opacity: 0.5;
  z-index: 3;
}

Ensure the z-index order of img glassBox overlay:

glassBox.css({
        "width": this.width() / 2 + &#39;px&#39;,
        "height": this.height() /2 + &#39;px&#39;,
        "background-color": &#39;grey&#39;,
        "position": "absolute",
        "left" : &#39;0px&#39;,
        "top": &#39;0px&#39;,
        &#39;opacity&#39;: &#39;0.2&#39;,
        &#39;display&#39;: &#39;none&#39;,
        &#39;border&#39;: &#39;1px solid blue&#39;,
        &#39;z-index&#39;: 2 // 保证glassBox在overlay的下面,在img的上面
    });

Events are bound On the overlay:

$( document ).ready( function(){
    $("#overlay").magnify(); 
} );

The above is the detailed content of jQuery: mouseenter event and mouseleave event cause flickering problem. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn