欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

自定义jq插件,鼠标悬浮展示图片或者视频放大图,可自定义展示内容

程序员文章站 2022-07-06 18:48:40
网站项目经常会遇到一些视频或者图片素材的展示功能,那么就需要自己写一个功能,就是在一些列表页面你想要是这个数据的详细内容,弹框在页面某个位置 例如这是视频悬浮展示效果,可自定义自动播放等属性标签 又例如这是图片悬浮展示,可控制悬浮展示与不展示 像上面这样或者一些其他列表做的一些悬浮弹框展示等,都可以 ......

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

例如这是视频悬浮展示效果,可自定义自动播放等属性标签
自定义jq插件,鼠标悬浮展示图片或者视频放大图,可自定义展示内容

又例如这是图片悬浮展示,可控制悬浮展示与不展示
自定义jq插件,鼠标悬浮展示图片或者视频放大图,可自定义展示内容

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

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

// 插件的调用
        // 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的图库分类, 如果有兴趣可以来网站看一下效果
有很多不足希望能够指出,学习进步,互相关注,谢谢~