自定义jq插件,鼠标悬浮展示图片或者视频放大图,可自定义展示内容
程序员文章站
2022-03-31 17:01:40
网站项目经常会遇到一些视频或者图片素材的展示功能,那么就需要自己写一个功能,就是在一些列表页面你想要是这个数据的详细内容,弹框在页面某个位置 例如这是视频悬浮展示效果,可自定义自动播放等属性标签 又例如这是图片悬浮展示,可控制悬浮展示与不展示 像上面这样或者一些其他列表做的一些悬浮弹框展示等,都可以 ......
网站项目经常会遇到一些视频或者图片素材的展示功能,那么就需要自己写一个功能,就是在一些列表页面你想要是这个数据的详细内容,弹框在页面某个位置
例如这是视频悬浮展示效果,可自定义自动播放等属性标签
又例如这是图片悬浮展示,可控制悬浮展示与不展示
像上面这样或者一些其他列表做的一些悬浮弹框展示等,都可以自定义完成。
那这样的插件需要怎么调用呢?
// 插件的调用 // 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.macdown.com, 这个插件主要用在视频与素材板块,即v.macdown.com的整站与sc.macdown.com的图库分类, 如果有兴趣可以来网站看一下效果
有很多不足希望能够指出,学习进步,互相关注,谢谢~
下一篇: 中秋吃什么月饼最好吃?你爱吃哪种?