网站项目经常会遇到一些视频或者图片素材的展示功能,那么就需要自己写一个功能,就是在一些列表页面你想要是这个数据的详细内容,弹框在页面某个位置

例如这是视频悬浮展示效果,可自定义自动播放等属性标签

又例如这是图片悬浮展示,可控制悬浮展示与不展示

像上面这样或者一些其他列表做的一些悬浮弹框展示等,都可以自定义完成。

那这样的插件需要怎么调用呢?

// 插件的调用
// dom 是父元素调用
$(dom).scaleTools({
item: 'li', // 这是子元素,可以为多个 ,元素需定义data-src属性与值,为弹框展示提供数据
fade: true, // 显示方式
conCallback(src) { // 这边是生成的展示内容标签,默认是img
return '<video autoplay muted loop><source src="'+ src +'"></video>' // 这边是已视频为例子
}
}) // 一些其他参数
{
checkbtn: ' ', // 这是提供控制是否弹框的按钮元素
followScroll: true, // 弹框根据元素位置固定或根据窗口位置固定,默认根据鼠标悬浮元素
fadeTime: 500, // 生成弹框间隔时间,默认鼠标悬浮后500毫秒后展示
oftX: 0, // 水平方向距离悬浮元素间距
oftYPosition: 'center', // 生成弹框与元素垂直方向中心点对齐, 其他参数'top', 'bottom'
}

上面的一些调用参数就是插件全部接受的自定义数据,如果有其他特有的需求可以自己读懂源码再去修改,或者给我留言,我去添加,下面就是方法的定义:


;(function($, win) {
const PLUGINNAME = 'scaleTools'; // 定义插件名 let defaultOpts = { // 默认参数
item: '.item',
checkbtn: '',
fade: false,
followScroll: true,
fadeTime: 500,
oftX: 0,
oftYPosition: 'center', // 'top', 'bottom'
conCallback: false
}; class Plugin {
constructor(wrap, opts) {
this.wrap = $(wrap);
this.opts = $.extend(true, {}, defaultOpts, opts); // 合并用户参数
this.items = this.wrap.children(this.opts.item);
this.isShown = false;
this.timer;
this.checkShow = false;
this.init();
} init() {
this.getSize() // 获取窗口大小
this.initEvent() // 初始事件
} initEvent() {
this.wrap
.on('mouseenter', this.opts.item, this.timeInterval.bind(this)) // 父元素委托鼠标进入事件
.on('mouseleave', this.opts.item, this.unbindScale.bind(this)); // 鼠标离开事件
$(win).on('resize', this.getSize.bind(this)); // 窗口改变重新获取
$(win).on('scroll', this.changeScrollTop.bind(this)); // 窗口滚动事件
if(!!this.opts.checkbtn) { // 是否存在插件开关
$(this.opts.checkbtn).on('click', (e)=> {
this.checkShowFn(); // 切换弹框是否悬浮展示
})
} } getSize() {
this.winH = $(window).height();
this.winW = $(window).width();
} initTool(e) {
let html = '<div class="scaleTool"><div class="tool-content">{ inner }</div></div>', // 初始弹框容器, 样式自己在样式文件写
str = '',
src = $(e.target).closest(this.opts.item).data('src') || $(e.target).closest(this.opts.item).find('img').attr('src'); // 获取悬浮元素 需要展示的数据src ,图片或者视频, 如果其他可不填 if(!this.opts.conCallback) {
str = '<img src="'+ src +'" />'
}else {
str = this.opts.conCallback(src)
}; if($('.scaleTool').length) { // 存在弹框
this.toolDom = $('.scaleTool'); // 重新赋值
this.toolDom.find('.tool-content').html(str); // 修改内容
} else {
html = html.replace('{ inner }', str); // 填入内容
$('body').append(html); // 加入页面
this.toolDom = $('.scaleTool'); // 初始声明
} } checkShowFn() { // 是否弹框开关
this.checkShow = !this.checkShow;
if(this.checkShow) {
$(this.opts.checkbtn).addClass('active') // 为开关添加类名自定义样式
} else {
$(this.opts.checkbtn).removeClass('active');
this.toolDom.remove();
}
} unbindScale() { // 鼠标离开
clearTimeout(this.timer);
if(this.toolDom && (this.checkShow || !this.opts.checkbtn)) {
this.opts.conCallback && this.toolDom.find('video')[0].pause();
this.toolDom.hide();
this.isShown = false
}
} // 鼠标进入
timeInterval(event) {
if(this.checkShow || !this.opts.checkbtn) {
this.timer = setTimeout(()=>{
this.showScale(event);
}, this.opts.fadeTime)
}
} showScale(e) {
clearTimeout(this.timer);
if(this.isShown || this.winW < 1200) return; // 页面窗口小于1200 或者正在显示弹框 return this.initTool(e);
let itemW = this.toolDom.width(),
itemH = this.toolDom.height(),
curX, curY,
$curBox = $(e.target).closest(this.opts.item);
// 获取当前悬浮元素的一些位置信息,对弹框位置的定义
let box = $curBox.get(0).getBoundingClientRect(); if(box.right > this.winW / 2) {
curX = box.left - itemW - this.opts.oftX
} else {
curX = box.right + this.opts.oftX
} if(this.opts.oftYPosition === 'top') {
if(box.top < itemH) {
if(box.top < 0) {
curY = 0
} else {
curY = box.top
}
} else {
curY = box.top - itemH
}
} else if(this.opts.oftYPosition === 'bottom') {
if(this.winH - box.bottom > itemH) {
curY = box.bottom
} else {
curY = this.winH - itemH
}
} else {
if((box.top + $curBox.outerHeight() / 2) < itemH / 2) {
if(box.top < 0) {
curY = 0
} else {
curY = box.top
} } else {
if((box.bottom - $curBox.outerHeight() / 2) > (this.winH - itemH / 2)) {
curY = this.winH - itemH
} else {
curY = box.top + $curBox.outerHeight() / 2 - itemH / 2
} }
} this.scrollH = $(win).scrollTop(); this.toolDom.css({
left: curX,
top: curY
}); this.toolT = curY; // 展示方式
if(this.opts.fade) {
this.toolDom.fadeIn()
} else {
this.toolDom.show()
}
this.playVideo() this.isShown = true
} changeScrollTop(e) { // 根据滚动高度修改弹框位置
let scrollT = $(e.target).scrollTop(),
reScrollT = this.scrollH,
itemT = this.toolT,
newScrollT;
if(this.opts.followScroll && this.isShown) {
newScrollT = reScrollT - scrollT;
this.toolDom.css({
top: itemT + newScrollT,
});
}
} playVideo() { // 视频播放
setTimeout(()=> {
this.opts.conCallback && this.toolDom.find('video').get(0).play()
}, 0)
}
} $.fn[PLUGINNAME] = function(options) {
this.each(function() {
if (!$.data(this, "plugin_" + PLUGINNAME)) {
$.data(this, "plugin_" + PLUGINNAME, new Plugin(this, options));
}
});
return this;
}; })(jQuery, window);

上面则是全部插件方法定义了,公司项目网站www.macw.com, 这个插件主要用在视频与素材板块,即v.macw.com的整站与sc.macw.com的图库分类, 如果有兴趣可以来网站看一下效果

有很多不足希望能够指出,学习进步,互相关注,谢谢~

自定义jq插件,鼠标悬浮展示图片或者视频放大图,可自定义展示内容的更多相关文章

  1. jq插件第二款来袭 图片滚动

    这第二款也是非常实用的插件,也是与图片相关,关于图片的需求太多了,这个是图片滚动哦,不过不是无缝滚动,是左像右滚动,到头的话再往回滚动,利用scrollLeft实现的,支持自动滚动和每次滚动的个数默认 ...

  2. jq实现鼠标移动到 图片上放大,移开图片缩小效果(打算封装成插件)

    先看代码 <script> $(function() { $('div').mouseover(function() { $('img').animate({ opacity: '0.9' ...

  3. Qt 之 自定义按钮 在鼠标 悬浮、按下、松开后的效果(全部通过QSS实现)

    http://blog.csdn.net/goforwardtostep/article/details/53464925

  4. jquery图片放大插件鼠标悬停图片放大效果

    都知道jquery都插件是非常强大的,最近分享点jquery插件效果,方便效果开发使用. 一.HTML代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHT ...

  5. jquery特效(5)—轮播图③(鼠标悬浮停止轮播)

    今天很无聊,就接着写轮播图了,需要说明一下,这次的轮播图是在上次随笔中jquery特效(3)—轮播图①(手动点击轮播)和jquery特效(4)—轮播图②(定时自动轮播)的基础上写出来的,也就是本次随笔 ...

  6. 鼠标悬浮弹出标题制作JQuery

    今天给客户制作的网站里面加个效果,当鼠标在列表图片之外时,标题不显示,当鼠标悬浮在图片之上时,标题从底部弹出. 效果图如下: 鼠标悬浮前: 鼠标悬浮后: html代码如下: <ul class= ...

  7. Gradle的构建过程都不会?带你全面了解Android如何自定义Gradle 插件

    目前 Android 工程的默认构建工具为 Gradle,我们在构建 APK 的时候往往会执行 ./gradlew assembleDebug 这样的命令.. 那么这个命令到底代表着什么含义呢?命令的 ...

  8. android listview展示图片

    最近学习android开发,感触颇多,和网站开发对比,还是有很大的差距,在这里记录一下. android listview展示图片 在网站开发上,展示图片非常简单,一个HTML img标签就搞定,加上 ...

  9. 自定义Fiddler插件一

    上个月自定义了一个Fiddler的插件,可以根据请求生成接口自动化测试的RF和Python代码,这样测试人员只需要手动操作页面用Fiddler抓取报文,就可以直接生成RF.Python代码,然后只需要 ...

随机推荐

  1. 13.翻译系列:Code-First方式配置多对多关系【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code- ...

  2. [转]data-driven与决策树聚类的两种方法

    参考文章: http://blog.csdn.net/quheDiegooo/article/details/60873999 http://blog.csdn.net/quhediegooo/art ...

  3. MSRA-TD5000数据集使用详解

    中文检测的数据集,目前最火的应该是清华的CTW,https://ctwdataset.github.io/ 但是它的数据集只存储在微云和google driver,微云空间受限不能完全保存,所以下载的 ...

  4. Sublime Text3176激活码

    此激活码为版本号为3176的激活码: 首先更改hosts文件防止Sublime Text3联网验证: Mac上hosts文件路径为/etc/hosts,所以需要sudo vim /etc/hosts ...

  5. python中stack在实际中的简单应用之平衡符号

    很多书籍都在讲stack的概念和使用方法,等我们把概念熟悉后,发现不知道在什么场景下使用 该结构体,这里就列几个实用的例子,让大家了解一下stack在实际中的用处和厉害之处. 由于stack中的特点是 ...

  6. LeetCode: 106_Construct Binary Tree from Inorder and Postorder Traversal | 根据中序和后序遍历构建二叉树 | Medium

    要求:根据中序和后序遍历序列构建一棵二叉树 代码如下: struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int ...

  7. PyTorch(一)Basics

    PyTorch Basics import torch import torchvision import torch.nn as nn import numpy as np import torch ...

  8. Ubuntu18.04 下修改 root密码

    首先打开终端输入命令 sudo passwd root 然后依次是当前用户密码,将要设置root密码,确认root密码.切换root看一下 备注: #符号 是系统用户 root$符号 是你创建的用户 ...

  9. 调试工具Chisel-LLDB插件

    Chisel-LLDB命令插件 相信每个人或多或少都在用LLDB来调试,比如po一个对象.LLDB的是非常强大的,且有内建的,完整的 Python 支持.今天我们主要介绍一个 facebook 开源的 ...

  10. Spring Boot应用的后台运行配置(转载)

    作者:程序猿DD 酱油一篇,整理一下关于Spring Boot后台运行的一些配置方式.在介绍后台运行配置之前,我们先回顾一下Spring Boot应用的几种运行方式: 运行Spring Boot的应用 ...