【问题标题】:css transition for page transitioin not triggering页面转换的css转换未触发
【发布时间】:2019-02-23 00:58:18
【问题描述】:

我正在尝试在我的网站中进行页面转换。我有 2 个 50% 高度、100% 宽度的元素,一个放置在正文之前和之后(带有伪选择器)。我希望 2 个元素滑动到屏幕中间,覆盖背景内容。当通过 Javascript 将“正在改变”的类添加到主体时触发转换。

document.getElementById("btn").addEventListener("click", fakeReq);

function fakeReq() {
  let body = document.body;
  body.classList.add("is-changing");
  console.log("class added");
  setTimeout(function() {
    body.classList.remove("is-changing");
    console.log("class removed");
  }, 5000);
}
body {
  height: 100vh; 
  width: 100%;
  background-color: grey; 
}

main {
  display: flex;
  height: 100%; 
  justify-content: center; 
  align-items: center; 
}


body::after, body::before {
	height: 50vh; 
	width: 100%; 
	position: fixed; 
	left: 0; 
	background-color: blue; 
	z-index: 10; 

}

body::before {
	top: 0; 
	transform: translateY(-100%); 
}

body::after {
	bottom: 0; 
	transform: translateY(100%);
}

body.is-changing::after, body.is-changing::before {
	transform: translateY(0); 
}

.loading-bar {
	position: fixed; 
	height: 2px; 
	width: 90%; 
}

.loading-bar::before {
	position: absolute; 
	background-color: aqua; 
	left: 0; 
	top: 0; 
	height: 100%; 
	width: 100%; 
	transform: scaleX(0);
	transform-origin: left center; 
}

.is-changing .loading-bar::before {
	transform: scaleX(1);
}
<body>
  <main>
    <div class="index main-content">
      <h1>Home Page</h1>
      <button id="btn">html request</button>
    </div>
  </main>
</body>

【问题讨论】:

  • 伪元素需要content:"",并且需要添加过渡

标签: css css-transitions css-transforms


【解决方案1】:

在我看来,您遇到了两个问题。

第一个问题是您忘记在伪元素中包含content 属性(通常这将是空的,例如content: "")。如果没有这个属性,你的伪元素将不会存在于 DOM 中。运行您的代码 sn-p 并检查它可以确认这一点,因为找不到伪元素。

其次,您正在创建多个伪元素。 body::before 是它自己的伪元素,body.is-changing::before 是一个单独的伪元素。如果您希望创建一组恒定的元素作为加载显示的“门”,您可能需要考虑创建两个真实元素,它们位于视口上方和下方的position: fixed,然后在何时滑入或滑出。添加了一个类。也许这些可能是div.upper-doordiv.lower-door

另外,在我看来,您的变换需要一个过渡,否则伪元素只会来回“捕捉”。您可以通过使用 css 动画在此过渡期间控制元素在不同点的位置。除了使用document.querySelector() 来定位.upper-door.lower-door div,或者简单地使用ID 而不是类并使用getElementById() 定位之外,您的JavaScript 将基本保持不变,如果这对您更有意义的话。您的 CSS 可能如下所示:

div.upper-door {
    top: 0;
    transform: translateY(-100%);
}

div.upper-door.is-changing {
    animation-duration: 5s;
    animation-name: upper-door-closeopen;
}

div.lower-door {
    bottom: 0;
    transform: translateY(100%);
}

div.lower-door.is-changing {
    animation-duration: 5s;
    animation-name: lower-door-closeopen;
}

@keyframes upper-door-closeopen {
    0% {
        transform: translateY(-100%);
    }
    25% {
        transform: translateY(0);
    }
    75% {
        transform: translateY(0);
    }
    100% {
        transform: translateY(-100%);
    }
}

@keyframes lower-door-closeopen {
    0% {
        transform: translateY(100%);
    }
    25% {
        transform: translateY(0);
    }
    75% {
        transform: translateY(0);
    }
    100% {
        transform: translateY(100%);
    }
}

.is-changing添加到元素时会触发css动画。在您进行实验时,您可能会发现此解决方案的不同排列(例如,如果单击按钮触发加载屏幕,则使用事件侦听器)是理想的。

如果您想了解更多信息,MDN 上有一个很棒的 CSS 动画资源。

【讨论】:

    【解决方案2】:

    您错过了在pseudo-elements 上添加content 属性,这是强制以使它们在页面上可用。您还错过了在pseudo-elements 上添加transition 属性来实现上/下滑动的动画。

    这是一个包含工作演示的 sn-p,我只使用了与您的问题相关的代码:

    document.getElementById("btn").addEventListener("click", fakeReq);
    
    function fakeReq() {
      let body = document.body;
      body.classList.add("is-changing");
      console.log("class added");
      setTimeout(function() {
        body.classList.remove("is-changing");
        console.log("class removed");
      }, 5000);
    }
    body {
      height: 100vh; 
      width: 100%;
      background-color: grey;
      position: relative; /* not really related to your issue but, to make sure that the body's pseudo-elements are positioned relative to the body */
    }
    
    main {
      display: flex;
      height: 100%; 
      justify-content: center; 
      align-items: center; 
    }
    
    
    body::after, body::before {
        content: ""; /* make the pseudo-elements available */
    	height: 50vh; 
    	width: 100%; 
    	position: fixed; 
    	left: 0; 
    	background-color: blue; 
    	z-index: 10; 
        transition: all .8s ease-out; /* allow the animation, change this rule per your requirements */
    }
    
    body::before {
    	top: 0; 
    	transform: translateY(-100%); 
    }
    
    body::after {
    	bottom: 0; 
    	transform: translateY(100%);
    }
    
    body.is-changing::after, body.is-changing::before {
    	transform: translateY(0); 
    }
    <body>
      <main>
        <div class="index main-content">
          <h1>Home Page</h1>
          <button id="btn">html request</button>
        </div>
      </main>
    </body>

    Learn more 关于after 伪元素。

    Learn more 关于before 伪元素。

    【讨论】:

      【解决方案3】:

      你可以使用下面的

      document.getElementById("btn").addEventListener("click", fakeReq);
      
      function fakeReq() {
        let body = document.body;
        body.classList.add("is-changing");
        console.log("class added");
        setTimeout(function() {
          body.classList.remove("is-changing");
          console.log("class removed");
        }, 5000);
      }
      body {
        height: 100vh; 
        width: 100%;
        background-color: grey; 
      }
      
      main {
        display: flex;
        height: 100%; 
        justify-content: center; 
        align-items: center; 
      }
      
      
      body::after, body::before {
      content:'';
      	height: 50vh; 
      	width: 100%; 
      	position: fixed; 
      	left: 0; 
      	background-color: blue; 
      	z-index: 10; 
      
      }
      
      body::before {
      content:'';
      	top: 0; 
      	transform: translateY(-100%); 
        transition: .5s all;
      }
      
      body::after {
      content:'';
      	bottom: 0; 
      	transform: translateY(100%);
      }
      
      body.is-changing::after, body.is-changing::before {
      content:'';
      	transform: translateY(0); 
      }
      
      .loading-bar {
      	position: fixed; 
      	height: 2px; 
      	width: 90%; 
      }
      
      .loading-bar::before {
      content:'';
      	position: absolute; 
      	background-color: aqua; 
      	left: 0; 
      	top: 0; 
      	height: 100%; 
      	width: 100%; 
      	transform: scaleX(0);
      	transform-origin: left center; 
      }
      
      .is-changing,.loading-bar::before {
      	transform: scaleX(1);
      }
      <body>
        <main>
          <div class="index main-content">
            <h1>Home Page</h1>
            <button id="btn">html request</button>
          </div>
        </main>
      </body>

      【讨论】:

        猜你喜欢
        • 2013-01-01
        • 2014-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-15
        • 2017-01-19
        • 2016-09-26
        • 2021-04-23
        相关资源
        最近更新 更多