练习rem响应式布局;

    • HTML代码
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <link rel="stylesheet" href="css/reset.min.css">
    7. <link rel="stylesheet" href="css/index.css">
    8. <script>
    9. ;(function (designWidth) {
    10. function computedFont() {
    11. let winW = document.documentElement.clientWidth || document.body.clientWidth;
    12. document.documentElement.style.fontSize = winW / designWidth * 100 + 'px';
    13. }
    14. computedFont();
    15. window.addEventListener('resize', computedFont);
    16. window.addEventListener('orientationchange', computedFont);
    17. })(750);
    18. </script>
    19. <title>Title</title>
    20. </head>
    21. <body>
    22. <section class="container">
    23. <audio src="img/myDream.m4a"
    24. preload="none"
    25. id="musicAudio"></audio>
    26. <div class="backgroundImg"></div>
    27. <div class="bg"></div>
    28. <header class="header">
    29. <div class="content">
    30. <img src="img/myDream.jpg" alt="">
    31. <div class="song">
    32. <p>我的梦</p>
    33. <p>张靓颖</p>
    34. </div>
    35. <a href="javascript:;" id="musicBtn"></a>
    36. </div>
    37. </header>
    38. <main class="main">
    39. <div class="wrapper">
    40. <p>我的未来不是梦</p>
    41. <p>我的未来不是梦</p>
    42. <p>我的未来不是梦</p>
    43. <p>我的未来不是梦</p>
    44. <p>我的未来不是梦</p>
    45. <p>我的未来不是梦</p>
    46. <p>我的未来不是梦</p>
    47. <p>我的未来不是梦</p>
    48. <p>我的未来不是梦</p>
    49. <p>我的未来不是梦</p>
    50. <p>我的未来不是梦</p>
    51. </div>
    52. </main>
    53. <footer class="footer">
    54. <div class="progress">
    55. <span id="current">00:00</span>
    56. <span id="duration">00:00</span>
    57. <div class="probg">
    58. <div class="already"></div>
    59. </div>
    60. </div>
    61. <a href="javascript:;" id="down">下载这首音乐</a>
    62. </footer>
    63. </section>
    64. <script src="js/zepto.min.js"></script>
    65. <script src="js/index.js"></script>
    66. </body>
    67. </html>
    • CSS代码
    1. * {
    2. margin: 0;
    3. padding: 0;
    4. }
    5. html {
    6. font-size: 100px;
    7. height: 100%;
    8. }
    9. body {
    10. height: 100%;
    11. }
    12. .container {
    13. height: 100%;
    14. position: relative;
    15. }
    16. .backgroundImg, .bg {
    17. position: absolute;
    18. left: 0;
    19. top: 0;
    20. width: 100%;
    21. height: 100%;
    22. z-index: -2;
    23. }
    24. .backgroundImg {
    25. background: url("../img/myDream.jpg") no-repeat;
    26. background-size: cover;
    27. filter: blur(7px);/*让盒子有一个模糊度*/
    28. -webkit-filter: blur(7px);
    29. }
    30. .bg {
    31. background: rgba(0, 0, 0, .2);
    32. }
    33. .header {
    34. position: relative;
    35. padding: .3rem;
    36. background: rgba(0, 0, 0, .3);
    37. }
    38. .header .content img {
    39. width: 1.2rem;
    40. height: 1.2rem
    41. }
    42. .header .content .song {
    43. display: inline-block;
    44. color: white;
    45. vertical-align: top;
    46. }
    47. .header .content .song p {
    48. height: .6rem;
    49. }
    50. .header .content .song p:nth-child(1) {
    51. font-size: .45rem;
    52. }
    53. .header #musicBtn {
    54. display: block;
    55. width: .6rem;
    56. height: .6rem;
    57. background: url("../img/music.svg") no-repeat;
    58. background-size: 100% 100%;
    59. position: absolute;
    60. right: .3rem;
    61. top: 50%;
    62. margin-top: -.3rem;
    63. }
    64. .header #musicBtn.select {
    65. animation: move 1s linear 0s infinite;
    66. }
    67. @keyframes move {
    68. from {
    69. transform: rotate(0deg);
    70. }
    71. to {
    72. transform: rotate(360deg);
    73. }
    74. }
    75. .main {
    76. padding: .3rem;
    77. height: 5rem;
    78. position: relative;
    79. overflow: hidden;
    80. }
    81. .main .wrapper {
    82. position: absolute;
    83. top: 0;
    84. left: 0;
    85. width: 100%;
    86. transition: all .3s linear 0s;
    87. }
    88. .main .wrapper p {
    89. height: .84rem;
    90. line-height: .84rem;
    91. text-align: center;
    92. color: rgba(255, 255, 255, .5);
    93. letter-spacing: .04rem;
    94. font-size: .4rem;
    95. }
    96. .main .wrapper p.select {
    97. color: #31C27C;
    98. }
    99. .progress {
    100. width: 100%;
    101. height: .8rem;
    102. position: relative;
    103. overflow: hidden;
    104. }
    105. .progress span {
    106. position: absolute;
    107. color: #fff;
    108. }
    109. .progress span:nth-child(1) {
    110. left: .3rem;
    111. }
    112. .progress span:nth-child(2) {
    113. right: .3rem;
    114. }
    115. .progress .probg {
    116. width: 65%;
    117. margin: .15rem auto;
    118. background: rgba(255, 255, 255, .3);
    119. height: .04rem;
    120. }
    121. .progress .probg .already {
    122. height: .04rem;
    123. background: #31C27C;
    124. width: 45%;
    125. }
    126. .footer #down {
    127. display: block;
    128. border-radius: .5rem;
    129. width: 60%;
    130. margin: auto;
    131. height: 1rem;
    132. line-height: 1rem;
    133. text-align: center;
    134. font-size: .4rem;
    135. color: #fff;
    136. background: url("../img/sprite_play.png") .2rem -5.86rem no-repeat #31C27C;
    137. /*设置雪碧图的大小*/
    138. background-size: .8rem 7rem;
    139. }
    • JS代码
    1. // 1. 获取元素
    2. let $main = $('.main');
    3. let $header = $('.header');
    4. let $footer = $('.footer');
    5. let musicAudio = document.querySelector('#musicAudio');
    6. let $musicBtn = $('#musicBtn');
    7. let $wrapper = $('.wrapper');
    8. let autoTimer = null;
    9. // 2. 计算当前内容区域的高度
    10. // 用屏幕的高度 - header的高度 - footer的高度 - 0.6rem
    11. function computeMain() {
    12. // px
    13. let winH = document.documentElement.clientHeight;
    14. let headerH = $header[0].offsetHeight;
    15. let footerH = $footer[0].offsetHeight;
    16. // 获取当前最新的fontSize
    17. let fontSize = parseFloat(document.documentElement.style.fontSize);
    18. // 用屏幕的高度 - header高度 - footer高度 - .6 rem;
    19. let curMainH = (winH - headerH - footerH) / fontSize - 0.9 + 'rem';
    20. $main.css({
    21. height: curMainH
    22. });
    23. }
    24. computeMain();
    25. // 3. 请求数据
    26. $.ajax({
    27. url: 'json/lyric.json',
    28. type: 'GET',
    29. async: false,
    30. success({lyric}) {
    31. bindHTML(lyric)
    32. }
    33. });
    34. // 4. 绑定数据
    35. function bindHTML(data) {
    36. // 1. 解决标题符号(歌曲名-歌手)
    37. let d1 = data.replace(/&#(\d+);/g, (res, a) => {
    38. switch (parseFloat(a)) {
    39. case 32:
    40. return " ";
    41. case 40:
    42. return '(';
    43. case 41:
    44. return ')';
    45. case 45:
    46. return '-';
    47. }
    48. // 如果捕获的不是以上这些数字要把捕获的内容返回,否则会把捕获的内容变成 undefined
    49. return res;
    50. });
    51. let ary = [];
    52. d1.replace(/\[(\d+)&#58;(\d+)&#46;(?:\d+)\]([^&#]+)(?:&#10;)/g, (res, min, sec, val) => {
    53. ary.push({
    54. minute: min,
    55. second: sec,
    56. value: val
    57. })
    58. });
    59. console.log(ary);
    60. // 循环绑定数据
    61. let str = ``;
    62. ary.forEach(({minute, second, value}) => {
    63. str += `<p data-min="${minute}" data-sec="${second}">${value}</p>`;
    64. });
    65. $wrapper.html(str);
    66. // 歌词就绪后播放音乐
    67. musicAudio.play();
    68. // 让音乐控制按钮转起来
    69. $musicBtn.addClass('select');
    70. // 计算播放时间、跟新进度条、变更选中歌词
    71. autoTimer = setInterval(computedTime, 1000);
    72. // musicAudio.ontimeupdate = computedTime;
    73. }
    74. // 5. 给音符按钮绑定触摸事件,如果当前正在播放,轻触按钮则暂停播放;如果当前处于暂停状态,轻触按钮则恢复播放;
    75. $musicBtn.tap(function () {
    76. //
    77. if (musicAudio.paused) {
    78. musicAudio.play();
    79. $musicBtn.addClass('select');
    80. // 重新绑定时器
    81. autoTimer = setInterval(computedTime, 1000);
    82. } else {
    83. musicAudio.pause();
    84. clearInterval(autoTimer);
    85. $musicBtn.removeClass('select');
    86. }
    87. });
    88. // 6. 根据播放时间更新高亮的歌词,并且跟新进度条
    89. let curTop = 0;
    90. let step = 0;
    91. function computedTime() {
    92. // 在audio元素上会有一个currentTime表示当前播放进度,duration表示音频总时长;
    93. let {currentTime, duration} = musicAudio;
    94. let curTime = formatTime(currentTime);
    95. let durTime = formatTime(duration);
    96. $('#current').html(curTime);
    97. $('#duration').html(durTime);
    98. // 如果当前时间大于等于总时间,清除定时器
    99. if (currentTime >= duration) {
    100. clearInterval(autoTimer);
    101. $musicBtn.removeClass('select');
    102. }
    103. // 设置进度条
    104. $('.already').css({
    105. width: (currentTime / duration) * 100 + '%'
    106. });
    107. // 设置高亮的歌词
    108. let min = curTime.split(':')[0];
    109. let sec = curTime.split(':')[1];
    110. let highLightItem = $wrapper.find('p').filter(`[data-min="${min}"]`).filter(`[data-sec="${sec}"]`);
    111. if (highLightItem.length) {
    112. step++;
    113. highLightItem.addClass('select').siblings().removeClass('select');
    114. if (step > 4) {
    115. curTop -= .84;
    116. $('.wrapper').css('top', `${curTop}rem`);
    117. }
    118. }
    119. }
    120. function formatTime(time) {
    121. let min = Math.floor(time / 60);
    122. let sec = Math.round(time - min * 60);
    123. min < 10 && (min = '0' + min);
    124. sec < 10 && (sec = '0' + sec);
    125. return `${min}:${sec}`;
    126. }

    ```