代码之家  ›  专栏  ›  技术社区  ›  SaroGFX

Vanilla JS从左向右切换动画

  •  3
  • SaroGFX  · 技术社区  · 7 年前

    我是一个新的编程人员,我正在学习普通的JS。我创建了这个抽屉导航,它有一个从左向右移动的圆圈,但是有一个问题。我在这里上载了当前状态: http://setup.industries/masquarade/

    让我陷入困境的问题是:

    • 第一次点击汉堡包导航图标不会打开抽屉,动画会被切换。我怀疑问题在if(open)中,因为open var不能真正捕获切换状态 open = header.style.width == '0%' 在初始bug之后,它可以正常工作。真让我头疼。

    如果您有其他更好的代码提示,或者指出我的错误实践,我会很乐意学习的。

    ——

    编辑1:我已经向这个问题添加了完整的代码。我不确定如何使椭圆可见,我直接链接到托管URL。

          // open sidenav //
    
          function openNav() {
            let header = document.getElementById("header");
            let open = header.style.width == '0%'
            let width = document.body.clientWidth;
            var ellipse = document.getElementById("ellipse");
    
            function moveEllipseRight() {
              ellipse.animate([
              // keyframes
              { transform: 'translateX(0px)' },
              { transform:  'translateX('+ width + 'px)' }
            ], {
              // timing options
              duration: 500,
              iterations: 1,
              easing: 'ease-in-out',
              fill: 'forwards'
            });}
    
            function moveEllipseLeft() {
              ellipse.animate([
              // keyframes
              { transform:  'translateX('+ width + 'px)' },
              { transform: 'translateX(0px)' }
            ], {
              // timing options
              duration: 500,
              iterations: 1,
              easing: 'ease-in-out',
              fill: 'forwards'
            });}
    
            // open sidenav //
    
            if (open) {
                header.style.width = "100%";
                 moveEllipseRight();
            } else {
                 header.style.width = '0%';
                 moveEllipseLeft();
               }
             }
    
    //  if (open) {
    //   ellipse.classList.remove("ellipse_left");
    //    ellipse.classList.add("ellipse_right");
    //  } else {
    //    ellipse.classList.remove("ellipse_right");
    //    ellipse.classList.add("ellipse_left");
    //  }
    
    //  let ellipse = document.getElementById("ellipse");
    //  let pos = 0;
    //  let id = setInterval(frame, 5);
    
    
     //  function myMove() {
     //    console.log('Hello')
     //    var ellipse = document.getElementById("ellipse");
     //    var pos = -200;
     //    var id = setInterval(frame, 1);
     //    let width = document.body.clientWidth; // - $('#mydiv').width();
     //
     //        function frame() {
     //          if (pos == width - 200) {
     //            clearInterval(id);
     //          } else {
     //            pos++;
     //            ellipse.style.left = pos + "px";
     //          }
     //        }
     //    }
    
    
    // information tabs //
    
    function openTab(evt, tab) {
      var i, tabcontent, tablinks;
      tabcontent = document.getElementsByClassName("tabcontent");
      for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
      }
      tablinks = document.getElementsByClassName("tablinks");
      for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
      }
      document.getElementById(tab).style.display = "block";
      evt.currentTarget.className += " active";
    }
    html, body {
        max-width: 100%;
        overflow-x: hidden;
    }
    body {
        background: black;
        color: white;
        font-family: 'Helvetica Neue', sans-serif;
        font-size: 1.2em;
        line-height: 1.4em;
    }
    
    a {
      color: white;
    }
    
    .clear {
      clear: both; float: none; height: 40px;
    }
    
    /* Ellipse */
    
    #ellipse {
      position: absolute;
      top: 120px;
      z-index:99;
      animation: 3s linear 0s slide 1;
      left: -200px;
    }
    
    /*
    .ellipse_left {left: -200px;}
    .ellipse_right {right: -200px;}
    */
    
    
    /* Masquarede Logo */
    
    img.masquarade_events {
      opacity: 0.3;
      position: absolute;
      bottom: 20px;
      right: 20px;
    }
    
    img.masquarade_events:hover {
      opacity: 0.9;
    }
    
    
    /* Content */
    
    .content {
      margin: 150px 0 0 300px;
      width: 700px;
      height: 400px;
    }
    
    @media screen and (max-width: 992px) {
      .content {
        margin: 150px 0 0 0;
        width: 700px;
        height: 400px;
      }
    }
    
    .date {
      font-weight: bold;
      margin-bottom: -10px;
    }
    
    .location {
    }
    
    ul.lineup {
      list-style-position: inside;
      padding: 0;
      list-style-type: none;
      width: 100%
      overflow: hidden;
      margin-bottom: 100px;
    }
    
    ul.lineup li {
      margin-right: 50px;
      line-height: 2.5em;
      float: left;
    }
    
    
    /* Buttons */
    
    a.button {
      margin-right: 10px;
      padding: 10px 50px 10px 50px;
      text-decoration: none;
      border-radius: 200px;
      font-size: 0.7em;
      transition: 0.3s;
    }
    
    a.white {
      background: white;
      color: black;
    }
    
    a.white:hover {
      color: white;
      background: #D90E46;
    }
    
    a.black {
      border: 2px white solid;
      color: white;
    }
    
    a.black:hover {
      border: 2px #FCF454 solid;
      color: #FCF454;
    }
    
    /* Header  */
    
    header {
      position: absolute;
      background-color: black;
      top:0;
      left:0;
      width: 0;
      height: 100%;
      z-index: 1;
    }
    
    /* Navigation  */
    
    header nav {
      position: absolute;
      top: 100px;
      right:300px;
    }
    
    nav ul {
      list-style-position: inside;
      width: 400px;
      padding: 0;
      list-style-type: none;
      font-size: 1em;
    }
    
    nav ul li{
      border-bottom: 1px solid white;
      padding: 10px 0 10px 0;
    }
    
    nav ul li:hover{
      font-weight: bold;
      padding: 10px 0 10px 10px;
    }
    
    li.active {
      font-weight: bold;
    }
    
    nav ul li:first-child{
    /*  border-top: 1px solid white;*/
    }
    
    nav ul li a{
      text-decoration: none;
    }
    
    nav ul h2{
      margin-bottom: 10px;
    }
    
    .tabcontent {
      display: none;
    }
    
    /* Header Icon */
    
    img.icon {
      position: absolute;
      z-index: 999;
      top:60px;
      right:70px;
    }
    
    /* Display */
    
    .display {
      width: 400px;
      height: 400px;
      position: absolute;
      top: 100px;
      right:750px;
    }
    
    .display p {
      margin:0 30px 30px 0;
    }
    <!doctype html>
    <html lang="en">
      <head>
        <!-- SETUP Industries - FUNCTIONAL DESIGN -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <!-- <link rel="shortcut icon" type="image/png" href="favicon.png"/> -->
    
    
        <!-- CSS -->
        <link rel="stylesheet" type="text/css" href="assets/style.css" />
    	  <link href="https://fonts.googleapis.com/css?family=Heebo:400,700,900" rel="stylesheet">
    
        <!-- JS -->
        <script src="assets/javascript.js"></script>
    
    
        <title>Masquarade Classix 2019</title>
      </head>
      <body>
    
      <!-- Navigation -->
    
        <!-- Icon -->
        <img onclick="openNav()"id="icon" src="http://setup.industries/masquarade/assets/icon.svg" class="icon" width="40" alt="Expand Navigation" />
        <header id="header">
    
          <nav>
            <ul>
              <h2>Information</h2>
              <li class="tablinks" onmouseover="openTab(event, 'Tickets')"><a href="#">Tickets and pricing </a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Location')"><a href="#">Location</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Transportation')"><a href="#">Transportation</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Amenities')"><a href="#">Ameneties</li>
              <li class="tablinks" onmouseover="openTab(event, 'HouseRules')"><a href="#">House rules</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'TermsAndConditions')"><a href="#">Terms and conditions</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Contact')"><a href="#">Contact</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Partners')"><a href="#">Partners</a></li>
            </ul>
          </nav>
    
    
    <div class="display">
    
    
          <div id="Tickets" class="tabcontent">
              <h2>Tickets and pricing</h2>
              <p>Saturday day tickets cost 45 EUR incl. service costs and 21% BTW. You can buy tickets online via the button below or at one of the resellers listed below.</p>
              <a href="#" class="button white">Buy Tickets</a>
              <br><br>
              <p style="font-size:0.8em;"> <strong>Paperpoint</strong><br>
                3930 Hamont-achel<br><br>
                <strong>Dag en nachtwinkel </strong><br>
                3900 Overpelt<br><br>
                <strong>VDM bvba, Q8 tankstation</strong> <br>
                Peer<br><br>
                <strong>Frituur De Kromme Draai</strong> <br>
                Eksel<br><br>
                <strong>’t frituurke</strong> <br>
                Haag 22, 3910 Achel<br></p>
          </div>
    
          <div id="Location" class="tabcontent">
              <h2>Location</h2>
          </div>
    
          <div id="Transportation" class="tabcontent">
              <h2>Transportation</h2>
          </div>
    
          <div id="Amenities" class="tabcontent">
              <h2>Amenities</h2>
          </div>
    
          <div id="HouseRules" class="tabcontent">
              <h2>House Rules</h2>
          </div>
    
          <div id="TermsAndConditions" class="tabcontent">
              <h2>Terms And Conditions</h2>
          </div>
    
          <div id="Contact" class="tabcontent">
              <h2>Contact</h2>
          </div>
    
          <div id="Partners" class="tabcontent">
              <h2>Partners</h2>
          </div>
    
    
    
    </div>
    
    
        </header>
      <!-- Navigation End -->
    <div class="container">
        <div id="ellipse" class="ellipse_left">
          <img src="assets/ellipse.svg" alt="ellipse" width="400" height="400"/>
        </div>
        <img class="masquarade_events" src="assets/masquarade_events.png" alt="Masquarade Events" width="125" height=""/>
    <div class="content">
    
        <p class="date">25 mei 2019</p>
        <p class="location">Hennemeeuwis Neerpelt</p>
        <h1>Masquarade Classix </h1>
        <ul class="lineup">
            <li>Nina Kraviz</li>
            <li>Recondite</li>
            <li>Mind Against</li>
            <li>Âme</li>
            <li>Vince Watson</li>
            <li>Kölsch</li>
            <li>Rodriguez Jr. </li>
            <li></li>
        </ul>
    <div class="clear"></div>
    
        <a href="#" class="button white">Buy Tickets</a>
        <a href="#" class="button black">More Information</a>
    
    </div>
    </div>
    
      </body>
    </html>
    2 回复  |  直到 7 年前
        1
  •  1
  •   Ray Chan    7 年前

    element.style的值是通过使用javascript或inline-style属性设置的,CSS不会为您设置该值。因此,如果使用CSS设置页眉宽度的样式,则 header.style.width 最初为空字符串,使表达式 header.style.width == '0%' 冒犯。

    您可以添加 console.log(document.getElementById('header').style.width) 亲自检查价值。

    因此,第一次单击汉堡包时,条件中的else块将始终运行。

    第一次点击汉堡包之后, document.getElementById('header').style.width 现在正通过javascript进行设置,因此随后的单击将按预期进行。

    为了解决这个问题,您可以使用一个inline-style属性来设置头部宽度的样式,或者使用javascript

    const headerWidth = getComputedStyle(document.getElementById('header')).width;
    const open = headerWidth === '0px' || headerWidth === '0%';
    
        2
  •  1
  •   Sølve T. DisgruntledGoat    7 年前

    你的开放逻辑颠倒了。只需更改100%/0%的顺序即可修复此问题。

    改进提示:

    1. 使用类而不是实际的CSS检查元素状态。(添加一个 open 当元素打开时将其类化,当元素未打开时将其移除)
    2. 通过执行上述操作,可以将宽度的操作移到CSS类中。 打开 : header.open {width: 100%}
    3. 通过使用“`”并将变量封装到 ${} 您可以去掉许多像这样的“+”:转换:`translatex($width px)`

    可以在代码段中看到:

    // open sidenav //
    
          function openNav() {
            let header = document.getElementById("header");
            let open = header.className.includes('open')
            let width = document.body.clientWidth;
            var ellipse = document.getElementById("ellipse");
    
            function moveEllipseRight() {
              ellipse.animate([
              // keyframes
              { transform: 'translateX(0)' },
              { transform:  `translateX(${width}px)` }
            ], {
              // timing options
              duration: 500,
              iterations: 1,
              easing: 'ease-in-out',
              fill: 'forwards'
            });}
    
            function moveEllipseLeft() {
              ellipse.animate([
              // keyframes
              { transform:  `translateX(${width}px)` },
              { transform: 'translateX(0)' }
            ], {
              // timing options
              duration: 500,
              iterations: 1,
              easing: 'ease-in-out',
              fill: 'forwards'
            });}
    
            // open sidenav //
    
            if (open) {
                 moveEllipseLeft();
                 header.classList.remove("open");
            } else {
                 moveEllipseRight();
                 header.classList.add("open");
               }
             }
    
    
    // information tabs //
    
    function openTab(evt, tab) {
      var i, tabcontent, tablinks;
      tabcontent = document.getElementsByClassName("tabcontent");
      for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
      }
      tablinks = document.getElementsByClassName("tablinks");
      for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
      }
      document.getElementById(tab).style.display = "block";
      evt.currentTarget.className += " active";
    }
    html, body {
        max-width: 100%;
        overflow-x: hidden;
    }
    body {
        background: black;
        color: white;
        font-family: 'Helvetica Neue', sans-serif;
        font-size: 1.2em;
        line-height: 1.4em;
    }
    
    a {
      color: white;
    }
    
    .clear {
      clear: both; float: none; height: 40px;
    }
    
    /* Ellipse */
    
    #ellipse {
      position: absolute;
      top: 120px;
      z-index:99;
      animation: 3s linear 0s slide 1;
      left: -200px;
    }
    
    /*
    .ellipse_left {left: -200px;}
    .ellipse_right {right: -200px;}
    */
    
    
    /* Masquarede Logo */
    
    img.masquarade_events {
      opacity: 0.3;
      position: absolute;
      bottom: 20px;
      right: 20px;
    }
    
    img.masquarade_events:hover {
      opacity: 0.9;
    }
    
    
    /* Content */
    
    .content {
      margin: 150px 0 0 300px;
      width: 700px;
      height: 400px;
    }
    
    @media screen and (max-width: 992px) {
      .content {
        margin: 150px 0 0 0;
        width: 700px;
        height: 400px;
      }
    }
    
    .date {
      font-weight: bold;
      margin-bottom: -10px;
    }
    
    .location {
    }
    
    ul.lineup {
      list-style-position: inside;
      padding: 0;
      list-style-type: none;
      width: 100%
      overflow: hidden;
      margin-bottom: 100px;
    }
    
    ul.lineup li {
      margin-right: 50px;
      line-height: 2.5em;
      float: left;
    }
    
    
    /* Buttons */
    
    a.button {
      margin-right: 10px;
      padding: 10px 50px 10px 50px;
      text-decoration: none;
      border-radius: 200px;
      font-size: 0.7em;
      transition: 0.3s;
    }
    
    a.white {
      background: white;
      color: black;
    }
    
    a.white:hover {
      color: white;
      background: #D90E46;
    }
    
    a.black {
      border: 2px white solid;
      color: white;
    }
    
    a.black:hover {
      border: 2px #FCF454 solid;
      color: #FCF454;
    }
    
    /* Header  */
    
    header {
      position: absolute;
      background-color: black;
      top:0;
      left:0;
      width: 0;
      height: 100%;
      z-index: 1;
    }
    /* Header animation css  */
    header.open {
      width: 100%;
    }
    
    /* Navigation  */
    
    header nav {
      position: absolute;
      top: 100px;
      right:300px;
    }
    
    nav ul {
      list-style-position: inside;
      width: 400px;
      padding: 0;
      list-style-type: none;
      font-size: 1em;
    }
    
    nav ul li{
      border-bottom: 1px solid white;
      padding: 10px 0 10px 0;
    }
    
    nav ul li:hover{
      font-weight: bold;
      padding: 10px 0 10px 10px;
    }
    
    li.active {
      font-weight: bold;
    }
    
    nav ul li:first-child{
    /*  border-top: 1px solid white;*/
    }
    
    nav ul li a{
      text-decoration: none;
    }
    
    nav ul h2{
      margin-bottom: 10px;
    }
    
    .tabcontent {
      display: none;
    }
    
    /* Header Icon */
    
    img.icon {
      position: absolute;
      z-index: 999;
      top:60px;
      right:70px;
    }
    
    /* Display */
    
    .display {
      width: 400px;
      height: 400px;
      position: absolute;
      top: 100px;
      right:750px;
    }
    
    .display p {
      margin:0 30px 30px 0;
    }
    <!doctype html>
    <html lang="en">
      <head>
        <!-- SETUP Industries - FUNCTIONAL DESIGN -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <!-- <link rel="shortcut icon" type="image/png" href="favicon.png"/> -->
    
    
        <!-- CSS -->
        <link rel="stylesheet" type="text/css" href="assets/style.css" />
    	  <link href="https://fonts.googleapis.com/css?family=Heebo:400,700,900" rel="stylesheet">
    
        <!-- JS -->
        <script src="assets/javascript.js"></script>
    
    
        <title>Masquarade Classix 2019</title>
      </head>
      <body>
    
      <!-- Navigation -->
    
        <!-- Icon -->
        <img onclick="openNav()"id="icon" src="http://setup.industries/masquarade/assets/icon.svg" class="icon" width="40" alt="Expand Navigation" />
        <header id="header">
    
          <nav>
            <ul>
              <h2>Information</h2>
              <li class="tablinks" onmouseover="openTab(event, 'Tickets')"><a href="#">Tickets and pricing </a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Location')"><a href="#">Location</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Transportation')"><a href="#">Transportation</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Amenities')"><a href="#">Ameneties</li>
              <li class="tablinks" onmouseover="openTab(event, 'HouseRules')"><a href="#">House rules</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'TermsAndConditions')"><a href="#">Terms and conditions</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Contact')"><a href="#">Contact</a></li>
              <li class="tablinks" onmouseover="openTab(event, 'Partners')"><a href="#">Partners</a></li>
            </ul>
          </nav>
    
    
    <div class="display">
    
    
          <div id="Tickets" class="tabcontent">
              <h2>Tickets and pricing</h2>
              <p>Saturday day tickets cost 45 EUR incl. service costs and 21% BTW. You can buy tickets online via the button below or at one of the resellers listed below.</p>
              <a href="#" class="button white">Buy Tickets</a>
              <br><br>
              <p style="font-size:0.8em;"> <strong>Paperpoint</strong><br>
                3930 Hamont-achel<br><br>
                <strong>Dag en nachtwinkel </strong><br>
                3900 Overpelt<br><br>
                <strong>VDM bvba, Q8 tankstation</strong> <br>
                Peer<br><br>
                <strong>Frituur De Kromme Draai</strong> <br>
                Eksel<br><br>
                <strong>’t frituurke</strong> <br>
                Haag 22, 3910 Achel<br></p>
          </div>
    
          <div id="Location" class="tabcontent">
              <h2>Location</h2>
          </div>
    
          <div id="Transportation" class="tabcontent">
              <h2>Transportation</h2>
          </div>
    
          <div id="Amenities" class="tabcontent">
              <h2>Amenities</h2>
          </div>
    
          <div id="HouseRules" class="tabcontent">
              <h2>House Rules</h2>
          </div>
    
          <div id="TermsAndConditions" class="tabcontent">
              <h2>Terms And Conditions</h2>
          </div>
    
          <div id="Contact" class="tabcontent">
              <h2>Contact</h2>
          </div>
    
          <div id="Partners" class="tabcontent">
              <h2>Partners</h2>
          </div>
    
    
    
    </div>
    
    
        </header>
      <!-- Navigation End -->
    <div class="container">
        <div id="ellipse" class="ellipse_left">
          <img src="assets/ellipse.svg" alt="ellipse" width="400" height="400"/>
        </div>
        <img class="masquarade_events" src="assets/masquarade_events.png" alt="Masquarade Events" width="125" height=""/>
    <div class="content">
    
        <p class="date">25 mei 2019</p>
        <p class="location">Hennemeeuwis Neerpelt</p>
        <h1>Masquarade Classix </h1>
        <ul class="lineup">
            <li>Nina Kraviz</li>
            <li>Recondite</li>
            <li>Mind Against</li>
            <li>Âme</li>
            <li>Vince Watson</li>
            <li>Kölsch</li>
            <li>Rodriguez Jr. </li>
            <li></li>
        </ul>
    <div class="clear"></div>
    
        <a href="#" class="button white">Buy Tickets</a>
        <a href="#" class="button black">More Information</a>
    
    </div>
    </div>
    
      </body>
    </html>