91aaa在线国内观看,亚洲AV午夜福利精品一区二区,久久偷拍人视频,久久播这里有免费视播

<strong id="fvuar"></strong>

  • <sub id="fvuar"><dl id="fvuar"><em id="fvuar"></em></dl></sub>

    1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

      手機(jī)站
      千鋒教育

      千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

      千鋒教育

      掃一掃進(jìn)入千鋒手機(jī)站

      領(lǐng)取全套視頻
      千鋒教育

      關(guān)注千鋒學(xué)習(xí)站小程序
      隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

      當(dāng)前位置:首頁  >  技術(shù)干貨  > 如何實(shí)現(xiàn)拖拽排序

      如何實(shí)現(xiàn)拖拽排序

      來源:千鋒教育
      發(fā)布人:wjy
      時(shí)間: 2022-06-02 13:54:00 1654149240

      可拖拽排序的菜單效果大家想必都很熟悉,本次我們通過一個(gè)可拖拽排序的九宮格案例來演示其實(shí)現(xiàn)原理。 

      如何實(shí)現(xiàn)拖拽排序

      ## 實(shí)現(xiàn)原理概述

      **拖拽原理**

      - 當(dāng)鼠標(biāo)在【可拖拽小方塊】(以下簡稱磚頭)身上按下時(shí),開始監(jiān)聽鼠標(biāo)移動(dòng)事件
      - 鼠標(biāo)事件移動(dòng)到什么位置,磚頭就跟到什么位置
      - 鼠標(biāo)抬起時(shí),取消鼠標(biāo)移動(dòng)事件的監(jiān)聽

      **排序原理**

      - 提前定義好9大坑位的位置(相對外層盒子的left和top)
      - 將9大磚頭丟入一個(gè)數(shù)組,以便后期通過splice方法隨意安插和更改磚頭的位置
      - 當(dāng)拖動(dòng)某塊磚頭時(shí),先將其從數(shù)組中移除(剩余的磚頭在邏輯上重新排序)
      - 拖動(dòng)結(jié)束時(shí),將該磚頭重新插回?cái)?shù)組的目標(biāo)位置(此時(shí)實(shí)現(xiàn)數(shù)據(jù)上的重排)
      - 數(shù)組中的9塊磚頭根據(jù)新的序號,對號入座到9大坑位,完成重新渲染

      ## 代碼實(shí)現(xiàn)

      **頁面布局**

      9塊磚頭(li元素)相對于外層盒子(ul元素)做絕對定位

      ```html
      <ul id="box">
              <li style="background-color:black;top: 10px; left: 10px">1</li>
              <li style="background-color:black;top: 10px; left: 220px">2</li>
              <li style="background-color:black;top: 10px; left: 430px">3</li>
              <li style="background-color:black;top: 220px; left: 10px">4</li>
              <li style="background-color:black;top: 220px; left: 220px">5</li>
              <li style="background-color:black;top: 220px; left: 430px">6</li>
              <li style="background-color:black;top: 430px; left: 10px">7</li>
              <li style="background-color:black;top: 430px; left: 220px">8</li>
              <li style="background-color:black;top: 430px; left: 430px">9</li>
          </ul>
      ```

      樣式如下

      ```css
      <style>
              * {
                  margin: 0;
                  padding: 0;
              }

              html,
              body {
                  width: 100%;
                  height: 100%;
              }

              ul,
              li {
                  list-style: none;
              }

              ul {
                  width: 640px;
                  height: 640px;
                  border: 10px solid pink;
                  border-radius: 10px;
                  margin: 50px auto;
                  position: relative;
              }

              li {
                  width: 200px;
                  height: 200px;
                  border-radius: 10px;
                  display: flex;
                  justify-content: center;
                  align-items: center;
                  color: white;
                  font-size: 100px;
                  position: absolute;
              }
          </style>
      ```

      **定義磚頭的背景色和9大坑位位置**

      ```js
      // 定義9大li的預(yù)設(shè)背景色
          var colorArr = [
              "red",
              "orange",
              "yellow",
              "green",
              "blue",
              "cyan",
              "purple",
              "pink",
              "gray",
          ];

          /* 定義9大坑位 */
          const positions = [
              [10, 10], [220, 10], [430, 10],
              [10, 220], [220, 220], [430, 220],
              [10, 430], [220, 430], [430, 430],
          ]
      ```

      **找出磚頭并丟入一個(gè)數(shù)組**

      ```js
      var ulBox = document.querySelector("#box")
          var lis = document.querySelectorAll("#box>li")
          /* 將lis轉(zhuǎn)化為真數(shù)組 */
          lis = toArray(lis)
      ```

      這里我使用了一個(gè)將NodeList偽數(shù)組轉(zhuǎn)化為真數(shù)組的輪子:

      ```js
      /* 偽數(shù)組轉(zhuǎn)真數(shù)組 pseudo array */
          function toArray(pArr){
              var arr = []
              for(var i=0;i<pArr.length;i++){
                  arr.push(pArr[i])
              }
              return arr
          }
      ```

      **給所有磚頭內(nèi)置一個(gè)position屬性**

      ```js
      /* 給每塊磚內(nèi)置一個(gè)position屬性 */
          lis.forEach(
              (item, index) => item.setAttribute("position", index)
          )
      ```

      **定義正在拖動(dòng)的磚頭**

      ```js
      /* 正在拖動(dòng)的Li(磚頭) */
              var draggingLi = null;

              // 正在拖動(dòng)的磚頭的zindex不斷加加,保持在最上層
              var maxZindex = 9
      ```

      **在身上按下 誰就是【正在拖動(dòng)的磚頭】**

      ```js
      /* 在身上按下 誰就是【正在拖動(dòng)的磚頭】 */
              lis.forEach(
                  function (li, index) {
                      li.style.backgroundColor = colorArr[index]

                      /* li中的文字不可選(禁止selectstart事件的默認(rèn)行為) */
                      li.addEventListener(
                          "selectstart",
                          function (e) {
                              // 阻止掉拖選文本的默認(rèn)行為
                              e.preventDefault()
                          }
                      )

                      /* 在任意li身上按下鼠標(biāo)=我想拖動(dòng)它 */
                      li.addEventListener(
                          "mousedown",
                          function (e) {
                              draggingLi = this
                              draggingLi.style.zIndex = maxZindex++
                          }
                      )
                  }
              )
      ```

      **在任意位置松開鼠標(biāo)則停止拖拽**

      ```js
      /* 在頁面的任意位置松開鼠標(biāo)=不再拖拽任何對象 */
              document.addEventListener(
                  "mouseup",
                  function (e) {
                      // 當(dāng)前磚頭自己進(jìn)入位置躺好
                      const p = draggingLi.getAttribute("position") * 1
                      // draggingLi.style.left = positions[p][0] + "px"
                      // draggingLi.style.top = positions[p][1] + "px"
                      move(
                          draggingLi,
                          {
                              left:positions[p][0] + "px",
                              top:positions[p][1] + "px"
                          },
                          200
                          // callback
                      )

                      // 正在拖拽的磚頭置空
                      draggingLi = null;
                  }
              )
      ```

      當(dāng)前磚頭從鼠標(biāo)事件位置回歸其坑位時(shí)用到動(dòng)畫效果,以下是動(dòng)畫輪子

      ```js
      /**
       * 多屬性動(dòng)畫
       * @param {Element} element 要做動(dòng)畫的元素
       * @param {Object} targetObj 屬性目標(biāo)值的對象 封裝了所有要做動(dòng)畫的屬性及其目標(biāo)值
       * @param {number} timeCost 動(dòng)畫耗時(shí),單位毫秒
       * @param {Function} callback 動(dòng)畫結(jié)束的回調(diào)函數(shù)
       */
      const move = (element, targetObj, timeCost = 1000, callback) => {
          const frameTimeCost = 40;

          // 500.00px 提取單位的正則
          const regUnit = /[\d\.]+([a-z]*)/;

          // 計(jì)算動(dòng)畫總幀數(shù)
          const totalFrames = Math.round(timeCost / frameTimeCost);

          // 動(dòng)態(tài)數(shù)一數(shù)當(dāng)前動(dòng)畫到了第幾幀
          let frameCount = 0;

          /* 查詢特定屬性的速度(湯鵬飛的辣雞) */
          // const getAttrSpeed = (attr) => (parseFloat(targetObj[attr]) - parseFloat(getComputedStyle(element)[attr]))/totalFrames

          // 存儲(chǔ)各個(gè)屬性的初始值和動(dòng)畫速度
          const ssObj = {};

          /* 遍歷targetObj的所有屬性 */
          for (let attr in targetObj) {
              // 拿到元素屬性的初始值
              const attrStart = parseFloat(getComputedStyle(element)[attr]);

              // 動(dòng)畫速度 = (目標(biāo)值 - 當(dāng)前值)/幀數(shù)
              const attrSpeed =
                  (parseFloat(targetObj[attr]) - attrStart) / totalFrames;

              // 將【屬性初始值】和【屬性幀速度】存在obj中 以后obj[left]同時(shí)拿到這兩個(gè)貨
              // obj{ left:[0px初始值,50px每幀] }
              ssObj[attr] = [attrStart, attrSpeed];
          }

          /* 開始動(dòng)畫 */
          const timer = setInterval(
              () => {
                  // element.style.left = parseFloat(getComputedStyle(element).left)+"px"
                  // element.style.top = parseFloat(getComputedStyle(element).top)+"px"
                  // element.style.opacity = getComputedStyle(element).opacity

                  // 幀數(shù)+1
                  frameCount++;

                  /* 每個(gè)屬性的值都+=動(dòng)畫速度 */
                  for (let attr in targetObj) {
                      // console.log(attr, ssObj[attr], totalFrames, frameCount);

                      // 用正則分離出單位
                      // console.log(regUnit.exec("500px"));
                      // console.log(regUnit.exec(0));
                      const unit = regUnit.exec(targetObj[attr])[1];

                      // 計(jì)算出當(dāng)前幀應(yīng)該去到的屬性值
                      const thisFrameValue =
                          ssObj[attr][0] + frameCount * ssObj[attr][1];

                      // 將元素的屬性掰到當(dāng)前幀應(yīng)該去到的目標(biāo)值
                      element.style[attr] = thisFrameValue + unit;
                  }

                  /* 當(dāng)前幀 多個(gè)屬性動(dòng)畫完成 判斷是否應(yīng)該終止動(dòng)畫  */
                  if (frameCount >= totalFrames) {
                      // console.log(frameCount, totalFrames);
                      clearInterval(timer);

                      /* 強(qiáng)制矯正(反正用戶又看不出來 V) */
                      // for (let attr in targetObj) {
                      //     element.style[attr] = targetObj[attr];
                      //     console.log(attr, getComputedStyle(element)[attr]);
                      // }

                      // 如果有callback就調(diào)用callback
                      // if(callback){
                      //     callback()
                      // }
                      callback && callback();
                  }
              },

              frameTimeCost
          );

          /* 動(dòng)畫結(jié)束后再過一幀 執(zhí)行暴力校正 */
          setTimeout(() => {
              /* 強(qiáng)制矯正(反正用戶又看不出來 V) */
              for (let attr in targetObj) {
                  element.style[attr] = targetObj[attr];
                  // console.log(attr, getComputedStyle(element)[attr]);
              }
          }, timeCost + frameTimeCost);

          // 返回正在運(yùn)行的定時(shí)器
          return timer;
      };
      ```

      **移動(dòng)鼠標(biāo)時(shí) 磚頭跟隨 所有磚頭實(shí)時(shí)洗牌**

      ```js
      /* 在ul內(nèi)移動(dòng)鼠標(biāo) draggingLi跟隨鼠標(biāo) */
              ulBox.addEventListener(
                  "mousemove",
                  function (e) {
                      /* 如果draggingLi為空 什么也不做 直接返回 */
                      if (draggingLi === null) {
                          return
                      }

                      // 拿到事件相對于ulBox的位置  
                      var offsetX = e.pageX - ulBox.offsetLeft - 100
                      var offsetY = e.pageY - ulBox.offsetTop - 100

                      /* 校正磚頭的偏移量 */
                      offsetX = offsetX < 10 ? 10 : offsetX
                      offsetY = offsetY < 10 ? 10 : offsetY
                      offsetX = offsetX > 430 ? 430 : offsetX
                      offsetY = offsetY > 430 ? 430 : offsetY

                      // 將該位置設(shè)置給draggingLi
                      draggingLi.style.left = offsetX + "px"
                      draggingLi.style.top = offsetY + "px"

                      /* 實(shí)時(shí)檢測實(shí)時(shí)【坑位】 */
                      const newPosition = checkPosition([offsetX, offsetY]);

                      // 如果當(dāng)前磚頭的position發(fā)生變化 則數(shù)據(jù)重排
                      const oldPosition = draggingLi.getAttribute("position") * 1
                      if (newPosition != -1 && newPosition != oldPosition) {
                          console.log(oldPosition, newPosition);

                          /* 數(shù)據(jù)重排 */
                          // 先將當(dāng)前磚頭拽出數(shù)組(剩余的磚頭位置自動(dòng)重排)
                          lis.splice(oldPosition, 1)
                          // 再將當(dāng)前磚頭插回newPosition
                          lis.splice(newPosition, 0, draggingLi)

                          // 打印新數(shù)據(jù)
                          // logArr(lis,"innerText")

                          // 磚頭洗牌
                          shuffle()
                      }

                  }
              )
      ```

      **坑位檢測方法**

      ```js
      /* 實(shí)時(shí)檢測坑位:檢測ep與9大坑位的距離是否小于100 */
              const checkPosition = (ep) => {
                  for (let i = 0; i < positions.length; i++) {
                      const [x, y] = positions[i]//[10,10]
                      const [ex, ey] = ep//[offsetX,offsetY]

                      const distance = Math.sqrt(Math.pow(x - ex, 2) + Math.pow(y - ey, 2))
                      if (distance < 100) {
                          return i
                      }
                  }

                  // 沒有進(jìn)入任何坑位
                  return -1
              }
      ```

      **磚頭洗牌方法**

      ```js
      /* 磚頭洗牌:lis中的每塊磚去到對應(yīng)的位置 */
              const shuffle = () => {
                  for (var i = 0; i < lis.length; i++) {
                      lis[i].style.left = positions[i][0] + "px"
                      lis[i].style.top = positions[i][1] + "px"

                      // 更新自己的位置
                      lis[i].setAttribute("position", i)
                  }
              }
      ```

      ## 完整代碼實(shí)現(xiàn)

      **主程序**

      ```js
      <!DOCTYPE html>
      <html lang="en">

      <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>九宮格拖拽排序</title>

          <style>
              * {
                  margin: 0;
                  padding: 0;
              }

              html,
              body {
                  width: 100%;
                  height: 100%;
              }

              ul,
              li {
                  list-style: none;
              }

              ul {
                  width: 640px;
                  height: 640px;
                  border: 10px solid pink;
                  border-radius: 10px;
                  margin: 50px auto;
                  position: relative;
              }

              li {
                  width: 200px;
                  height: 200px;
                  border-radius: 10px;
                  display: flex;
                  justify-content: center;
                  align-items: center;
                  color: white;
                  font-size: 100px;
                  position: absolute;
              }
          </style>
      </head>

      <body>
          <ul id="box">
              <li style="background-color:black;top: 10px; left: 10px">1</li>
              <li style="background-color:black;top: 10px; left: 220px">2</li>
              <li style="background-color:black;top: 10px; left: 430px">3</li>
              <li style="background-color:black;top: 220px; left: 10px">4</li>
              <li style="background-color:black;top: 220px; left: 220px">5</li>
              <li style="background-color:black;top: 220px; left: 430px">6</li>
              <li style="background-color:black;top: 430px; left: 10px">7</li>
              <li style="background-color:black;top: 430px; left: 220px">8</li>
              <li style="background-color:black;top: 430px; left: 430px">9</li>
          </ul>

          <!--
          position 位置
           -->
          <script src="../../../tools/arr_obj_tool.js"></script>
          <script src="../../../tools/animtool.js"></script>

          <script>
              // 定義9大li的預(yù)設(shè)背景色
              var colorArr = [
                  "red",
                  "orange",
                  "yellow",
                  "green",
                  "blue",
                  "cyan",
                  "purple",
                  "pink",
                  "gray",
              ];

              /* 定義9大坑位 */
              const positions = [
                  [10, 10], [220, 10], [430, 10],
                  [10, 220], [220, 220], [430, 220],
                  [10, 430], [220, 430], [430, 430],
              ]

              var ulBox = document.querySelector("#box")
              var lis = document.querySelectorAll("#box>li")
              /* 將lis轉(zhuǎn)化為真數(shù)組 */
              lis = toArray(lis)

              /* 給每塊磚內(nèi)置一個(gè)position屬性 */
              lis.forEach(
                  (item, index) => item.setAttribute("position", index)
              )

              /* 正在拖動(dòng)的Li(磚頭) */
              var draggingLi = null;

              // 正在拖動(dòng)的磚頭的zindex不斷加加,保持在最上層
              var maxZindex = 9

              /* 在身上按下 誰就是【正在拖動(dòng)的磚頭】 */
              lis.forEach(
                  function (li, index) {
                      li.style.backgroundColor = colorArr[index]

                      /* li中的文字不可選(禁止selectstart事件的默認(rèn)行為) */
                      li.addEventListener(
                          "selectstart",
                          function (e) {
                              // 阻止掉拖選文本的默認(rèn)行為
                              e.preventDefault()
                          }
                      )

                      /* 在任意li身上按下鼠標(biāo)=我想拖動(dòng)它 */
                      li.addEventListener(
                          "mousedown",
                          function (e) {
                              draggingLi = this
                              draggingLi.style.zIndex = maxZindex++
                          }
                      )
                  }
              )

              /* 在頁面的任意位置松開鼠標(biāo)=不再拖拽任何對象 */
              document.addEventListener(
                  "mouseup",
                  function (e) {
                      // 當(dāng)前磚頭自己進(jìn)入位置躺好
                      const p = draggingLi.getAttribute("position") * 1
                      // draggingLi.style.left = positions[p][0] + "px"
                      // draggingLi.style.top = positions[p][1] + "px"
                      move(
                          draggingLi,
                          {
                              left: positions[p][0] + "px",
                              top: positions[p][1] + "px"
                          },
                          200
                          // callback
                      )

                      // 正在拖拽的磚頭置空
                      draggingLi = null;
                  }
              )

              /* 在ul內(nèi)移動(dòng)鼠標(biāo) draggingLi跟隨鼠標(biāo) */
              ulBox.addEventListener(
                  "mousemove",
                  function (e) {
                      /* 如果draggingLi為空 什么也不做 直接返回 */
                      if (draggingLi === null) {
                          return
                      }

                      // 拿到事件相對于ulBox的位置  
                      var offsetX = e.pageX - ulBox.offsetLeft - 100
                      var offsetY = e.pageY - ulBox.offsetTop - 100

                      /* 校正磚頭的偏移量 */
                      offsetX = offsetX < 10 ? 10 : offsetX
                      offsetY = offsetY < 10 ? 10 : offsetY
                      offsetX = offsetX > 430 ? 430 : offsetX
                      offsetY = offsetY > 430 ? 430 : offsetY

                      // 將該位置設(shè)置給draggingLi
                      draggingLi.style.left = offsetX + "px"
                      draggingLi.style.top = offsetY + "px"

                      /* 實(shí)時(shí)檢測實(shí)時(shí)【坑位】 */
                      const newPosition = checkPosition([offsetX, offsetY]);

                      // 如果當(dāng)前磚頭的position發(fā)生變化 則數(shù)據(jù)重排
                      const oldPosition = draggingLi.getAttribute("position") * 1
                      if (newPosition != -1 && newPosition != oldPosition) {
                          console.log(oldPosition, newPosition);

                          /* 數(shù)據(jù)重排 */
                          // 先將當(dāng)前磚頭拽出數(shù)組(剩余的磚頭位置自動(dòng)重排)
                          lis.splice(oldPosition, 1)
                          // 再將當(dāng)前磚頭插回newPosition
                          lis.splice(newPosition, 0, draggingLi)

                          // 打印新數(shù)據(jù)
                          // logArr(lis,"innerText")

                          // 磚頭洗牌
                          shuffle()
                      }

                  }
              )

              /* 實(shí)時(shí)檢測坑位:檢測ep與9大坑位的距離是否小于100 */
              const checkPosition = (ep) => {
                  for (let i = 0; i < positions.length; i++) {
                      const [x, y] = positions[i]//[10,10]
                      const [ex, ey] = ep//[offsetX,offsetY]

                      const distance = Math.sqrt(Math.pow(x - ex, 2) + Math.pow(y - ey, 2))
                      if (distance < 100) {
                          return i
                      }
                  }

                  // 沒有進(jìn)入任何坑位
                  return -1
              }

              /* 磚頭洗牌:lis中的每塊磚去到對應(yīng)的位置 */
              const shuffle = () => {
                  for (var i = 0; i < lis.length; i++) {
                      lis[i].style.left = positions[i][0] + "px"
                      lis[i].style.top = positions[i][1] + "px"

                      // 更新自己的位置
                      lis[i].setAttribute("position", i)
                  }
              }

          </script>
      </body>

      </html>
      ```

      **動(dòng)畫輪子**

      ```js
      function moveWithTransition(element, targetObj, duration) {
          element.style.transition = `all ${duration / 1000 + "s"} linear`;
          for (var attr in targetObj) {
              element.style[attr] = targetObj[attr];
          }
          setTimeout(() => {
              element.style.transition = "none";
          }, duration);
      }

      /**
       * 多屬性動(dòng)畫
       * @param {Element} element 要做動(dòng)畫的元素
       * @param {Object} targetObj 屬性目標(biāo)值的對象 封裝了所有要做動(dòng)畫的屬性及其目標(biāo)值
       * @param {number} timeCost 動(dòng)畫耗時(shí),單位毫秒
       * @param {Function} callback 動(dòng)畫結(jié)束的回調(diào)函數(shù)
       */
      const move = (element, targetObj, timeCost = 1000, callback) => {
          const frameTimeCost = 40;

          // 500.00px 提取單位的正則
          const regUnit = /[\d\.]+([a-z]*)/;

          // 計(jì)算動(dòng)畫總幀數(shù)
          const totalFrames = Math.round(timeCost / frameTimeCost);

          // 動(dòng)態(tài)數(shù)一數(shù)當(dāng)前動(dòng)畫到了第幾幀
          let frameCount = 0;

          /* 查詢特定屬性的速度(湯鵬飛的辣雞) */
          // const getAttrSpeed = (attr) => (parseFloat(targetObj[attr]) - parseFloat(getComputedStyle(element)[attr]))/totalFrames

          // 存儲(chǔ)各個(gè)屬性的初始值和動(dòng)畫速度
          const ssObj = {};

          /* 遍歷targetObj的所有屬性 */
          for (let attr in targetObj) {
              // 拿到元素屬性的初始值
              const attrStart = parseFloat(getComputedStyle(element)[attr]);

              // 動(dòng)畫速度 = (目標(biāo)值 - 當(dāng)前值)/幀數(shù)
              const attrSpeed =
                  (parseFloat(targetObj[attr]) - attrStart) / totalFrames;

              // 將【屬性初始值】和【屬性幀速度】存在obj中 以后obj[left]同時(shí)拿到這兩個(gè)貨
              // obj{ left:[0px初始值,50px每幀] }
              ssObj[attr] = [attrStart, attrSpeed];
          }

          /* 開始動(dòng)畫 */
          const timer = setInterval(
              () => {
                  // element.style.left = parseFloat(getComputedStyle(element).left)+"px"
                  // element.style.top = parseFloat(getComputedStyle(element).top)+"px"
                  // element.style.opacity = getComputedStyle(element).opacity

                  // 幀數(shù)+1
                  frameCount++;

                  /* 每個(gè)屬性的值都+=動(dòng)畫速度 */
                  for (let attr in targetObj) {
                      // console.log(attr, ssObj[attr], totalFrames, frameCount);

                      // 用正則分離出單位
                      // console.log(regUnit.exec("500px"));
                      // console.log(regUnit.exec(0));
                      const unit = regUnit.exec(targetObj[attr])[1];

                      // 計(jì)算出當(dāng)前幀應(yīng)該去到的屬性值
                      const thisFrameValue =
                          ssObj[attr][0] + frameCount * ssObj[attr][1];

                      // 將元素的屬性掰到當(dāng)前幀應(yīng)該去到的目標(biāo)值
                      element.style[attr] = thisFrameValue + unit;
                  }

                  /* 當(dāng)前幀 多個(gè)屬性動(dòng)畫完成 判斷是否應(yīng)該終止動(dòng)畫  */
                  if (frameCount >= totalFrames) {
                      // console.log(frameCount, totalFrames);
                      clearInterval(timer);

                      /* 強(qiáng)制矯正(反正用戶又看不出來 V) */
                      // for (let attr in targetObj) {
                      //     element.style[attr] = targetObj[attr];
                      //     console.log(attr, getComputedStyle(element)[attr]);
                      // }

                      // 如果有callback就調(diào)用callback
                      // if(callback){
                      //     callback()
                      // }
                      callback && callback();
                  }
              },

              frameTimeCost
          );

          /* 動(dòng)畫結(jié)束后再過一幀 執(zhí)行暴力校正 */
          setTimeout(() => {
              /* 強(qiáng)制矯正(反正用戶又看不出來 V) */
              for (let attr in targetObj) {
                  element.style[attr] = targetObj[attr];
                  // console.log(attr, getComputedStyle(element)[attr]);
              }
          }, timeCost + frameTimeCost);

          // 返回正在運(yùn)行的定時(shí)器
          return timer;
      };
      ```

      **偽數(shù)組轉(zhuǎn)真數(shù)組輪子**

      ```js
      /* 偽數(shù)組轉(zhuǎn)真數(shù)組 pseudo array */
      function toArray(pArr){
          var arr = []
          for(var i=0;i<pArr.length;i++){
              arr.push(pArr[i])
          }
          return arr
      }
      ```

      這里大家也可以簡單地

      ```js
      const arr = [...pArr]
      ```

      祝大家擼碼愉快,身心健康!更多關(guān)于“web前端培訓(xùn)”的問題,歡迎咨詢千鋒教育在線名師。千鋒已有十余年的培訓(xùn)經(jīng)驗(yàn),課程大綱更科學(xué)更專業(yè),有針對零基礎(chǔ)的就業(yè)班,有針對想提升技術(shù)的提升班,高品質(zhì)課程助理你實(shí)現(xiàn)夢想。

      tags:
      聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
      10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
      請您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
      免費(fèi)領(lǐng)取
      今日已有369人領(lǐng)取成功
      劉同學(xué) 138****2860 剛剛成功領(lǐng)取
      王同學(xué) 131****2015 剛剛成功領(lǐng)取
      張同學(xué) 133****4652 剛剛成功領(lǐng)取
      李同學(xué) 135****8607 剛剛成功領(lǐng)取
      楊同學(xué) 132****5667 剛剛成功領(lǐng)取
      岳同學(xué) 134****6652 剛剛成功領(lǐng)取
      梁同學(xué) 157****2950 剛剛成功領(lǐng)取
      劉同學(xué) 189****1015 剛剛成功領(lǐng)取
      張同學(xué) 155****4678 剛剛成功領(lǐng)取
      鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
      董同學(xué) 138****2867 剛剛成功領(lǐng)取
      周同學(xué) 136****3602 剛剛成功領(lǐng)取
      相關(guān)推薦HOT
      抖音小店運(yùn)營做什么的

      在當(dāng)前的電商市場中,抖音小店已經(jīng)逐漸成為一種新的電商模式,它集成了社交化、音視頻分享、直播銷售等多種功能,使得消費(fèi)者更加便捷地進(jìn)行商品...詳情>>

      2023-10-08 16:36:41
      抖音小店照片要求尺寸多大

      在抖音平臺(tái)開設(shè)小店已經(jīng)成為了越來越多人的選擇,相信大家已經(jīng)在各大社交平臺(tái)上看到有不少小店的推廣。在抖音上,照片是展示產(chǎn)品的重要手段,因...詳情>>

      2023-10-08 16:14:25
      抖音招商團(tuán)長托管服務(wù)費(fèi)怎么退回來

      抖音招商團(tuán)長托管服務(wù)是抖音為有意愿創(chuàng)作內(nèi)容并帶動(dòng)其他創(chuàng)作者成為團(tuán)隊(duì)成員的用戶提供的一種服務(wù)。通過該服務(wù),招商團(tuán)長可以自主組建團(tuán)隊(duì)并得到...詳情>>

      2023-10-08 16:08:53
      抖音小店怎么做代銷

      抖音已經(jīng)成為了一個(gè)非常受歡迎的短視頻應(yīng)用程序,在其中許多用戶都精心打造了自己的小店,用于銷售各種各樣的商品,獲取額外的收入。然而,要想...詳情>>

      2023-10-08 15:28:41
      怎樣開抖音小店帶貨賺錢

      隨著直播帶貨的火熱,越來越多的人開始嘗試通過抖音小店來開展帶貨業(yè)務(wù)。抖音小店是抖音直播帶貨的配套,可以讓用戶在購買直播中產(chǎn)品時(shí)就實(shí)現(xiàn)購...詳情>>

      2023-10-08 15:06:36