javascript - jQuery中mouseenter和mouseleave造成闪烁的问题
高洛峰
高洛峰 2017-04-10 18:09:17
[JavaScript讨论组]

大家好。今天我在做一个图片放大镜的jquery插件。类似于京东上那种商品图片的放大镜。

我发现我在image对象上绑定了mouseenter和mouseleave后,当鼠标在image上移动是会同时触发mouseenter和mouseleave,造成了闪烁。
可是我并不期望mouseenter, mouseleave被反复调用,甚至是同时发生。应该如何解决呢?尝试了网上的几种方法都不太可行。

多谢各位。

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

    var glassBox = $('');

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

    });

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

    var detailBox = $('

'); var detailImage = $(''); detailBox.css({ "width": this.width(), "height": this.height(), "display": 'none', "position": 'relative', "overflow": 'hidden' //"background-color": 'lime' }); detailImage.css({ "position": 'absolute' }); detailImage.attr("src", this.attr("src")); detailBox.append(detailImage); this.after(detailBox); this.mouseenter(function(event){ //event.stopPropagation(); glassBox.get(0).style.display = 'block'; detailBox.get(0).style.display = 'block'; }); this.mouseleave(function(event){ //event.stopPropagation(); if (event.relatedTarget !== "span") { glassBox.get(0).style.display = 'none'; detailBox.get(0).style.display = 'none'; } }); 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 + 'px', top: y + 'px' }); detailImage.css({ "left": -3.5 * (event.pageX - this.offsetLeft) + 'px', "top": -3.5 * (event.pageY - this.offsetTop) + 'px' }); }); }

HTML如下:


    
        
        
    
    
    
        

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(1)
ringa_lee

闪烁的原因是这样的:

  1. 你把mouseenter mouseleave事件绑定在了img上面

  2. mouseenter img时,你又生成了一个glassBox

  3. glassBox在img的上层,于是挡住了img和鼠标光标,于是产生了一个对于img的mouseleave

  4. 于是代码又把glassBox display=none了,mouse又能重新enter到img了

解决方案1
不是用mouseenter mouseleave,直接在mousemove里面对鼠标的位置是否在img的范围内进行判断。

解决方案2
创建一个覆盖层,和img一样大小:

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

保证img glassBox overlay的z-index顺序:

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

事件都绑定在overlay上面:

$( document ).ready( function(){
    $("#overlay").magnify(); 
} );
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号