3分30秒

3分30秒

(function (window, document) {

  

  const methods = { // 公共方法


    // 添加元素

    appendChild(parent, ...children) {

      children.forEach(el => {

        parent.appendChild(el);

      })

    }, // methods.appendChild(parent, el1, el2)


    // 获取元素

    $(selector, root = document) {

      return root.querySelector(selector);

    }, // methods.$('#wrap')  ==> document.querySelector('#wrap')

       // root默认是document 如果有传第二个参数parent => parent.querySelector('#wrap')


    // 获取多个元素

    $$(selector, root = document) {

      return root.querySelectorAll(selector);

    },


  }



  let Img = function(options) {

    this._init(options);

    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);  // 挂载点 wrap


    this.imgContainer = null;            // 所有图片的容器

    this.wrap = null;                    // 整体容器

    this.typeBtnEls = null;              // 所有分类按钮组成的数组

    this.figures = null;                 // 所有当前显示的图片组成的数组


    this._classify(data);  // 接收图片的数据 分类图片


    console.log(this.classified);

  };


  // 图片分类 

  // all => 类型1 类型2 类型3 类型2

  //         0      1     2     3

  // classified : {'类型1' :all[0], '类型2 :all[1,3], '类型3' : all[2]}

  Img.prototype._classify = function(data) {

    let srcs = [];    // 记录已经分类过的图片的src


    data.forEach(({ title, type, alt, src}, index) => {

      if (!this.types.includes(type)) {   // includes 查看types所有分类中 有没有当前获取到的分类 没有就加上这个分类

        this.types.push(type);

      }


      if (!Object.keys(this.classified).includes(type)) {  // Object.keys 返回对象的所有属性名 并组成数组

        this.classified[type] = [];     // 如果没有这个类型 给这个类型赋为空数组

      }


      // 如果图片还没有生成并分类

      if (!srcs.includes(src)) { 

        srcs.push(src);   // 记录到srcs中

        

        let figure = document.createElement('figure');          // 生成图片容器

        let img = document.createElement('img');                // 放置图片

        let figcaption = document.createElement('figcaption');  // 图片显示信息


        img.src = src;

        img.setAttribute('alt', alt)  // 设置img标签的alt属性并赋值

        figcaption.innerText = title;


        // 使用定义好的方法添加元素

        methods.appendChild(figure, img, figcaption);

        // 把图片添加到all 所有图片中

        this.all.push(figure);

        // 把图片添加到对应分类中  从all中获取图片 因为是push进all里面的 所以都是取all的最后一位就对了

        this.classified[type].push(this.all.length -1);

      } 


      // 如果图片已经生成分类过了  到srcs(记录已经分类过的图片)中找到图片 添加到对应分类

      else {

        // findIndex 返回符合条件的第一个位置 如果srcs中有图片全等于src 就把这个图片的下标返回出来 然后图片添加到当前分类中

        this.classified[type].push(srcs.findIndex(function(s1) { return s1 === src }))

      }


    })

  }



  // 根据分类获取图片

  Img.prototype._getImgsByType = function(type) {

    // 如果当前分类是全部 直接返回all 所有图片

    // 分类不是全部 遍历当前类型的图片 返回all中对应的图片              function(index) { return this.all[index] }

    return type === '全部' ? [...this.all] : this.classified[type].map(index => this.all[index])

  }



  // 生成DOM

  Img.prototype._createElement = function() {

    let typesBtn = [];  // 存放每个按钮的HTML字符串

    

    // 生成每个类型按钮的模板字符串

    for (let type of this.types) { // 遍历全部类型的值   全部 JavaScript 前端框架...

      //   如果类型 === 当前显示的类型 再给它添加高亮样式类名

      typesBtn.push(`<li class="__Img__classify__type-btn${ type === this.curType ? ' __Img__type-btn-active' : '' }">${ type }</li>`);

    }


    // 整体的模板字符串

    let tamplate = 

      `<ul class="__Img__classify">${ typesBtn.join('') }</ul>

      <div class="__Img__img-container"></div>`


    // 最大的容器

    let wrap = document.createElement('div');

    wrap.className = '_Img_container';

    wrap.innerHTML = tamplate;


    // 选出图片的容器元素 因为要往里面放图片

    this.imgContainer = methods.$('.__Img__img-container', wrap);


    // 调用设置好的获取图片方法 获取当前显示的分类图片 插入到图片容器中  获取到的图片是数组 用扩展运算符展开

    methods.appendChild(this.imgContainer, ...this._getImgsByType(this.curType));


    this.wrap = wrap;

    // 获取所有分类按钮DOM元素

    this.typeBtnEls = methods.$$('__Img__classify__type-btn', wrap) 

    // 图片墙上的所有图片

    this.figures = methods.$$('figure', wrap); 


    // 遮罩层

    let overlay = document.createElement('div');

    overlay.className = '_Img_overlay';

    overlay.innerHTML = `

        <div class="__Img__overlay-prev-btn"></div>

        <div class="__Img__overlay-next-btn"></div>

        <img src="/assets/images/1.jpg" alt="">`

    // 把遮罩层插入到wrap中

    methods.appendChild(this.wrap, overlay);

    this.overlay = overlay;

    // 获取要放大显示的图片元素

    this.previewImg = methods.$('img', overlay)


  };


  // 绑定事件

  Img.prototype._bind = function() {


  };

  

  // 显示元素

  Img.prototype._show = function() {

    // 把生成的wrap插入到现实中的挂载点上

    methods.appendChild(this.parasitifer, this.wrap);


    // 遍历图片墙上的图片 修改样式显示

    setTimeout(() => {

      this.figures.forEach(figure => {

        figure.style.transform = 'scale(1,1)';

        figure.style.opacity = '1';

      })

    })

  };



  window.$Img = Img;  // 将Img构造函数挂载到window上

})(window, document);


请问老师,我显示的效果和视频3分30秒时不一样,鼠标指着图片也没有显示遮罩层,还有一个报错,找不到1.jpg,文件我都是复制源码过来的:Failed to load resource: net::ERR_FILE_NOT_FOUNDhttp://img1.sycdn.imooc.com//climg/5f291eb80924ffcb05730775.jpg

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

3回答
提问者 慕标1234374 2020-08-04 17:05:19

自己找到原因了,添加DOM时类名的下划线写错了

提问者 慕标1234374 2020-08-04 16:41:28
  • 提问者 慕标1234374 #1
    css我是在源码复制过来的,是视频后面还会通过js进行修改吗
    2020-08-04 16:47:27
提问者 慕标1234374 2020-08-04 16:40:43

请问老师,我显示的效果和视频3分30秒时不一样,鼠标指着图片也没有显示遮罩层,还有一个报错,找不到1.jpg,文件我都是复制源码过来的:Failed to load resource: net::ERR_FILE_NOT_FOUND

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师