iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 18
0
自我挑戰組

新手村-30 Day JS Coding Challenge系列 第 18

新手村18 - Adding Up Times with Reduce

  • 分享至 

  • xImage
  •  

18 - Adding Up Times with Reduce

俗話說的好,一天一蘋果,醫生遠離我

一天一 JS,What the f*ck JavaScript?

small steps every day - 記錄著新手村日記

完成目標

透過 Reduce 把播放清單中的時間加起來。

  • 功能

    加總時間

  • 畫面

    依時間格式顯示小時、分鐘、秒數

index_START.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Videos</title>
</head>
  <body>
    <ul class="videos">
      <li data-time="5:43">
        Video 1
      </li>
      <li data-time="2:33">
        Video 2
      </li>
      <li data-time="3:45">
        Video 3
      </li>
      <li data-time="0:47">
        Video 4
      </li>
      <li data-time="5:21">
        Video 5
      </li>
      <li data-time="6:56">
        Video 6
      </li>
      <li data-time="3:46">
        Video 7
      </li>
      <li data-time="5:25">
        Video 8
      </li>
      <li data-time="3:14">
        Video 9
      </li>
      <li data-time="3:31">
        Video 10
      </li>
      <li data-time="5:59">
        Video 11
      </li>
      <li data-time="3:07">
        Video 12
      </li>
      <li data-time="11:29">
        Video 13
      </li>
      <li data-time="8:57">
        Video 14
      </li>
      <li data-time="5:49">
        Video 15
      </li>
      <li data-time="5:52">
        Video 16
      </li>
      <li data-time="5:50">
        Video 17
      </li>
      <li data-time="9:13">
        Video 18
      </li>
      <li data-time="11:51">
        Video 19
      </li>
      <li data-time="7:58">
        Video 20
      </li>
      <li data-time="4:40">
        Video 21
      </li>
      <li data-time="4:45">
        Video 22
      </li>
      <li data-time="6:46">
        Video 23
      </li>
      <li data-time="7:24">
        Video 24
      </li>
      <li data-time="7:12">
        Video 25
      </li>
      <li data-time="5:23">
        Video 26
      </li>
      <li data-time="3:34">
        Video 27
      </li>
      <li data-time="8:22">
        Video 28
      </li>
      <li data-time="5:17">
        Video 29
      </li>
      <li data-time="3:10">
        Video 30
      </li>
      <li data-time="4:43">
        Video 31
      </li>
      <li data-time="19:43">
        Video 32
      </li>
      <li data-time="0:47">
        Video 33
      </li>
      <li data-time="0:47">
        Video 34
      </li>
      <li data-time="3:14">
        Video 35
      </li>
      <li data-time="3:59">
        Video 36
      </li>
      <li data-time="2:43">
        Video 37
      </li>
      <li data-time="4:17">
        Video 38
      </li>
      <li data-time="6:56">
        Video 39
      </li>
      <li data-time="3:05">
        Video 40
      </li>
      <li data-time="2:06">
        Video 41
      </li>
      <li data-time="1:59">
        Video 42
      </li>
      <li data-time="1:49">
        Video 43
      </li>
      <li data-time="3:36">
        Video 44
      </li>
      <li data-time="7:10">
        Video 45
      </li>
      <li data-time="3:44">
        Video 46
      </li>
      <li data-time="3:44">
        Video 47
      </li>
      <li data-time="4:36">
        Video 48
      </li>
      <li data-time="3:16">
        Video 49
      </li>
      <li data-time="1:10">
        Video 50
      </li>
      <li data-time="6:10">
        Video 51
      </li>
      <li data-time="2:14">
        Video 52
      </li>
      <li data-time="3:44">
        Video 53
      </li>
      <li data-time="5:05">
        Video 54
      </li>
      <li data-time="6:03">
        Video 55
      </li>
      <li data-time="12:39">
        Video 56
      </li>
      <li data-time="1:56">
        Video 57
      </li>
      <li data-time="4:04">
        Video 58
      </li>
    </ul>
  <script>
  </script>
  </body>
</html>

JS - step by step

首先,先透過 querySelectorAll 抓出所有的 li,方便我們之後透過 reduce 方法來計算裡面的時間,還記得前面幾張所說,透過這個方法抓出的數值會是一個 Nodelist,因此如果要轉成陣列的話有以下四種方法:

<script>
  let li = document.querySelectorAll("li");
  let a = Array.from(li).map( item => item);
  let b = [].map.call(li, item => item);
  let c = [].map.apply(li, [item => item]);
  let d = [...li].map( item => item);

	//(58) [li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li, li]

</script>

接下來,必須透過 dataset.time 來抓出 lidata-time 的值

HTMLElement.dataset:https://tinyurl.com/yywtglmc

<script>
  let li = document.querySelectorAll("li");
  // let a = Array.from(li).map( item => item);
  // let b = [].map.call(li, item => item);
  // let c = [].map.apply(li, [item => item]);
  let d = [...li].map( item => item.dataset.time);
  console.log(d);

	//(58) ["5:43", "2:33", "3:45", "0:47", "5:21", "6:56", "3:46", "5:25", "3:14", "3:31", "5:59", "3:07", "11:29", "8:57", "5:49", "5:52", "5:50", "9:13", "11:51", "7:58", "4:40", "4:45", "6:46", "7:24", "7:12", "5:23", "3:34", "8:22", "5:17", "3:10", "4:43", "19:43", "0:47", "0:47", "3:14", "3:59", "2:43", "4:17", "6:56", "3:05", "2:06", "1:59", "1:49", "3:36", "7:10", "3:44", "3:44", "4:36", "3:16", "1:10", "6:10", "2:14", "3:44", "5:05", "6:03", "12:39", "1:56", "4:04"]
</script>

印出時間後,我們必須抓出分鐘、秒數,並命名為 [min,sec],記得考慮到字串、數字的問題,不管是分鐘或者是秒數都必須乘上數字!

<script>
  let li = document.querySelectorAll("li");
  // let a = Array.from(li).map( item => item);
  // let b = [].map.call(li, item => item);
  // let c = [].map.apply(li, [item => item]);
  let d = [...li].map( item => item.dataset.time)
                 .map( time => {
              	 		let [min,sec] = time.split(":");
              			return min * 60 + sec * 1 ;
              	 });
  console.log(d);
	//(58) [343, 153, 225, 47, 321, 416, 226, 325, 194, 211, 359, 187, 689, 537, 349, 352, 350, 553, 711, 478, 280, 285, 406, 444, 432, 323, 214, 502, 317, 190, 283, 1183, 47, 47, 194, 239, 163, 257, 416, 185, 126, 119, 109, 216, 430, 224, 224, 276, 196, 70, 370, 134, 224, 305, 363, 759, 116, 244]
</script>

這時候就要用上 reduce 將剛剛所有的時間加總起來,

Array.prototype.reduce():https://tinyurl.com/yye5lgcw

<script>
  let li = document.querySelectorAll("li");
  // let a = Array.from(li).map( item => item);
  // let b = [].map.call(li, item => item);
  // let c = [].map.apply(li, [item => item]);
  let d = [...li].map( item => item.dataset.time)
                 .map( time => {
                 		let [min,sec] = time.split(":");
                  	return min * 60 + sec * 1 ;
                 }).reduce( (first,next) => first + next , 0);
	console.log(d);
</script>

最後再將所有的時間算數算出小時、分鐘、秒鐘~

<script>
      let li = document.querySelectorAll("li");
      // let a = Array.from(li).map( item => item);
      // let b = [].map.call(li, item => item);
      // let c = [].map.apply(li, [item => item]);
      let d = [...li].map( item => item.dataset.time)
                     .map( time => {
                        let [min,sec] = time.split(":");
                        return min * 60 + sec * 1 ;
                     }).reduce( (first,next) => first + next , 0);
      console.log(d);

      let sec = d % 60;
      let min = (d - sec) / 60;
      let hour = Math.floor(min / 60);

      min %= 60;
      console.log(`${hour}:${min}:${sec}`);
</script>

就大功告成啦!

JS - final

<script>

  const timeNodes = Array.from(document.querySelectorAll('[data-time]'));

  const seconds = timeNodes
    .map(node => node.dataset.time)
    .map(timeCode => {
      const [mins, secs] = timeCode.split(':').map(parseFloat);
      return (mins * 60) + secs;
    })
    .reduce((total, vidSeconds) => total + vidSeconds);

    let secondsLeft = seconds;
    const hours = Math.floor(secondsLeft / 3600);
    secondsLeft = secondsLeft % 3600;

    const mins = Math.floor(secondsLeft / 60);
    secondsLeft = secondsLeft % 60;

    console.log(hours, mins, secondsLeft);

</script>

本刊同步於個人網站:http://chestertang.site/

本次範例程式碼原作者來源:https://tinyurl.com/yavm5f5n


上一篇
新手村17 - Sort Without Articles
下一篇
新手村19 - Webcam Fun
系列文
新手村-30 Day JS Coding Challenge30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言