FX小组件一:悬浮查看大图开发详解及组件下载

        前端时间,一个做后端的同学被逼着做前端,但是表格中放个图片显得极丑,便在群里问我们有没有显示小图,悬浮查看大图的功能。我也没搜集过这个组件,但一想也不是什么复杂的东西,就顺手写了个小组件给他了。后来想想,可能有些后端转前端,或者刚学习前端的新人也会由此类需要,虽然网上应该有不少此类组件,便打算把这个组件的开发方式和源码放出来,希望能对正在学习前端的朋友有所帮助。

        好了,废话不多说,还是直接上干货吧。

        首先说说组件的触发模式,一般组件都存在两种触发模式,一种是js加载时,根据标签、class、属性等,直接进行渲染,不需要其他的js代码,只需要按照特定的格式编写html就可以直接使用,例如bootstrap中的js组件,基本都是使用这种触发模式。

        另一种触发模式,就是使用js调用函数(也就是方法,不同人的叫法习惯不同,但都是一个东西)来触发,例如jQuery UI中的组件,大多都是使用这种触发模式的,这也是本文中的图片悬浮组件使用的触发模式。

        对js组件有些了解的朋友可能会问,为什么不同时使用两种触发模式呢?我主要是考虑到不是什么地方都适合自动渲染的,为了减少不必要的冲突以及更好的在不同位置配置不同的样式,本组件暂时还是只能手动触发渲染。

        触发模式决定了,接下来就是正式开发了。

        首先我们需要定义一个命名空间,以防止变量污染。对于命名空间的必要性,大家可以自己百度,就不在这里多做赘述了。定义命名空间的代码如下:

//获取或创建FX空间
var FX = FX || {};

        我的所有组件都会放在FX空间中,所以在这里我尝试获取FX变量,如果已存在则直接使用,不存在则重新创建,以免在引用多个我的组件时出现覆盖的情况。有些新人可能看不明白FX || {}的写法是什么意思,在这里解释一下,明白的可以直接掉过本段下面的内容。这里要理解这段代码,首先要明白两个概念。第一,在js中,一旦涉及逻辑判断,会根据值自动转换为布尔类型来进行逻辑判断,其中空串(""),空字符串(“ ”或“      ”,也就是只有空格的字符串),null(或undefined),数字0,只包含0和空格的字符串(“0”,“   0   ”“0000000")会被自动转换为false,其他的任何值都会被自动转换为true。第二,||符号是短路或,也就是说,当||前面的代码值为true时,就只会执行||前面的代码,如果前面的代码为false,就会执行后面的代码。那么var FX = FX || {};这段代码就可以理解了,意思就是首先获取FX变量,如果FX变量不存在,则创建一个空对象,然后赋值给FX变量。

        现在命名空间有了,我们就需要在命名空间中声明一个方法用于渲染组件,代码如下:

/**
 * 悬浮查看大图的方法
 * @params el 需要渲染的容器
 * @params overrideConfig 重置的配置属性
 */
FX.suspendImg = function(el,overrideConfig){};

        从以上代码中我们可以看见,我们在FX空间中添加了一个变量suspendImg,并赋值了一个函数。函数有两个变量,el和overrideConfig,其中el是需要渲染的容器,overrideConfig是重写的赔指数型,这两个参数在下文中会解释其作用。

        接下来,就是对函数的编写了。首先,既然有overrideConfig,那自然是有config的,config用于定义其默认配置,也就是“需要渲染的标签,大图的宽高,大图显示时相对于鼠标对的偏移度”,代码如下:

    //默认配置
    var config = {
        tag : 'image',//用于指定要添图片显示功能的标签
        width : '200px',//悬浮图片宽度
        height : '200px',//悬浮图片高度
        top : 10,//悬浮图片上偏移
        left : 10//悬浮图片左偏移
    };

    //使用用户传入的配置信息覆盖默认配置
    if(overrideConfig){
        config = $.extend(config,overrideConfig);
    }

        从这段代码可以看出overrideConfig的用法了,就是用来重写默认配置的,而这也可以看出为什么overrideConfig要作为第二个参数而不是第一个,因为js中调用函数时,不像java那样,同函数名不同参数就是不同的函数,js中的函数只以名称区分,也就是说,这个函数被存放于FX.suspendImg中,那么在调用FX.suspendImg函数时,无论你是写FX.suspendImg(),FX.suspendImg("body"),FX.suspendImg("body",{}),甚至是FX.suspendImg(“body”,null,1,2,3,4,5),最终都会调用到同一个方法。只是,若只传入一个参数,那么第二个参数overrideConfig就会为null,同理,传入两个以上参数时,函数只能接收到前两个参数。当然,如果不传入overrideConfig,则全部使用默认配置。如果大家的项目里面是需要悬浮查看大图的位置是完全统一的格式,也可以直接修改默认配置,这样每次调用就不需要传入overrideConfig了。

        之后,调用了$.extend函数来进行对象合并,$.extend函数的用法可以参考jquery手册或者百度,这里就不说太多了,这里的用法就是使用用户传入的值来覆盖默认配置。当然,$.extend的功能远不止是覆盖,大家不要断章取义哦。

        配置覆盖完成后,就是关键代码了。首先考虑思路,悬浮查看大图的关键点就在于:鼠标悬浮、鼠标离开、显示大图,由此可以看出,至少需要用到鼠标悬浮事件,鼠标离开事件,并且需要一个用于显示大图的容器。那么首先,我们需要创建一个容器。

    //获取或创建悬浮显示用的大图片容器
    var suspendImage = $(".suspend-image");
    if(suspendImage.length == 0){
        suspendImage = $('<div class="suspend-image"></div>').appendTo("body");
    }
    suspendImage.css({
        'width' 	: config.width,
        'height' 	: config.height,
        'display' 	: 'none',
        'position' 	: 'absolute'
    });
        首先,我们试图获取页面上已存在的容器,如果获取到了就不需要创建了,如果没获取到我们就创建一个新的容器。之后,我们更改容器的宽高等css属性,并将该容器设置为绝对定位,并设置为隐藏。可以看见,其中宽高都是从config里取的,也就是说开发人员可以在使用时,根据场景不同,配置不同的宽高,也可以使用默认的宽高。


        最后,就是为图片添加悬浮事件和离开事件了,我们先来看看代码:

    //对el下的所有指定标签添加悬浮显示功能
    $(el).on("mousemove",config.tag,function(e){
        suspendImage.show();
        suspendImage.css({
            top : e.pageY + config.top,
            left : e.pageX + config.left,
        }).html('<image style="width:100%;height:100%;" src="'+$(this).attr("src")+'">');
    })
	
    //鼠标移开时,隐藏悬浮窗
    $(el).on("mouseleave",config.tag,function(e){
        suspendImage.hide();
    });

        代码中添加了两个事件,其中mousemove是鼠标悬浮事件,mouseleave是鼠标离开事件。在悬浮事件中,我们首先将大图容器显示出来,然后为该容器添加定位。因为我们在创建容器时已经为容器添加了绝对定位,所以我们需要做的就是在鼠标悬浮时,基于鼠标所在的位置,将容器定位到这里,并将图片显示在容器中。而top和left属性就是用于定位的。

        e.pageY可以获取到当前鼠标所在的Y轴坐标,e.pageX获取的是X轴坐标,后面只需要要加一个config.top/config.left,是为了增加其偏移量。如果我们不增加偏移量,那么容器就会直接定位在鼠标所在的位置,那么鼠标就相当于立刻离开了小图,也就会立刻触发鼠标离开事件,但却不会触发鼠标悬浮事件,因为此时鼠标被大图容器遮挡了,但是因为触发了离开事件,大图容器又隐藏了,所以就看不到大图了。然后鼠标只要再次移动,又触发了鼠标悬浮事件,如此反复,会发现鼠标移动时大图一直在闪,鼠标一停下大图就消失了。所以切记,一定要设置偏移量,且偏移量最好是正数,如果要是负数,就需要根据大图容器的大小来考虑偏移值了。

        鼠标离开事件则没什么可说的了,只做了隐藏大图容器这一件事情。

        代码的功能部分就讲解完了,接下来和大家说说jquery的on语法。大家看到我绑定事件的方式,可能有些朋友有点迷糊的觉得:这似乎不是我平时用的绑定事件的方式啊!的确,对于大部分刚接触jquery,或者对jquery不是很熟悉的人来说,大多数时候绑定事件都是用$(el).click(function(e){})或者$(el).on("click",function(e){})的方式,那么这种三个参数的绑定方式是什么意思呢?

        首先我们来讲讲$(el),只要用过jquery绑定事件的朋友应该都能理解这一句,这就是用于绑定事件的元素了。其中el就是我们在调用这个FX.suspendImg函数时传入的第一个参数,如果传入的是body,那么在这里代码就可以理解为$("body"),也就是要将事件绑定在body上面。有朋友就要问了,这不是图片的悬浮和离开事件吗,为什么要绑定在body上面?这也就是这种三个参数的on语法的优势了。

    有些朋友可能遇到过,一批数据渲染出来后,我们为class为photo的标签数据绑定了一些事件(例如$(".photo").click(function(){alert(1);})),可以正常生效。但是当翻页后,这批数据同样是class为photo,但却不会触发我们之前绑定的click事件了。这是因为我们的在使用$(".photo")时,获取到的是页面已有的.photo元素,所以事件都是绑定在这些元素上的,翻页后新渲染的数据自然是没有绑定事件的。那么,如果我们将事件绑定在.photo的上级元素上呢?此时我们就可以这么写:$("body").on("click",".photo",function(){});

        这里的写法,意思就是:将单击事件绑定在body上面,但body被单击时,如果此时被单击的元素是.photo元素,那么就触发单击事件。因为单击事件是冒泡触发的,也就是说,一个元素被触发单击事件后,会自动去试图触发它上级标签的单击事件,无论成功失败,都会再次去试图触发上级标签的单击事件,一直到没有上级标签为止。所以,只要一个元素是在body中,那么这个元素被点击时,就一定会触发body的单击事件,除非在某一层级被阻止冒泡了(阻止冒泡的方式,大家需要用到时百度就好了,一般在做菜单的时候经常会用到,因为多层级菜单一不小心就会触发多次父级菜单的单击事件)。当然,我们也不一定要绑定在body上,比如所有.photo元素都被存放在#photos元素中,那么我们只需要将事件绑定在#photos元素上即可。

        所以,用$("body").on("click",".photo",function(){});的方式绑定事件,最大的好处就是,当页面的元素被刷新时,点击事件依旧能生效,因为事件本就不是绑定在那些元素上的,而是绑定在上级元素上的,只要上级元素没有被删除重置,就不会影响事件触发。同时,$("body").on("click",".photo",function(){});这种写法也是在做组件时必须使用的写法,尤其是自动触发式的组件,毕竟你不能让用户更新一下tab标签,就不能切换tab页了吧。


        好了,本次组件详细说明就到这里,下面是本组件的全部源码和使用demo,有兴趣的朋友可以自己下载下来使用学习,有其他问题也可以留言问我,或者本文有什么用词不当或理解错误的地方,也欢迎各位点出,谢谢。

源码和demo下载地址:https://download.csdn.net/download/qq_35478599/10369231

        不知道从什么时候开始,上传的文件必须设置积分了,这个还是显得很蛋疼,所以还是直接贴出源码吧,免得大家还要浪费积分。

        js源码:

/**
 * Created by Freddy-xjn on 2018/4/23
 * 本组件由Freddy-xjn原创,转载请注明出处
 */
//获取或创建FX空间
var FX = FX || {};

/**
 * 悬浮查看大图的方法
 * @params el 需要渲染的容器
 * @params overrideConfig 配置属性
 */
FX.suspendImg = function(el,overrideConfig){
    //默认配置
    var config = {
        tag : 'image',//用于指定要添图片显示功能的标签
        width : '200px',//悬浮图片宽度
        height : '200px',//悬浮图片高度
        top : 10,//悬浮图片上偏移
        left : 10//悬浮图片左偏移
    };

    //使用用户传入的配置信息覆盖默认配置
    if(overrideConfig){
        config = $.extend(config,overrideConfig);
    }

    //获取或创建悬浮显示用的大图片容器
    var suspendImage = $(".suspend-image");
    if(suspendImage.length == 0){
        suspendImage = $('<div class="suspend-image"></div>').appendTo("body");
    }
    suspendImage.css({
        'width' 	: config.width,
        'height' 	: config.height,
        'display' 	: 'none',
        'position' 	: 'absolute'
    });

    //对el下的所有指定标签添加悬浮显示功能
    $(el).on("mousemove",config.tag,function(e){
        suspendImage.show();
        suspendImage.css({
            top : e.pageY + config.top,
            left : e.pageX + config.left,
        }).html('<image style="width:100%;height:100%;" src="'+$(this).attr("src")+'">');
    })
	
	//鼠标移开时,隐藏悬浮窗
    $(el).on("mouseleave",config.tag,function(e){
        suspendImage.hide();
    });

};

        demo:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no;">
	<meta name="apple-mobile-web-app-capable" content="yes">
	<meta name="apple-mobile-web-app-status-bar-style" content="black">
	<meta name="format-detection" content="telephone=no">	
	<title>首页</title>
</head>
<style>
	.text-img{
		width : 50px;
		height : 50px;
	}
</style>
<body>
	<image class="text-img" src="img1.jpg">
	<image class="text-img" src="img2.jpg">
	<image class="text-img" src="img3.jpg">
	<image class="text-img" src="img4.jpg">
</body>
<script src="http://www.jq22.com/jquery/jquery-1.9.1.js"></script>
<script src="FX-suspendImg.js"></script>
<script type="text/javascript">
	FX.suspendImg("body",{
		tag : '.text-img',
		width : '50%',
		height : '50%',
	});
</script>

</html>

效果图:


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值