Js进阶案例合集

案例一:渲染商品

CSS代码

注意CSS中tab栏切换的简便写法


HTML代码


  

JS初始代码

模块一:封装渲染函数

function render(arr) {
      let str = ''
      //item指当前数组元素即对象
      arr.forEach(item => {
        const { name, price, picture } = item
        str += `
         

${name}

${price}

` }) document.querySelector('.list').innerHTML = str } render(goodsList)

精华:提前声明一个空字符串,用字符串拼接的方法生成结构添加到页面中

模块二:筛选商品

document.querySelector('.filter').addEventListener('click', e => {
      const { tagName, dataset } = e.target
      if (tagName === 'A') {
        // arr是返回的新数组
        let arr = goodsList //这样赋值点击4就把全部商品进行渲染
        if (dataset.index === '1') {
          arr = goodsList.filter(item => item.price > 0 && item.price <= 100)
        } else if (dataset.index === '2') {
          arr = goodsList.filter(item => item.price >= 100 && item.price <= 300)
        } else if (dataset.index === '3') {
          arr = goodsList.filter(item => item.price >= 300)
        }
        //调用渲染函数
        render(arr)
      }
    })

精华:

1.filter()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素

主要使用场景:筛选数组符合条件的元素,并返回筛选之后元素的新数组

2.arr是返回的新数组,初始化赋值为goodsList,因为事件委托点击对象必定为链接,在判断条件中没有对4号进行特判,这样赋值能满足点击4就把全部商品进行渲染的需求


案例二:购物车 

CSS代码


HTML代码

合计:1000.00

JS初始代码

模块一:更换数据模块

document.querySelector('.list').innerHTML = goodsList.map(item => {
      const { picture, name, count, price, spec, gift } = item//对象解构
      //规格文字模块处理
      const text = Object.values(spec).join('/')
      //赠品模块处理
      const str = gift ? gift.split(',').map(item => `【赠品】${item} `).join('') : ''
      //计算小计模块 单价 * 数量  保留两位小数
      // 注意精度问题,因为保留两位小数,所以乘以 100  最后除以100
      const subTotal = ((price * 100 * count) / 100).toFixed(2)
      return `
    

${name} ${str}

${text}

${price.toFixed(2)}

x${count}

${subTotal}

` }).join('')

总体思路:

先利用map来遍历,有多少条数据就渲染多少商品,注意map返回值是数组,我们需要用join 转换为字符串,再把返回的字符串赋值给list大盒子的innerHTML

具体处理:

先更换不需要处理的数据,图片,商品名称,单价,数量,采取对象解构的方式,注意单价要保留2位小数,toFixed(2)

处理规格文字模块:获取每个对象里面的spec , 用Object.values()获得所有属性值返回的是数组,再使用join(‘/’)这样就可以转换为符合格式要求的字符串了

处理赠品模块:获取每个对象里面的gift , 注意要判断是否有gift属性,没有的话不需要渲染,如果有的话先用split(‘,’)方法把字符串拆分为数组,再利用map遍历数组,同时把数组元素生成到span里面,再使用join(‘’)转换为字符串

精度问题:

关于小数的计算精度问题

0.1 + 0.2 = ?

解决方案:我们经常转换为整数(0.1*100 + 0.2*100)/ 100 === 0.3

模块二:合计模块

const total = goodsList.reduce((prev, item) => prev + (item.price * 100 * item.count) / 100, 0)
    document.querySelector('.amount').innerHTML = total.toFixed(2)

求和用到数组reduce 方法累计器,根据数据里面的数量和单价累加和即可,注意reduce方法有2个参数,第一个是回调函数,第二个是初始值,遇到对象数组起始值必先设置为0


案例三:模态框的封装

CSS代码


HTML代码


  

  

练习面向对象写插件(模态框)

模块一:制作Modal构造函数

function Modal(title = '', message = '') {
      //创建div标签
      this.modalBox = document.createElement('div')
      //给div标签添加类名为modal
      this.modalBox.className = 'modal'
      //modal盒子内部填充2个div标签并且修改文字内容
      this.modalBox.innerHTML = `
     
${title} x
${message}
` }

模块二:open方法

 Modal.prototype.open = function () {
      //先来判断页面中是否有modal盒子,如果有先删除,否则继续添加
      const box = document.querySelector('.modal')
      box && box.remove()
      //注意这个方法不要用箭头函数,因为我们需要使用this
      //把刚才创建的modalBox显示到页面body中
      document.body.append(this.modalBox)

      //要等着盒子显示出来,就可以绑定点击事件了
      this.modalBox.querySelector('i').addEventListener('click', () => {
        //这个地方需要用到箭头函数
        //这里的this指向实例对象
        this.close()
      })
    }

需要写在构造函数的原型对象上,共享方法 

open 打开的本质就是把创建标签添加到页面中,把刚才创建的modalBox添加到页面body 标签中

需要注意,x 删除按钮绑定事件,要写到open里面添加,因为只有等到盒子显示出来,才可以绑定点击事件

为了避免多次点击x 删除按钮所导致的出现多个模态框的情况,我们在给构造函数原型对象挂载open方法时需要先来判断页面中是否有modal盒子,如果有先删除,否则继续添加,这里使用&&的逻辑中断方法十分合适

关于此处this的指向问题,必须明确这步代码的操作对象究竟是谁才能选择正确。要注意:箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this

模块三:close方法

Modal.prototype.close = function () {
      this.modalBox.remove()
}

需要写在构造函数的原型对象上,共享方法 

把刚才创建的modalBox从页面body 标签中删除

document.querySelector('#delete').addEventListener('click', () => {
      const del = new Modal('温馨提示', '您没有权限删除')
      del.open()
    })

    document.querySelector('#login').addEventListener('click', () => {
      const login = new Modal('友情提示', '您还没有注册账号')
      login.open()
    })

你可能感兴趣的:(javascript,css,前端)