温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

ES6中怎么实现图片切换特效

发布时间:2021-08-09 17:25:49 来源:亿速云 阅读:163 作者:Leah 栏目:开发技术

这篇文章给大家介绍ES6中怎么实现图片切换特效,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

demo.html

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>Document</title></head><body>  <script type="text/javascript">    let arr = ["前端", "jquery", "javascript", "html", "css"];    //补充代码    let lis='';    let ul = document.createElement('ul');    function appendHTML( ...innerhtml){      innerhtml.forEach(el => {        let templates = `<li>`+el+`</li>`;        lis+=templates;       });      return lis;    }    appendHTML(...arr);    ul.innerHTML=lis;    document.body.appendChild(ul);  </script></body></html>

style.css

* { margin: 0; padding: 0;}body { background: #fafafa; background: url('../images/bg.png')}::-webkit-scrollbar { display: none;}#wrap { width: 1065px; padding-top: 50px; margin: 0 auto; padding: 30px; background: rgb(255, 255, 255); border-radius: 2px; margin-top: 100px;}/* 整体容器 */.__Img__container { font-size: 10px;}/* 分类容器 */.__Img__container .__Img__classify { /* text-align: center; */}/* 分类按钮 */.__Img__container .__Img__classify .__Img__classify__type-btn { display: inline-block; padding: .2em 1em; font-size: 1.6em; margin-right: 10px; cursor: pointer; border: 1px solid #e95a44; outline: none; color: #e95a44; transition: all .4s; user-select: none; border-radius: 2px;}/* 激活状态的分类按钮 */.__Img__container .__Img__classify .__Img__classify__type-btn.__Img__type-btn-active { background: #e95a44; /* border: 1px solid #9b59b6; */ color: #fff;}/* 所有图片容器 */.__Img__container .__Img__img-container { position: relative; margin-top: 30px; width: 1005px; display: flex; flex-wrap: wrap; transition: all .6s cubic-bezier(0.77, 0, 0.175, 1);}/* 单个图片容器 */.__Img__container .__Img__img-container figure { width: 240px; height: 140px; position: absolute; transition: all .6s cubic-bezier(0.77, 0, 0.175, 1); transform: scale(0, 0); opacity: 0; overflow: hidden; border-radius: 2px; user-select: none;}/* 伪元素遮罩层 */.__Img__container .__Img__img-container figure::before { display: block; position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 4; background: rgba(58, 12, 5, 0.5); content: ' '; font-size: 0; opacity: 0; transition: all .3s; cursor: pointer;}/* 图片 */.__Img__container .__Img__img-container figure img { display: block; width: 100%; height: 100%; transition: all .3s;}/* 图片标题 */.__Img__container .__Img__img-container figure figcaption { position: absolute; top: 50%; left: 50%; z-index: 7; opacity: 0; font-size: 1.5em; color: rgb(255, 255, 255); transform: translate(-50%, -50%); transition: all .3s; text-align: center; cursor: pointer;}/* 悬停图片的时候标题显示 */.__Img__container .__Img__img-container figure:hover figcaption { opacity: 1;}.__Img__container .__Img__img-container figure:hover img { transform: scale(1.1, 1.1);}/* 悬停图片的时候遮罩显示 */.__Img__container .__Img__img-container figure:hover::before { opacity: 1;}.__Img__overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, .8); display: flex; justify-content: center; align-items: center; opacity: 0; transition: all .3s; display: none;}.__Img__overlay .__Img__overlay-prev-btn,.__Img__overlay .__Img__overlay-next-btn { position: absolute; width: 50px; height: 50px; border-radius: 50%; border: 2px solid white; text-align: center; line-height: 50px; color: white; font-size: 2rem; cursor: pointer;}.__Img__overlay .__Img__overlay-prev-btn { left: 20px;}.__Img__overlay .__Img__overlay-next-btn { right: 20px;}.__Img__overlay .__Img__overlay-prev-btn:active,.__Img__overlay .__Img__overlay-next-btn:active { background: rgb(241, 241, 241, .4);}.__Img__overlay .__Img__overlay-next-btn::after { content: "N";}.__Img__overlay .__Img__overlay-prev-btn::after { content: "P";}.__Img__overlay img { transform: scale(2, 2);}index.js// 1. 对图片进行分类// 2. 生成dom元素// 3. 绑定事件// 4. 显示到页面上// 以插件形式完成(function (window, document) { let canChange = true; let curPreviewImgIndex = 0; // 公共方法集合  const methods = {   // 以数组形式添加子元素   appendChild(parent, ...children) {    children.forEach(el => {     parent.appendChild(el);    });   },   // 选择器   $(selector, root = document) {    return root.querySelector(selector);   },   // 选择多个元素   $$(selector, root = document) {    return root.querySelectorAll(selector);   }  }; // 构造函数  let Img = function(options) {   // 初始化    this._init(options);   // 生成DOM元素    this._createElement();   // 绑定事件    this._bind();   // 显示到页面上    this._show();  } // 初始化  Img.prototype._init = function({ data, initType, parasitifer }) {   this.types = ['全部']; // 所有的分类   this.all = []; // 所有图片元素   this.classified = {'全部': []}; // 按照类型分类后的图片   this.curType = initType; // 当前显示的图片分类   this.parasitifer = methods.$(parasitifer); // 挂载点   this.imgContainer = null; // 所有图片的容器   this.wrap = null; // 整体容器   this.typeBtnEls = null; // 所有分类按钮组成的数组   this.figures = null; // 所有当前显示的图片组成的数组   // 对图片进行分类   this._classify(data);   //console.log(this.classified);//分类的结果  }; // 对图片进行分类  Img.prototype._classify = function(data) {   let srcs = [];   // 解构赋值,获取每张图片的四个信息   data.forEach(({ title, type, alt, src }) => {    // 如果分类中没有当前图片的分类,则在全部分类的数组中新增该分类    if (!this.types.includes(type)) {     this.types.push(type);    }    // 判断按照类型分类后的图片中有没有当前类型    if (!Object.keys(this.classified).includes(type)) {     this.classified[type] = [];    }    // 判断当前图片是否已生成    if (!srcs.includes(src)) {     // 如果图片没有生成过,则生成图片,并添加到对应的分类中     srcs.push(src);     let figure = document.createElement('figure');     let img = document.createElement('img');     let figcaption = document.createElement('figcaption');     img.src = src;     img.setAttribute('alt', alt);     figcaption.innerText = title;     // 在figure中添加img和figcaption     methods.appendChild(figure, img, figcaption);     // 将生成的figure添加到all数组中     this.all.push(figure);     // 新增的这个图片会在all数组中的最后一个元素     this.classified[type].push(this.all.length - 1);    } else {     // 去all中 找到对应的图片     // 添加到 对应的分类中     this.classified[type].push(srcs.findIndex(s1 => s1 === src));    }   });  }; // 根据分类获取图片  Img.prototype._getImgsByType = function(type) {   // 如果分类是全部,就返回所有图片   // 否则,通过map进行遍历,根据分类来获取图片数组   return type === '全部' ? [...this.all] : this.classified[type].map(index => this.all[index]);  }; // 生成DOM  Img.prototype._createElement = function() {   // 创建分类按钮   let typesBtn = [];   // 遍历分类数组   for (let type of this.types.values()) {    typesBtn.push(`     <li class="__Img__classify__type-btn${ type === this.curType ? ' __Img__type-btn-active' : '' }">${ type }</li>    `);   }   //console.log(typesBtn);//查看所有分类按钮   // 整体的模版    let tamplate = `     <ul class="__Img__classify">      ${ typesBtn.join('') }     </ul>     <p class="__Img__img-container"></p>    `;    let wrap = document.createElement('p');    wrap.className = '__Img__container';    wrap.innerHTML = tamplate;//生成整体元素    //取得所有图片的容器    this.imgContainer = methods.$('.__Img__img-container', wrap);    //查看当前分类下的图片    console.log(this._getImgsByType(this.curType));    // 把当前分类下的图片数组,插入到图片容器里    methods.appendChild(this.imgContainer, ...this._getImgsByType(this.curType));    //把可能有用的数据先挂到指定位置    this.wrap = wrap;    this.typeBtnEls = [...methods.$$('.__Img__classify__type-btn', wrap)];    this.figures = [...methods.$$('figure', wrap)];    // 遮罩层    let overlay = document.createElement('p');    overlay.className = '__Img__overlay';    overlay.innerHTML = `     <p class="__Img__overlay-prev-btn"></p>     <p class="__Img__overlay-next-btn"></p>     <img src="" alt="">    `;    // 把遮罩层添加到图片墙中    methods.appendChild(this.wrap, overlay);    this.overlay = overlay;    // 当前要预览的图片    this.previewImg = methods.$('img', overlay);    // 移动每张图片到合适的位置    this._calcPosition(this.figures);   }; // 获取上一次显示的图片和下一次显示的图片中,相同的图片下标(映射关系)  Img.prototype._diff = function(prevImgs, nextImgs) {   let diffArr = [];//保存两次中相同的数据的下标   //遍历前一次的所有图片   //如果在下一次中存在相同的,则获取下标index2   prevImgs.forEach((src1, index1) => {    let index2 = nextImgs.findIndex(src2 => src1 === src2);    if (index2 !== -1) {     // 在这个映射数组中存入下标     diffArr.push([index1, index2]);    }   });   return diffArr;  }; // 绑定事件  Img.prototype._bind = function() {   // 事件代理,点击事件绑定在ul上    methods.$('.__Img__classify', this.wrap).addEventListener('click', ({ target }) => {     if (target.nodeName !== 'LI') return;     if (!canChange) return;     canChange = false;     const type = target.innerText;//获取按钮上的文字(图片类型)     const els = this._getImgsByType(type);//获取对应类型的图片     let prevImgs = this.figures.map(figure => methods.$('img', figure).src);//上一次显示的图片数组     let nextImgs = els.map(figure => methods.$('img', figure).src);//下一次显示的图片数组     const diffArr = this._diff(prevImgs, nextImgs);//获取两次相同图片的映射关系(下标)     diffArr.forEach(([, i2]) => {      // 对下一次的所有图片进行遍历      this.figures.every((figure, index) => {       let src = methods.$('img', figure).src;       // 如果下一次的图片在这一次中已经出现过       if (src === nextImgs[i2]) {        // 则从所有图片数组中剔除该图片(从Index位置,裁剪1个)        this.figures.splice(index, 1);        return false;       }       return true;      });     });     // 计算图片位置     this._calcPosition(els);     let needAppendEls = [];     if (diffArr.length) {      // 如果存在相同图片      let nextElsIndex = diffArr.map(([, i2]) => i2);      els.forEach((figure, index) => {       // 如果该图片没有出现过,则需要插入       if (!nextElsIndex.includes(index)) needAppendEls.push(figure);      });     } else {      // 如果不存在相同图片      needAppendEls = els;//需要插入的图片=所有图片     }     // 上一次的图片全部隐藏掉     this.figures.forEach(el => {      el.style.transform = 'scale(0, 0) translate(0%, 100%)';      el.style.opacity = '0';     });     // 把下一次需要显示的图片添加到图片容器中     methods.appendChild(this.imgContainer, ...needAppendEls);     // 设置下一次显示的动画     setTimeout(() => {      // els表示所有图片,包括新增的,和上一次已经显示过的      els.forEach(el => {       el.style.transform = 'scale(1, 1) translate(0, 0)';       el.style.opacity = '1';      });     });     // 从DOM中销毁上一次出现的图片,将图片数组转为下一次要现实的图片     setTimeout(() => {      this.figures.forEach(figure => {       this.imgContainer.removeChild(figure);      });      this.figures = els;      canChange = true;      // 保证在一次切换动画没有完成之前,拒绝进行下一次切换      // 避免快速切换     }, 600);     // 给图片按钮添加切换时的动画效果     this.typeBtnEls.forEach(btn => (btn.className = '__Img__classify__type-btn'));     target.className = '__Img__classify__type-btn __Img__type-btn-active';    });   // 事件代理实现点击图片的效果    this.imgContainer.addEventListener('click', ({ target }) => {     // 如果点击的不是图片或者图片描述,则返回     if (target.nodeName !== 'FIGURE' && target.nodeName !== 'FIGCAPTION') return;     // 如果点击的是图片的描述     // 则把target转为其父元素图片     if (target.nodeName === 'FIGCAPTION') {      target = target.parentNode;     }     const src = methods.$('img', target).src;     // 拿到当前图片索引     curPreviewImgIndex = this.figures.findIndex(figure => src === methods.$('img', figure).src);     this.previewImg.src = src;//把当前图片的src属性赋值给预览图     this.overlay.style.display = 'flex';//设置遮罩层布局显示     setTimeout(() => {      this.overlay.style.opacity = '1';//设置遮罩层显示     });    });   // 预览时点击遮罩层,实现预览退出    this.overlay.addEventListener('click', () => {     this.overlay.style.opacity = '0';     // 箭头函数可以保留最初的this指向     setTimeout(() => {      this.overlay.style.display = 'none';     }, 300);    });   // 预览点击切换上一张    methods.$('.__Img__overlay-prev-btn', this.overlay).addEventListener('click', e => {     e.stopPropagation();//阻止事件冒泡     // 如果是第一张,上一张就是最后一张     curPreviewImgIndex = curPreviewImgIndex === 0 ? this.figures.length - 1 : curPreviewImgIndex - 1;     // 获取到需要上一张显示的图片的src,赋值给预览图的src     this.previewImg.src = methods.$('img', this.figures[curPreviewImgIndex]).src;    });   // 预览点击切换下一张    methods.$('.__Img__overlay-next-btn', this.overlay).addEventListener('click', e => {     e.stopPropagation();     // 如果是最后一张,下一张就是第一张     curPreviewImgIndex = curPreviewImgIndex === this.figures.length - 1 ? 0 : curPreviewImgIndex + 1;     this.previewImg.src = methods.$('img', this.figures[curPreviewImgIndex]).src;    });  }; // 显示元素  Img.prototype._show = function() {   methods.appendChild(this.parasitifer, this.wrap);   //设置出现的动画效果   setTimeout(() => {    this.figures.forEach(figure => {     figure.style.transform = 'scale(1, 1) translate(0, 0)';     figure.style.opacity = '1';    });   });  }; // 计算每张图片所占的位置  Img.prototype._calcPosition = function(figures) {   let horizontalImgIndex = 0;   figures.forEach((figure, index) => {    figure.style.top = parseInt(index / 4) * 140 + parseInt(index / 4) * 15 + 'px';    figure.style.left = horizontalImgIndex * 240 + horizontalImgIndex * 15 + 'px';    figure.style.transform = 'scale(0, 0) translate(0, -100%)';    horizontalImgIndex = (horizontalImgIndex + 1) % 4;   });   let len = Math.ceil(figures.length / 4);//总行数   this.imgContainer.style.height = len * 140 + (len - 1) * 15 + 'px';//解决绝对定位造成的父容器高度塌陷的问题  }; // 把生成的图片墙挂到全局 window.$Img = Img;})(window, document);data.js// 图片信息文件const data = [ {  type: 'JavaScript',  title: 'ES6快速入门',  alt: 'ES6快速入门',  src: './assets/images/1.jpg' }, {  type: 'JavaScript',  title: 'Javascript实现二叉树算法',  alt: 'Javascript实现二叉树算法',  src: './assets/images/2.jpg' }, {  type: 'JavaScript',  title: 'Canvas绘制时钟',  alt: 'Canvas绘制时钟',  src: './assets/images/3.jpg' }, {  type: 'JavaScript',  title: '基于websocket的火拼俄罗斯',  alt: '基于websocket的火拼俄罗斯',  src: './assets/images/15.jpg' }, {  type: '前端框架',  title: 'React知识点综合运用实例',  alt: 'React知识点综合运用实例',  src: './assets/images/4.jpg' }, {  type: '前端框架',  title: 'React组件',  alt: 'React组件',  src: './assets/images/5.jpg' }, {  type: '前端框架',  title: 'Vue+Webpack打造todo应用',  alt: 'Vue+Webpack打造todo应用',  src: './assets/images/6.jpg' }, {  type: '前端框架',  title: 'Vue.js入门基础',  alt: 'Vue.js入门基础',  src: './assets/images/7.jpg' }, {  type: '前端框架',  title: '使用Vue2.0实现购物车和地址选配功能',  alt: '使用Vue2.0实现购物车和地址选配功能',  src: './assets/images/8.jpg' }, {  type: 'React',  title: 'React知识点综合运用实例',  alt: 'React知识点综合运用实例',  src: './assets/images/4.jpg' }, {  type: 'React',  title: 'React组件',  alt: 'React组件',  src: './assets/images/5.jpg' }, {  type: 'Vue.js',  title: 'Vue+Webpack打造todo应用',  alt: 'Vue+Webpack打造todo应用',  src: './assets/images/6.jpg' }, {  type: 'Vue.js',  title: 'Vue.js入门基础',  alt: 'Vue.js入门基础',  src: './assets/images/7.jpg' }, {  type: 'Vue.js',  title: '使用Vue2.0实现购物车和地址选配功能',  alt: '使用Vue2.0实现购物车和地址选配功能',  src: './assets/images/8.jpg' }]

关于ES6中怎么实现图片切换特效就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

es6
AI