Skip to content

Latest commit

 

History

History
787 lines (744 loc) · 24.6 KB

总结笔记.md

File metadata and controls

787 lines (744 loc) · 24.6 KB

笔记

1.iframe内联框架

  1. 可引入一个页面嵌套在主页面中

  2. 内联框架在页面中全屏

    allowfullscreen='true';
    style='width=100%;higth=100%';
    frameborder=0;	//关闭iframe边框
    //以上是iframe的属性
  3. 引入页面

    src=' ';	//引入目标路径

2.自定义播放条

  1. 进度条和音量条

    1. 使用input中的type='range'代替作为拉动条

    2. 问题:

      1. 原始播放条太丑,修改原始播放条样式(已滑动)

        -webkit-appearance: none; //去除默认样式
        background: -webkit-linear-gradient(red, red) no-repeat;//设置背景颜色,也就是滚过去的播放条颜色填充
        backsize	//设置已拖动的长度,填充上颜色
      2. 滑动轨道

         background-image: url('../img/statbar.png');//设置轨道的背景
      3. 修改原始进度条的滑块样式

        ::-webkit-slider-thumb	//通过伪类来获取滑块
        -webkit-appearance: none;	//清除系统默认样式
    3. JS实现随歌曲播放进度条变化

      1. 使用timeupdate事件对audio实时监听,监听播放进度
      2. audio的currentTime属性获取现在时间
      3. audio的duration属性获取总时间
      4. 用currentTime/durtion计算出相对播放位置,用background-size改变背景填充颜色
    4. 实现手动拉动滚动条跳转

      1. 使用input时间对进度条进行监听,监听是否操作了进度条

      2. 用户拖动进度条时改变背景填充范围

        e.target.value	//滑动的长度
      3. 使用mouseup使用户松开时才跳转到指定播放位置

  2. 播放按钮

    1. 使用js将按钮与audio联系起来
    2. play( )方法 :播放
    3. pause( )方法:暂停
    4. paused属性:检测是否正在播放
  3. 待播清单

    1. 隐藏防止歌曲溢出盒子的滚动条

      xxx::-webkit-scrollbar{
      	width:0;	//使默认滚动条的宽度为0
      }
    2. 添加歌曲

      1. 思路:将已选的歌曲储存在session储存里,每一次添加歌曲就将相关信息储存在session存储的指定json字符创中,在列表中再将其加载出来

      2. 读取相关信息

        let name_value = name;
        let id_value = id;
        let musicname_value = musicname;
        let picurl_value = picurl;
      3. 储存到session中的指定json字符串,与之前的信息进行拼串处理

        let ARR =sessionStorage.getItem('arr');
        let x = ARR.length - 2;
        ARR = ARR.slice(0, x) + ',{"name":"' + name_value + '","id":' + id_value + ',"musicname":"' + musicname_value + '","picurl":"' + picurl_value + '"}' + ']}';	//拼成json字符串
        sessionStorage.setItem('arr', ARR);
      4. 读取信息创造节点,加载出列表

    3. 删除歌曲

      1. 思路:点击li上的垃圾箱图标,触发点击的事件,删除歌曲

      2. 取消点击事件冒泡,否则点击垃圾箱会一同触发其父元素li的点击事件

        event.cancelBubble = true;	//event是指定事件的相关信息
      3. 组成一个新的json字符串,除了删除的指定元素

        let arrdata = JSON.parse(sessionStorage.getItem('arr'));
        let arrnew = '{"arr":[{}';
        for (let j = 1; j < arrdata.arr.length; j++) {
            if (j != i + 1) {
                arrnew += ',{"name":"' + arrdata.arr[j].name + '","id":' + arrdata.arr[j].id + ',"musicname":"' + arrdata.arr[j].musicname + '","picurl":"' + arrdata.arr[j].picurl + '"}';	
            }	//执行除了指定元素的循环进行拼串
        
        }
        arrnew += ']}';
        sessionStorage.setItem("arr", arrnew);
      4. 重新读取信息创造节点,加载出列表

3.自定义搜索框

  1. input的type为text,并设置默认文字

    placeholder="常言道";
  2. 为放大镜的图标设置点击跳转页面的事件

    1. 检测是否有键入搜索关键词

      if (searchBox.value == '') {
          searchurl = defaultUrlHeader + '/cloudsearch?keywords=' + '常言道' + '&limit=20&offset=0';
      } else {
          searchurl = defaultUrlHeader + '/cloudsearch?keywords=' + searchBox.value + '&limit=20&offset=0';
      }	
    2. 储存相关信息到session储存

      sessionStorage.setItem("search", searchurl);
      sessionStorage.setItem("search_key", searchBox.value);
    3. 跳转页面

      注:由于搜索框是在内联样式iframe里面的,而跳转页面是修改iframe的src属性,所以必须先跳转到上一级父元素,然后才能修改iframe的src属性,以下跳转均如此

      parent.inner.src = '../5.搜索歌曲页面/5.搜索歌曲页面.html';
  3. 实现敲击键盘enter跳转搜索

    1. 获取键盘按下的键

      var code = window.event.keyCode;
    2. 判断是否为enter键

      if(code == 13)
    3. 其余步骤与上面点击事件类似

4.ajax封装

  1. 存储的默认值

    var defaults = {
        url: '',
        header: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        success: function () { },
        error: function () { }
    }
  2. 使用options对象中的属性覆盖defaults对象中的属性

    Object.assign(defaults, options);
  3. 创建并配置ajax对象

    var xhr = new XMLHttpRequest();
    xhr.open('GET', defaults.url);
     xhr.send();	//默认get请求
  4. 当xhr接收完响应数据后触发

    xhr.onload = function () {
        // 服务端返回的数据
        var responseText = xhr.responseText;
        responseText = JSON.parse(responseText);
        // 当http状态码为200时
        if (xhr.status == 200) {
            // 请求成功,调用处理成功情况的函数
            defaults.success(responseText);
        } else {
            // 请求失败,调用请求失败的函数
            defaults.error(responseText);
        }
    
    }

5.获取cookie中的指定数据(封装成getcookie函数)

  1. 将其中的cookie键值对字符串用;隔开组成数组

    var cookieArray = document.cookie.split(";");
  2. 将新生成的数组中的元素再次分割为数组,第一位则为键名,第二位则为值

    for (var i = 0; i < cookieArray.length; ++i) {
        var cookies = cookieArray[i].split("=");
        if (cookies[0].trim() == name) {
            return cookies[1];	//返回要寻找键名的值
        }
    }
  3. 找不到要寻找的键名,返回空

    if (i == cookieArray.length) {
        return "";
    }

6.登录模块

  1. 电话登录:/login/cellphone

    1. 调出登录框,调用接口

    2. 登录成功在session中储存返回的用户个人信息

    3. 填入头像等信息

    4. 如果有勾选记住密码,则储存在cookie中(即储存在浏览器中)

      储存cookie中思路:

      1. 可以储存在浏览器中
      2. 传入一个rem,表示会不会自动登录,值为true或false
      3. 如果有记住密码,rem的值就为true(调用getcookie函数)
      4. 下一次打开的时候如果rem值为true,则自动登录
      5. 如果不勾选,则rem为false
      6. 下一次进入得手动输入密码
    5. 登录对账号进行正则判断

      1. 对账号输入框进行时间绑定,keyup事件,检测键盘按键被松手

      2. 对文本框里的内容进行正则表达式的判断

        var num1 = SignUp_phone.value;
        // 验证电话的正则表达式
        var reg = /^1[34578][0-9]{9}$/;
         if (!reg.test(num1))
      3. 显示提示信息

      4. 注:输入正确的格式后会给登录按钮绑定点击事件,所以在输入正确的格式后再次输入错误的格式,点击登录按钮时,会发送一个请求,但是设计的效果应该是:格式错误就不能发送请求,正确才能发送;解决:在输错的时候再一次将登录按钮点击事件重置,则不会发送无用的请求(只能用onclick)

  2. 邮箱登录:/login(实现方式同上)

  3. 退出登录:/logout

    1. 清除所有储存的数据
    2. 将cookie中的rem改为false,防止下次记住密码自动登录
    3. 将头像等信息去掉
  4. 注册:/register/cellphone

    1. 调出指定注册页面
    2. 传入相关参数
    3. 发送验证码:/captcha/sent
    4. 验证验证码:/captcha/verify
  5. 打开浏览器记住登录状态

    1. 从cookie中取值,判断rem是否为true
    2. rem为true的话,自动登录,不需要手动登陆

7.轮播图模块

  1. 调用接口:/banner?type=0

  2. 创造节点填入图片

  3. 实现轮播思路(前提:使用迭代器让其按顺序执行)

    1. 让即将出现的元素先display:block,但是还是透明的状态

      function one() {
          setTimeout(() => {
              roll_li[after].style.display = "block";
              iterator.next();
          }, 1);
      }
    2. 让即将出现的元素透明度慢慢提升,让要消失的图片透明度慢慢下降,并且两者同时进行,即可达到淡入淡出的效果

      function two() {
          setTimeout(() => {
              setPointer(after);
              roll_li[font].className = "roll_li hidden";
              roll_li[after].className = "roll_li visible";
              iterator.next();
          }, speed);
      }
    3. 让原来的元素display:none

      function three() {
          setTimeout(() => {
              roll_li[font].style.display = "none";
              iterator.next();
          }, 201);
      }
    4. 执行

      function* gen() {
          yield one();
          yield two();
          yield three();
      }
      
      let iterator = gen();
      iterator.next();
    5. 将以上步骤封装为一个函数move

      参数:font:上一张;after:下一张;speed:淡入淡出速度

    6. 实现自动轮播

      timer = setInterval(function () {
          if (index == 9) {
              index = 0;
              move(9, 0, 200);
          } else {
              font = index;
              after = index + 1;
              move(font, after, 200);
              index++;
          }
      }, 3000);
    7. 限流函数

      function throttle(func, wait) {
          var _this, arg;
          var prev = 0; // 上一次触发的时间,第一次默认为0
          return function () {
              var now = Date.now(); // 触发时的时间
              _this = this;
              if (now - prev > wait) {
                  func.apply(_this, arg); // 允许传入参数,并修正this
                  prev = now; // 更新上一次触发的时间
              }
          }
      }
    8. 点击导航点跳转图片

      for (let i = 0; i < pointer.length; i++) {
          pointer[i].num = i;
          // 点击跳转,并且开启节流,防止用户误操作
          pointer[i].addEventListener("click", throttle(function () {
              // 防止用户重复点正在显示的照片
              if (roll_li[this.num].className != 'roll_li visible') {
                  let tiao = this.num;
                  clearInterval(timer);
                  move(index, tiao, 1);
                  index = tiao;
                  automove();
              }
          }, 2900))
      }
    9. 箭头跳转,略

    10. 鼠标移入暂停:添加鼠标移入事件,鼠标移入则关闭定时器

8.歌单导入模块

  1. 调用接口:/personalized

  2. 封装创造节点函数(创造歌单节点)

    由于获得的歌单要运用到两个板块里,所以封装时引入了三个参数:

    ​ num:热门推荐(0)或者是个性化推荐(1)

    ​ font:第一张的索引

    ​ after:最后一张的索引

  3. 将数据传入,并给每一个歌单绑定一个点击事件,点击保存歌单的id到session储存,并且保存其type为歌单,点击跳转页面到歌单详情

9.专辑导入模块

  1. 调用接口:/album/newest
  2. 创造节点(创造专辑节点)
  3. 实现轮播:点击改变css样式即可

10.排行榜模块

  1. 调用接口:/playlist/detail
  2. 创造节点(创造排行榜数据节点)
  3. 绑定点击跳转页面事件
  4. 绑定添加到待播清单的功能(模块2)
  5. 绑定添加到我的歌单的功能(模块11)

11.添加歌曲至我的歌单模块

  1. 调用接口:

    获取我的歌单: /user/playlist(带上cookie和timestamp)

    对我的歌单进行添加歌曲: /playlist/tracks?op=add

  2. 将隐藏的我的歌单的框显示出来

  3. 创造节点引入我的歌单

  4. 绑定点击事件,点击某个歌单后,取消其他选中的颜色,使刚选中的变色,并将改歌单的id储存到session储存里

    for (let k = 0; k < results.playlist.length; k++) {
        plusMusic_li[k].style.backgroundColor = '';
    }
    li.style.backgroundColor = '#9d9d9d';
    sessionStorage.setItem('select_musiclist', results.playlist[j].id);
  5. 点击取消按钮,使歌单内容区的内容消失,并使歌单隐藏

    plusMusic_ul[0].innerHTML = '';
    plusMusic_div[0].style.display = 'none';
  6. 点击确认按钮,发送添加歌曲请求后,返回添加成功,歌单内容区的内容消失,并使歌单隐藏

    alert("添加成功");
    plusMusic_ul[0].innerHTML = '';
    plusMusic_div[0].style.display = 'none';

12.添加歌单模块

  1. 接口:/playlist/create

  2. 实现思路:

    1. 将创建歌单名的弹窗给显示出来
    2. 给取消按钮绑定点击事件,点击取消按钮就会隐藏改弹窗
    3. 给确认按钮绑定点击事件,点击确认按钮就会发送请求,刷新页面,获得新创建的歌单

13.删除歌单模块(可批量)

  1. 接口:

    1. 歌单:/playlist/delete(可批量)
    2. 专辑:/album/sub?t=0(不可批量)
  2. 实现思路:

    1. 循环遍历所有的歌单,如果遇到选中的,就将其拼串成多个歌单连成的格式

      for (let k = 0; k < playlistlen; k++) {
          if (check[k].checked != '') {
              deleteurl = deleteurl +','+ result.playlist[k].id;
          }
      }
    2. 去除连成的歌单字符串中的第一个逗号,再与接口拼接

      deleteurl=deleteurl.slice(1);
      let timestamp=(new Date()).valueOf();
      deleteurl='https://autumnfish.cn/playlist/delete?id='+deleteurl+'&cookie='+user_2.cookie+'&timestamp='+timestamp;
    3. 请求发送成功后刷新页面

    4. 点击编辑按钮取消按钮等略

  3. 注意:删除专辑只能一个个删除,不能批量删除

14.修改个人信息模块

  1. 接口:/user/update

  2. 思路:

    1. 将input文本框里的数据作为参数传递

    2. 生日日期上传格式转化:(转化为时间戳)

      timer = new Date(birthday.value).getTime();
  3. 将修改的信息重新显示到页面上(刷新)

    1. 生日日期从时间戳转化回来:

      let birth = formatDateT(result.profile.birthday);
      let newbirth = birth.split('T');
      birthday.value = newbirth[0];
    2. 将时间戳转化为日期格式的函数formatDateT

      function formatDateT(dataTime) {
          var newDate = new Date(dataTime + 8 * 3600 * 1000)	//转化为北京时间,因为使用toISOString会丢失时区
          return newDate.toISOString()	//使用ISO标准将时间戳转化
      }
  4. 修改绑定手机号:/rebind

  5. 修改密码:/register/cellphone

15.歌单专辑详情模块(评论,删除本人歌单歌曲)

  1. 接口

    1. 歌单:/playlist/detail
    2. 专辑:/album
  2. 获取相关信息填入

    1. 介绍文本填入需处理

      if (text) {		//判断是否有介绍
          // 正则表达式判断文本中的所有句号,改成换行
          texts = text.replace(new RegExp('。', 'g'), '。<br><br>');
          info_intr[0].innerHTML = '介绍:' + texts;
          info_more_intr[0].innerHTML = '介绍:' + texts;
          more[0].innerHTML = '展开';
      }
    2. 展开收起按钮:设置点击事件使文本框隐藏和显示即可

  3. 创造节点,将获取到的歌曲填入

    此处有一个分类,即是否为自己的歌单

    1. 如果不是自己的歌单,可以将歌曲收藏至自己的歌单(模块11)

    2. 如果为自己的歌单,可删除歌单中的歌曲

      1. 调用接口:/playlist/tracks?op=del
      2. 传入所选歌曲的id即可删除,并刷新

    其他共同点

    1. 添加歌曲到待播清单(模块2)
    2. 可点击歌曲跳转页面(歌曲详情,歌手详情,专辑页)
    3. 可以自动播放
    4. 可以切换上一首下一首
  4. 获取评论

    1. 接口:

      1. 歌单:/comment/playlist
      2. 专辑:/comment/album
    2. 创造节点获取评论

  5. 评论

    1. 接口:/comment?t=1&type=

    2. 实现思路:

      1. 发送成功后,利用gif图代替评论刷新一下
      2. 返回评论数据
  6. 获取相关推荐

    1. 接口:

      1. 歌单:/related/playlist
      2. 专辑:/album/newest
    2. 获取内容创造节点

16.搜索页面模块(分页)

  1. 接口:/cloudsearch

  2. 实现思路:

    1. 首页搜索后会将地址储存在session中,此处直接调用
    2. 发送请求,只加载20条,将总条数/20(即最大页数储存在session中,后边分页用到),并将当前页面0储存在session中
    3. 创造节点填入数据
    4. 并将页码也填入
  3. 歌曲功能与上文的歌单中是一样的,均可以自动播放,上一首,下一首,添加到待播清单,收藏到我的歌单里,点击相关信息跳转页面

  4. 分页功能(最大数据量调整为18页)

    1. 首页/尾页:储存目标页,改变接口里的offset偏移页数
    2. 上一页/下一页:获取现在的页数,进行加一或减一操作(有限制范围),同样改变接口便宜数量
    3. 操作完刷新即可

17.歌曲详情页面模块(歌词滚动同步)

  1. 判断歌曲是要继续播放还是重新加载,之前储存了ing

    注:ing为true即为歌曲正在播放,跳转过来无需重新加载

    ​ false为需要重新加载的情况,如切换歌曲

  2. 获取歌词

    1. 接口:/lyric

    2. 处理歌词

      // 处理每一句歌词
      function handle_lyric(content) {
          // 获取每一句的秒数
          var twoParts = content.split("]");
          //将时间前的"["截掉
          var time = twoParts[0].substr(1);
          var timeParts = time.split(":");
          var seconds = +timeParts[1];
          var min = +timeParts[0];
          seconds = min * 60 + seconds;
          //歌词获取
          var words = twoParts[1];
          if (words == "") {
              words = "<br>";
          }
          return {
              seconds: seconds,	//返回秒
              words: words,	//返回歌词
          };
      }
    3. 创造节点将歌词导入

    4. 监听播放条改变,使歌词滚动

      parent.broadcast_1[0].addEventListener("timeupdate", function () {
          for (let j = 0;j < parts.length - 1 ; j++) {
              if (parseInt(parent.broadcast_1[0].currentTime) >= parseInt(parts[j].seconds) && parseInt(parent.broadcast_1[0].currentTime) < parseInt(parts[j + 1].seconds)) {	//检测歌词所在位置
                  //歌词滚动到所在行
                  lyric[0].style.marginTop = -50 * (j - 2) + "px";
                  for (let j = 0; j < parts.length - 1; j++) {
                      li[j].className = 'normal';
                  }	//使其余歌词正常
                  li[j].className = 'big';	//播放的歌词变大
                  break;
              }
          }
      });
    5. 点击播放条跳转(与监听类似)

18.歌手页模块(懒加载)

  1. 接口:/top/artists

  2. 在创建的img标签上添加一个属性,用于存放正确路径的图片

    img.setAttribute('data_src', imgsrc);

    注:添加自定义属性值和属性名

  3. 在img的src上填入一个正在加载的代替图片

  4. 设置在屏幕可见范围内就加载出正确的图片

    var imgurl = avatar_img[i].getAttribute("data_src");
    avatar_img[i].src = imgurl;

    注:在html标签中添加的自定义属性,如果想要获取这个属性的值,需要使用getAttribute("自定义属性的名字")才能获取这个属性的值

  5. 滚动条移动到底部的时候,会发送请求继续获取数据

    if (document.documentElement.scrollHeight - document.documentElement.scrollTop < document.documentElement.clientHeight+10) {
        loadnum++;
        musicurl = url + '&offset=' + loadnum * 30;
        huidiao(url, musicurl, loadnum);
    }

    注:由于缩放页面的时候会出现满足不了if条件的情况,故将判断区间扩大范围

  6. 需先执行一次代码,然后在启动滚动事件,否则刚打开的时候不滚动是没有图片加载出来的

19.歌手详情模块

  1. 接口:

    1. 获取歌手的歌曲:/artists
    2. 获取歌手mv:/artist/mv
    3. 获取歌手专辑:/artist/album
    4. 获取歌手信息:/artist/desc
    5. 获取相似歌手信息:/simi/artist
  2. 布局思路:

    1. 使用js将下面的数据进行选择性隐藏处理,再将其某一个显示出来
    2. 专辑和mv分页(模块16)
    3. mv嵌入头像处理布局