jQuery实现响应式瀑布流 - 实现灯箱效果

news2024/9/30 3:21:59

        在这之前,有写过一篇关于实现瀑布流的文章,后期有人留言提出需要添加灯箱效果的功能,所以这次则讲述下如何实现此功能。由于该篇接上篇写的:jQuery实现响应式瀑布流效果(jQuery+flex)_jquery瀑布流插件-CSDN博客

,所以建议先学习上篇,再来练习此篇内容。

一、页面样式

        弹框灯箱部分的页面样式这里就不细讲了,在之前瀑布流页面样式后追加即可,代码如下:

/* 弹框样式 */
.image-dialog-wrap {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    background-color: rgba(0, 0, 0, .5);
    position: fixed;
    left: 0;
    top: 0;
    z-index: 999;
}

.image-dialog-wrap .dialog-close {
    width: 36px;
    height: 36px;
    background: url("../images/dialog-close.png") no-repeat center;
    background-size: 100% 100%;
    position: absolute;
    top: 15px;
    right: 15px;
    z-index: 10;
    cursor: pointer;
}

.image-dialog-wrap .dialog-flex-box {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    overflow: hidden;
}

.image-dialog-wrap .dialog-flex-box .flex-item {
    display: block;
    width: 100%;
    box-sizing: border-box;
}

.image-dialog-wrap .dialog-top-box {
    flex: 3;
    position: relative;
    padding: 15px 30px;
    text-align: center;
}

.image-dialog-wrap .dialog-top-box::before {
    display: inline-block;
    content: attr(data-title);
    font-size: 16px;
    color: #fff;
}

.image-dialog-wrap .dialog-image-box {
    flex: 16;
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    position: relative;
}

.image-dialog-wrap .dialog-image-box.cover-box{
    position: absolute;
    top: 0;
    height: 100% !important;
    display: block !important;
}

.image-dialog-wrap .dialog-image-box .image-btn {
    width: 50px;
    height: 100px;
    margin-top: -50px;
    border: 0;
    outline: none;
    background-color: rgba(0, 0, 0, .5);
    background-position: center;
    background-repeat: no-repeat;
    background-size: contain;
    position: absolute;
    top: 50%;
    cursor: pointer;
    display: none;
}

.image-dialog-wrap .dialog-image-box .image-btn.btn-left {
    background-image: url("../images/angle-left.png");
    left: 0;
}

.image-dialog-wrap .dialog-image-box .image-btn.btn-right {
    background-image: url("../images/angle-right.png");
    right: 0;
}

.image-dialog-wrap .dialog-image-box:hover .image-btn {
    display: block;
}

.image-dialog-wrap .dialog-image-box:hover .image-btn[disabled] {
    opacity: .2;
    cursor: default;
}

.image-dialog-wrap .scale-btn {
    width: 45px;
    height: 45px;
    background: url(../images/scale-up.png) no-repeat center;
    background-size: 80%;
    position: absolute;
    top: 10px;
    right: 70px;
    border: 0;
    outline: none;
    border-radius: 5px;
    cursor: pointer;
}

.image-dialog-wrap .scale-btn[rel=cover] {
    background-image: url(../images/scale-down.png);
}

.image-dialog-wrap .dialog-desc-box {
    flex: 3;
    font-size: 16px;
    color: #fff;
    padding: 15px 20px;
}


@media screen and (min-width: 1200px) {
    .image-dialog-wrap .dialog-flex-box {
        margin: 0 auto;
    }
}

@media screen and (max-width: 1199px) {
    .image-dialog-wrap {
        padding: 50px 15px 0;
    }

    .image-dialog-wrap .dialog-image-box {
        background-color: transparent;
    }

    .image-dialog-wrap .dialog-image-box .image-btn {
        width: 30px;
        height: 80px;
        margin-top: -40px;
    }

}

        移动端的界面效果图:

        样式内部的图标,都是从iconfront中下载的,需要可以从该网站下载,地址:

iconfont-阿里巴巴矢量图标库

二、JS功能开发

2.1 闭包

        如上篇瀑布流功能函数定义,也在闭包中进行功能开发,代码如下:

/**
 * 闭包 - 灯箱效果
 */
(function($, win, doc){

    /**
     * 图片灯箱效果
     * @param {*} options 
     */
    $.fn.imageBox = function(options){
        
		// 须链式调用,返回this
        return this;
    }
})(jQuery, window, document);

2.2 定义传参

        如上图,页面结构包含”顶部一段话“、”图片“、”底部描述内容“三块,这里我们如何获取对应内容,并将渲染到灯箱指定位置呢?所以这块需要做对外接口,使其调整灵活点,读取指定位置内容进行渲染即可。如下代码:

<img src="${item.img}" alt="" 
        data-img="${item.img}" 
        data-title="顶部一段话" 
        data-desc="${item.description}"

        如上,我们在渲染时,将三块内容分别存放在img标签的data中,然后在显示灯箱图片是,取对应图片的data数据即可。所以功能函数中对外定义参数如下:

/**
 * 闭包 - 灯箱效果
 */
(function($, win, doc){

    /**
     * 图片灯箱效果
     * @param {*} options 
     */
    $.fn.imageBox = function(options){
        options = $.extend({
            imgName: "img",					// 需要添加到灯箱中图片类名或标签名
            imgColumnName: "img",			// 填充灯箱中图片链接地址
            topColumnName: "title",			// 填充顶部标题容器的data后缀-title
            descriptionColumnName: "desc"	// 填充底部描述容器的data后缀-desc
        }, options);

        return this;
    }
})(jQuery, window, document);

2.3 页面调用

        这里将上篇瀑布流中页面代码稍作调整,在img上添加2.2中所示data数据,以及在执行瀑布流功能函数前,执行灯箱功能函数调用,代码如下:

<body>
    <!-- waterfall -->
    <div class="waterfall-container">
        <div class="wf-content" id="waterfall"></div>
    </div>
    <!-- /waterfall -->
<script type="text/javascript">
var imagesList = [
    {
		title: "图片1", 
		description: "这是一张优美的图片!这是一张优美的图片!这是一张优美的图片!这是一张优美的图片!", 
		img: "images/waterfall/photo (1).png"
	},
	// 略...
];

// 将获取的数据填充到dom中,返回拼接后的html
function generateHtml(item, count){
    return `<a href="javascript:;" class="item">
                <img src="${item.img}" alt="" 
						data-img="${item.img}" 
						data-title="顶部一段话" 
						data-desc="${item.description}" />
                <div class="txt-box">
                    <h3>${item.title}-${count}</h3>
                    <p>${item.description}</p>
                </div>
            </div>`;
}

var loadIndex = 0;

// ajax 加载数据
function ajaxLoadData(that){
    // 略
}

 $(function(){
    // 添加灯箱效果
    $('#waterfall').imageBox({
        imgName: "img[data-img]",
        imgColumnName: "img"
    });

    // 实例瀑布流
    var waterfall = $('#waterfall').waterfall({
        eleItemClassName: "item",
        loadingText: "正在加载数据中...",
        loadOverText: "没有更多数据了",
        loadText: "~ 下拉加载更多数据 ~",
        // 滑到底部执行函数
        slideToDownCallback: function(){
            ajaxLoadData(this);
        }
    });

    // 请求数据
    ajaxLoadData(waterfall);
 });  
 </script>

2.4 图解并定义容器

        上图中说明了各区域的类名,以及各容器间关系(包含与被包含),现在我们将根据此图,在灯箱功能函数执行时,初始化灯箱打开后的页面结构。代码如下:

/**
 * 闭包 - 灯箱效果
 */
(function($, win, doc){

    /**
     * 图片灯箱效果
     * @param {*} options 
     */
    $.fn.imageBox = function(options){
        options = $.extend({
            imgName: "img",					// 需要添加到灯箱中图片类名或标签名
            imgColumnName: "img",			// 填充灯箱中图片链接地址
            topColumnName: "title",			// 填充顶部标题容器的data后缀-title
            descriptionColumnName: "desc"	// 填充底部描述容器的data后缀-desc
        }, options);

        var that = this,
            // 存储图片信息
            imageData = {
                list: [],           //所有图片
                index: -1           //索引
            },
            // 常量(用来切换是否全屏显示)
            CONSTMODE = {
                CONTAIN: 'contain',
                COVER: 'cover'
            },
            imageBoxContainer = $('<div />').addClass("image-dialog-wrap").hide(),
            flexBox = $('<div />').addClass('dialog-flex-box'),
            titleBox = $('<div />').addClass("flex-item dialog-desc-box"),     // 底部标题信息
            imgBox = $('<div />').addClass('flex-item dialog-image-box'),       // 图片信息
            topBox = $('<div />').addClass('flex-item dialog-top-box'),         // 头部标题信息
            btnLeft = $('<button type="button" />').addClass('image-btn btn-left'),
            btnRight = $('<button type="button" />').addClass('image-btn btn-right'),
            btnScale = $('<button type="button" />').addClass('scale-btn'),
            closeBox = $('<div />').addClass('dialog-close');                   // 关闭按钮

        // 添加到页面中
        $('body').append(imageBoxContainer);
        // 添加左右切换按钮容器到图片容器中
        imgBox.append(btnLeft);
        imgBox.append(btnRight);
		// 将顶部标题、图片、底部描述三块区域添加到dialog-flex-box容器中
        flexBox.append(topBox);
        flexBox.append(imgBox);
        flexBox.append(titleBox);
		// 将dialog-flex-box、关闭按钮、全屏显示按钮添回到的灯箱总容器中
        imageBoxContainer.append(flexBox);
        imageBoxContainer.append(closeBox);   
        imageBoxContainer.append(btnScale);           

        return this;
    }
})(jQuery, window, document);

2.5 点击事件

        以上准备工作做完后,现在可以实现具体功能了。首先点击图片时,需要获取瀑布流容器中需要添加到灯箱中的所有图片信息,这里是每次点击都重新获取一次,由于瀑布流是上拉加载的,所以页面中图片数量是处于变化中的。

        如2.3中可知,灯箱功能函数执行是,传入的是瀑布流大窗口的ID(#waterfall),所以这里我们直接通过$(this).on() 进行监听即可。先实现灯箱的相关事件定义好,由于关闭功能较简单先实现其功能,代码如下:

// 向左切换
btnLeft.on('click', function(){
	// do something...
});

// 向右切换
btnRight.on('click', function(){
	// do something...
});

// 图片显示模式切换
btnScale.on('click', function(){
	// do something...
});

// 关闭弹框
closeBox.on('click', function(){
	imageBoxContainer.fadeOut();
});

// 选择图片
$(this).on('click', options.imgName, function(){
	// do something...
});

2.6 获取全部图片

        在闭包中定义函数getAllImage(),获取全部图片信息和当前显示图片索引。代码如下:

/**
 * 获取数据
 * @param {*} eleWrap 
 * @param {*} imgSrc 
 * @param {*} options 
 * @returns 
 */
function getAllImage(eleWrap, imgSrc, options){
	var data = {
			list: [],       //存储所有图片
			index: 0        //当前显示图片索引
		},
		// 如果传入为图片地址,直接使用,否则重新读取
		current = 'string' === typeof imgSrc ? imgSrc : $(imgSrc).data(options.imgColumnName);
	// 循环获取所有图片
	$(eleWrap).find(options.imgName).each(function(index){
		var url = $(this).data(options.imgColumnName);
		if(url){
			// 添加图片
			data.list.push($(this).data());
			// 判断索引,是否为默认显示项
			if(url==current){
				data.index = index;
			}
		}
	});
	return data;
}

2.7 重构当前显示图片信息

        将函数resetCurrentImage()和setImageMode()定义在$.fn.imageBox内部,这样方便与直接获取容器对象,并修改样式和内容。代码如下:

// 重置当前图片
function resetCurrentImage(){
	var data = imageData.list[imageData.index],
		img = new Image(),
		imgMaxHeight = $(win).height() - 200;
	// 指定显示图片地址
	img.src = data[options.imgColumnName];
	// 顶部标题
	topBox.attr('data-title', data[options.topColumnName]);
	// 底部描述
	titleBox.text(data[options.descriptionColumnName]);
	// 设置图片样式
	imgBox.css({
		"background-image": "url('"+data[options.imgColumnName]+"')",
		"height": img.height > imgMaxHeight ? imgMaxHeight : img.height
	});
}

// 设置模式
function setImageMode(mode){
	mode = mode || CONSTMODE.CONTAIN;
	// 在全屏按钮上记录显示模式
	btnScale.data('mode', mode);
	btnScale.attr('rel', mode);
	imgBox.css('background-size', mode);
	// 判断是否全屏显示
	if(mode==CONSTMODE.COVER){
		imgBox.addClass('cover-box');
	}else {
		imgBox.removeClass('cover-box');
	}
}

2.8 默认显示模式

        灯箱功能函数初始时,在灯箱结构部分初始完成后,默认执行一次setImageMode()函数,设置灯箱图片显示模式。

2.9 显示灯箱

        在2.5中,将选择图片事件中,添加如下代码,此时点击图片后则可以正常显示灯箱效果了。

        getAllImage()函数执行后,会返回对应的list和index结构,是和imageData结构一致,所以获取后直接赋值给它即可,后期图片左右切换会使用到。

// 选择图片
$(this).on('click', options.imgName, function(){
	// 获取所有图片信息
	imageData = getAllImage(that, this, options);
	// 重置当前灯箱中显示图片信息
	resetCurrentImage();
	// 显示灯箱容器
	imageBoxContainer.fadeIn();
});

        效果如下:

2.10 左右切换

        在2.0中,灯箱显示时获取全部图片信息时,已经将所有图片信息存储在list中,当前显示图片索引值为index,所以这里切换时,只要控制index即可。代码如下:

// 向左切换
btnLeft.on('click', function(){
	// 如果索引值小于0,则停止执行
	imageData.index = imageData.index - 1 <= 0 ? 0 : imageData.index - 1;
	// 如果切换到第一个图片信息,则禁用向左切换按钮,否则解禁按钮
	if(imageData.index == 0) btnLeft.prop('disabled', true);
	else if(btnLeft.prop('disabled')) btnLeft.prop('disabled', false);
	// 解禁向右切换按钮
	if(btnRight.prop('disabled')) btnRight.prop('disabled', false);
	// 重构当前图片信息
	resetCurrentImage();
});

// 向右切换
btnRight.on('click', function(){
	// 如果索引值大于图片信息总长度,则停止执行
	imageData.index = imageData.index + 1 >= imageData.list.length - 1 ? imageData.list.length - 1 : imageData.index + 1;
	// 如果切换到最后一张图片信息,则禁用向右切换按钮,否则解禁
	if(imageData.index == imageData.list.length - 1) btnRight.prop('disabled', true);
	else if(btnRight.prop('disabled'))  btnRight.prop('disabled', false);
	// 解禁向左切换按钮
	if(btnLeft.prop('disabled')) btnLeft.prop('disabled', false);
	// 重构当前图片信息
	resetCurrentImage();
});

2.11 全屏显示

        全屏显示效果是结合CSS样式和JS交互共同实现的,这块比较好理解,setImageMode()重置显示模式在2.7中已定义,直接在点击事件中调用即可,代码如下:

// 图片显示模式切换
btnScale.on('click', function(){
	var mode = $(this).data('mode');
	// 如果是COVER则传入CONTAIN,若是CONTAIN则传入COVER
	setImageMode(mode==CONSTMODE.CONTAIN?CONSTMODE.COVER:CONSTMODE.CONTAIN);
});

2.12 瀑布流和灯箱的JS代码

        这里将瀑布流和灯箱的JS代码放在一起,如果有小朋友参照上述代码执行,出错或显示不了,可以马对照以下代码。

/**
 * 闭包 - 定义瀑布流封装函数
 */
(function($, win, doc){

    /**
     * 获取列数
     * @param {*} gridList 
     * @returns 
     */
    function getGridColumn(gridList){
        var winWidth = win.innerWidth;
        // 循环判断当前宽度范围
        for(var i = 0; i < gridList.length; i++){
            if(winWidth>gridList[i].min&&winWidth<=gridList[i].max){
                return gridList[i].value;
            }
        }
        // 否则返回最大值列数
        return gridList[0].value;
    }

    /**
     * 生成对应的列
     * @param {*} that 
     * @param {*} options 
     * @returns 
     */
    function generateGrid(that, options){
        var itemList = [];
        for(var i = 0, tmpSubElement; i < that.columns; i++){
            tmpSubElement = $('<div />').addClass(options.gridClassName + "-" + (i+1)).addClass(options.gridInnerItemClassName);
            itemList[i] = $('<div />').addClass(options.gridClassName);
            itemList[i].append(tmpSubElement);
            that.container.append(itemList[i]);
        }
        return itemList;
    }

    /**
     * 获取每列中高度最小值元素
     * @param {*} that 
     * @param {*} options 
     * @returns 
     */
    function getMinItem(that, options){
        return that.grids.sort((first, second) => {
            return first.find('.' + options.gridInnerItemClassName).height() - second.find('.' + options.gridInnerItemClassName).height();
        })[0];
    }

    // 拼图,将元素追加到对应容器中
    function jigsawPhoto(that, items, options){
        var minHeightElement;
        // 循环处理
        items.each((i, item) => {
            minHeightElement = getMinItem(that, options);
            minHeightElement.find('.' + options.gridInnerItemClassName).append(item);
        });
    }


    /**
     * 定义瀑布流功能
     * @param {*} options 
     */
    $.fn.waterfall = function(options){
        options = $.extend(true, {
            // 瀑布流最包层容器选择器名称
            containerListClassName: 'waterfall-flex-container',
            eleItemClassName: "",                    //放置每列中的元素选择器
            gridClassName: "column-item",           //列选择器   
            gridInnerItemClassName: "grid-inner-item",
            loadClassName: "waterfall-load-more",
            loadingText: "正在加载中...",
            loadOverText: "已经没有数据了",
            loadText: "~ 下拉加载更多 ~",
            diff: 50,           //底部差值,提前执行
            // 布局,不同尺寸下显示不行列元素,尺寸从大到小排序
            grid: {
                2300: 6,
                1920: 5,
                1360: 4,
                980: 3,
                768: 2,
                520: 1
            },
            // 错误回调函数
            errorCallback: function(){},
            // 滑到底部执行函数
            slideToDownCallback: function(){}
        }, options);

        // 定义容器和DOM
        var containerListObj = $('<div />').addClass(options.containerListClassName),       //容器DOM对象
            domObj = $(this),
            elementItems = domObj.find('.' + options.eleItemClassName),
            loadObj = $('<div />').addClass(options.loadClassName).text(options.loadText);

        // 定义变量
        var that = this;

        // 获取容器显示列范围
        this.grid = (function(grid){
                var list = [],
                    keys = Object.keys(grid).map(item => parseInt(item)).sort((a, b) => b - a);
                
                keys.forEach((key, i) => {
                    if(i == keys.length - 1){
                        list.push({ min: 0, max: key, value: grid[key] })
                    }else{
                        list.push({ min: keys[i+1], max: key, value: grid[key] })
                    }
                });
                    
                return list;
            })(options.grid);

        // 获取当前显示列数
        this.columns = getGridColumn(this.grid);

        $(this).append(containerListObj);   // 添加响应式容器
        $(this).append(loadObj);            // 添加加载提示内容

        //将创建DOM对象赋值到this当前对象上
        this.container = containerListObj;    //放置列容器DOM对象
        this.items = elementItems;            //瀑布流所有元素DOM对象集
        this.loading = loadObj;               //上拉加载盒子DOM对象

        // 生成结果
        this.grids = generateGrid(this, options);
        // 拼图堆加
        jigsawPhoto(this, elementItems, options);

        // 监听屏幕大小变化
        $(win).resize(function(){
            that.container.empty();
            // 获取当前显示列数
            that.columns = getGridColumn(that.grid);
            // 生成结果
            that.grids = generateGrid(that, options);
            // 拼图堆加
            jigsawPhoto(that, that.items, options);
        });

        // 定义变量判断是否正在获取追加内容
        var isLoading = false;
        // 执行回调函数位置滚动条高度
        this.scrollTop = 0;
        // 滑到底部执行函数
        this.slideToDownCallback = options.slideToDownCallback;

        // 重新执行获取数据,刷新数据
        this.refresh = function(){
            // 追加获取元素
            var newItems = domObj.find('.' + options.eleItemClassName ).each((i, item) => {
                that.items.push(item);
            });
            // 拼图堆加
            jigsawPhoto(that, newItems, options);
            //
            $(doc).scrollTop(that.scrollTop);

            isLoading = false;
            loadObj.text(options.loadText);
        }
        // 开始加载 时执行
        this.startLoading = function(){
            isLoading = true;
            loadObj.text(options.loadingText);
        }
        // 加载完毕后 执行
        this.loadEnd = function(){
            isLoading = true;
            loadObj.text(options.loadOverText);
        }

        // 监听滑动事件
        $(win).scroll(function(e){
            // 判断是否已滑到底部
            if($(doc).height() - $(win).height() - options.diff <= $(doc).scrollTop() && !isLoading){
                that.scrollTop = $(doc).scrollTop();
                that.slideToDownCallback();
            }
        });
        
        return this;
    }

})(jQuery, window, document);

/**
 * 闭包 - 灯箱效果
 */
(function($, win, doc){

    /**
     * 获取数据
     * @param {*} eleWrap 
     * @param {*} imgSrc 
     * @param {*} options 
     * @returns 
     */
    function getAllImage(eleWrap, imgSrc, options){
        var data = {
                list: [],       //存储所有图片
                index: 0        //当前显示图片索引
            },
            // 如果传入为图片地址,直接使用,否则重新读取
            current = 'string' === typeof imgSrc ? imgSrc : $(imgSrc).data(options.imgColumnName);
        // 循环获取所有图片
        $(eleWrap).find(options.imgName).each(function(index){
            var url = $(this).data(options.imgColumnName);
            if(url){
                // 添加图片
                data.list.push($(this).data());
                // 判断索引,是否为默认显示项
                if(url==current){
                    data.index = index;
                }
            }
        });
        return data;
    }

    /**
     * 图片灯箱效果
     * @param {*} options 
     */
    $.fn.imageBox = function(options){
        options = $.extend({
            imgName: "img",					// 需要添加到灯箱中图片类名或标签名
            imgColumnName: "img",			// 填充灯箱中图片链接地址
            topColumnName: "title",			// 填充顶部标题容器的data后缀-title
            descriptionColumnName: "desc"	// 填充底部描述容器的data后缀-desc
        }, options);

        var that = this,
            // 存储图片信息
            imageData = {
                list: [],           //所有图片
                index: -1           //索引
            },
            // 常量(用来切换是否全屏显示)
            CONSTMODE = {
                CONTAIN: 'contain',
                COVER: 'cover'
            },
            imageBoxContainer = $('<div />').addClass("image-dialog-wrap").hide(),
            flexBox = $('<div />').addClass('dialog-flex-box'),
            titleBox = $('<div />').addClass("flex-item dialog-desc-box"),     // 底部标题信息
            imgBox = $('<div />').addClass('flex-item dialog-image-box'),       // 图片信息
            topBox = $('<div />').addClass('flex-item dialog-top-box'),         // 头部标题信息
            btnLeft = $('<button type="button" />').addClass('image-btn btn-left'),
            btnRight = $('<button type="button" />').addClass('image-btn btn-right'),
            btnScale = $('<button type="button" />').addClass('scale-btn'),
            closeBox = $('<div />').addClass('dialog-close');                   // 关闭按钮

        // 添加到页面中
        $('body').append(imageBoxContainer);
        // 添加左右切换按钮容器到图片容器中
        imgBox.append(btnLeft);
        imgBox.append(btnRight);
		// 将顶部标题、图片、底部描述三块区域添加到dialog-flex-box容器中
        flexBox.append(topBox);
        flexBox.append(imgBox);
        flexBox.append(titleBox);
		// 将dialog-flex-box、关闭按钮、全屏显示按钮添回到的灯箱总容器中
        imageBoxContainer.append(flexBox);
        imageBoxContainer.append(closeBox);   
        imageBoxContainer.append(btnScale);         


		// 重置当前图片
        function resetCurrentImage(){
            var data = imageData.list[imageData.index],
                img = new Image(),
                imgMaxHeight = $(win).height() - 200;
			// 指定显示图片地址
            img.src = data[options.imgColumnName];
            // 顶部标题
            topBox.attr('data-title', data[options.topColumnName]);
            // 底部描述
            titleBox.text(data[options.descriptionColumnName]);
            // 设置图片样式
            imgBox.css({
                "background-image": "url('"+data[options.imgColumnName]+"')",
                "height": img.height > imgMaxHeight ? imgMaxHeight : img.height
            });
        }

        // 设置模式
        function setImageMode(mode){
            mode = mode || CONSTMODE.CONTAIN;
            // 设置模式
            btnScale.data('mode', mode);
            btnScale.attr('rel', mode);
            imgBox.css('background-size', mode);
			// 判断是否全屏显示
            if(mode==CONSTMODE.COVER){
                imgBox.addClass('cover-box');
            }else {
                imgBox.removeClass('cover-box');
            }
        }
        setImageMode();


		// - - - - - - - - - - - - - - - - - - - - - - 点击事件 Start - - - - - - - - - - - - - - - - - - - - - -
        // 向左切换
        btnLeft.on('click', function(){
            imageData.index = imageData.index - 1 <= 0 ? 0 : imageData.index - 1;
            if(imageData.index == 0) btnLeft.prop('disabled', true);
            else if(btnLeft.prop('disabled')) btnLeft.prop('disabled', false);
            if(btnRight.prop('disabled')) btnRight.prop('disabled', false);
            resetCurrentImage();
        });

        // 向右切换
        btnRight.on('click', function(){
            imageData.index = imageData.index + 1 >= imageData.list.length - 1 ? imageData.list.length - 1 : imageData.index + 1;
            if(imageData.index == imageData.list.length - 1) btnRight.prop('disabled', true);
            else if(btnRight.prop('disabled'))  btnRight.prop('disabled', false);
            if(btnLeft.prop('disabled')) btnLeft.prop('disabled', false);
            resetCurrentImage();
        });

        // 图片显示模式切换
        btnScale.on('click', function(){
            var mode = $(this).data('mode');
            // 如果是COVER则传入CONTAIN,若是CONTAIN则传入COVER
            setImageMode(mode==CONSTMODE.CONTAIN?CONSTMODE.COVER:CONSTMODE.CONTAIN);
        });

        // 关闭弹框
        closeBox.on('click', function(){
            imageBoxContainer.fadeOut();
        });

        // 选择图片
        $(this).on('click', options.imgName, function(){
			// 获取所有图片信息
            imageData = getAllImage(that, this, options);
			// 重置当前灯箱中显示图片信息
            resetCurrentImage();
			// 显示灯箱容器
            imageBoxContainer.fadeIn();
        });

        return this;
    }
})(jQuery, window, document);

        以上仅供参考,如有疑问欢迎交流!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1333384.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

驾驶未来:百度Apollo自动驾驶技术的探索与实践(文末赠送apollo周边)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 粉丝福利活动 ✅参与方式&#xff1a;通过连接报名观看课程&#xff0c;即可免费获取精美周边 ⛳️活动链接&#xf…

Java之Synchronized与锁升级

Synchronized与锁升级 一、概述 在多线程并发编程中 synchronized 一直是元老级角色&#xff0c;很多人都会称呼它为重量级锁。但是&#xff0c;随着 Java SE 1.6 对 synchronized 进行了各种优化之后&#xff0c;有些情况下它就并不那么重了。 本文详细介绍 Java SE 1.6 中为…

智能算法(GA、DBO等)求解阻塞流水车间调度问题(BFSP)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

七天搞定java接口自动化测试实战,一文搞定...

前言 无论是自动化测试还是自动化部署&#xff0c;撸码肯定少不了&#xff0c;所以下面的基于java语言的接口自动化测试&#xff0c;要想在业务上实现接口自动化&#xff0c;前提是要有一定的java基础。 如果没有java基础&#xff0c;也没关系。这里小编也为大家提供了一套jav…

Gaussian-Splatting 训练并导入Unity中

这个周末玩点啥~&#x1f41e; &#x1f354;资源下载&#x1f365;环境安装&#x1f4a1;安装C编译工具&#x1f4a1;安装Python&#x1f4a1;安装CUDA&#x1f4a1;添加ffmpeg到环境变量Path&#x1f4a1;pytorch安装&#x1f4a1;tqdm 安装&#x1f4a1;diff-gaussian-raste…

元素的显示与隐藏(常用)

场景&#xff1a;类似网站广告&#xff0c;当我们点击关闭就不见了&#xff0c;但是我们重新刷新页面&#xff0c;会重新出现&#xff01; 本质&#xff1a;让一个元素在页面中隐藏或者显示出来。 1. display 显示隐藏元素 但是不保留位置 2. visibility 显示隐藏元素 但是保留…

luceda ipkiss教程 53:在版图上加中文

要在版图上加中文&#xff0c;如&#xff1a; 可以通过如下方法实现&#xff1a; 首先&#xff0c;可以在ppt中加入文本框&#xff0c;在文本框中输入想要加到版图上的中文内容&#xff0c;如&#xff0c;复旦大学&#xff0c;并将文本框存为windows位图。 其次&#xff0c;通…

智能优化算法应用:基于金豺算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于金豺算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于金豺算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.金豺算法4.实验参数设定5.算法结果6.参考文献7.MA…

在Redis客户端设置连接密码 并演示密码登录

我们先连接到Redis服务 然后 我们要输入 CONFIG SET requirepass “新密码” 例如 CONFIG SET requirepass "A15167"这样 密码就被设置成立 A15167 我们 输入 AUTH 密码 例如 AUTH A15167这里 返回OK说明成功了 然后 我们退出在登录就真的需要 redis-cli -h IP地…

C语言沉浸式刷题【C语言必刷题】

1.猜凶手 某地发生了一起谋杀案&#xff0c;警察通过排查确定杀人凶手必为四个嫌疑犯的一个&#xff0c;以下是4个嫌犯的供词。已知&#xff08;请编写代码找出凶手&#xff09; A说&#xff1a;不是我。 B说&#xff1a;是C。C说&#xff1a;是D。D说&#xff1a;C再胡说。 程…

从0开始python学习-35.allure报告企业定制

目录 1. 搭建allure环境 2. 生成报告 3. logo定制 4. 企业级报告内容或层级定制 5. allure局域网查看 1. 搭建allure环境 1.1 JDK&#xff0c;使用PyCharm 找到pycharm安装目录找到java.exe记下jbr目录的完整路径&#xff0c;eg: C:\Program Files\JetBrains\PyCharm Com…

1.数字反转

题目 AC import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();if(n>0) {StringBuilder str new StringBuilder();str.append(n);StringBuilder str1 str.reverse();String st…

猫头虎带您探索Go语言的魅力:GoLang程序员必备的第三方库大盘点 ‍ ‍

猫头虎带您探索Go语言的魅力&#xff1a;GoLang程序员必备的第三方库大盘点 ‍ &#x1f680;&#x1f431;‍&#x1f4bb; 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#x…

2024-AI人工智能学习-安装了pip install pydot但是还是报错

2024-AI人工智能学习-安装了pip install pydot但是还是报错 出现这样子的错误&#xff1a; /usr/local/bin/python3.11 /Users/wangyang/PycharmProjects/studyPython/tf_model.py 2023-12-24 22:59:02.238366: I tensorflow/core/platform/cpu_feature_guard.cc:182] This …

MySQL的事务-原子性

MySQL的事务处理具有ACID的特性&#xff0c;即原子性&#xff08;Atomicity)、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;和持久性&#xff08;Durability&#xff09;。 1. 原子性指的是事务中所有操作都是原子性的&#xff0c;要…

【论文解读】CNN-Based Fast HEVC Quantization Parameter Mode Decision

时间&#xff1a;2019 年 级别&#xff1a;SCI 机构&#xff1a;南京信息工程大学 摘要 随着多媒体呈现技术、图像采集技术和互联网行业的发展&#xff0c;远程通信的方式已经从以前的书信、音频转变为现在的音频/视频。和 视频在工作、学习和娱乐中的比例不断提高&#xff0…

Kubectl 部署有状态应用(下)

接上文 《Kubectl 部署有状态应用&#xff08;上&#xff09;》创建完StatefulSet后&#xff0c;本文继续介绍StatefulSet 扩展、更新、删除等内容。 StatefulSet 中的 Pod 验证序数索引和稳定的网络身份 StatefulSet 中的 Pod 具有唯一的序数索引和稳定的网络身份。 查看 …

【单调栈】LeetCode:1944队列中可以看到的人数

作者推荐 【贪心算法】【中位贪心】.执行操作使频率分数最大 本文涉及的基础知识点 单调栈分类、封装和总结 题目 有 n 个人排成一个队列&#xff0c;从左到右 编号为 0 到 n - 1 。给你以一个整数数组 heights &#xff0c;每个整数 互不相同&#xff0c;heights[i] 表示…

【软考中级】网络工程师:8.网络安全

本章考察内容比较广泛&#xff0c;考题对知识点都会有所涉及。 8.1 网络安全的基本概念 8.1.1 网络安全威胁的类型 窃听 这种情况发生在广播式网络系统中&#xff0c;每个节点都可以读取数据&#xff0c;实现搭线窃听、安装通信监视器和读取网上的信息等。 假冒 当一个实体…

python使用opencv提取视频中的每一帧、最后一帧,并存储成图片

提取视频每一帧存储图片 最近在搞视频检测问题&#xff0c;在用到将视频分帧保存为图片时&#xff0c;图片可以保存&#xff0c;但是会出现(-215:Assertion failed) !_img.empty() in function cv::imwrite问题而不能正常运行&#xff0c;在检查代码、检查路径等措施均无果后&…