css 未触发页面转换的转换
css transition for page transitioin not triggering
我有一个页面转换,我正试图在我的网站中使用。我有 2 个 50% 高度、100% 宽度的元素,一个放在主体之前和之后(带有伪选择器)。我希望这 2 个元素滑到屏幕中间,覆盖背景内容。当 "is-changing" class 通过 Javascript.
添加到 body 时触发转换
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
属性(通常这将是空的,例如 content: ""
)。没有这个属性,你的伪元素将不会存在于DOM中。 运行 你的代码片段并检查它证实了这一点,因为伪元素无处可寻。
其次,您正在创建多个伪元素。 body::before
是它自己的伪元素,而 body.is-changing::before
是一个单独的伪元素。如果您希望创建一组常量元素作为加载显示的 "doors",您可能需要考虑创建两个位于视口上方和下方 position: fixed
的真实元素,然后滑动添加 class 时 in 或 out。也许这些可能是 div.upper-door
和 div.lower-door
.
此外,在我看来,您的转换需要过渡,否则伪元素将只是 "snap" 来回。通过使用 css 动画,您可以在此过渡期间的不同点控制元素的位置。您的 JavaScript 将基本保持不变,除了使用 document.querySelector()
定位 .upper-door
和 .lower-door
div,或者简单地使用 ID 而不是 classes 并使用getElementById()
,如果这对您更有意义。您的 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 动画的资源。
您可以使用以下
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>
您错过了在 pseudo-elements
上添加 content
属性,这是 强制性 以使其在页面上可用。您还错过了在 pseudo-elements
上添加 transition
属性 来实现您的滑动动画 up/down。
这是一个包含工作演示的片段,我只使用了与您的问题相关的代码:
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 about after
pseudo-element.
Learn more about before
pseudo-element.
我有一个页面转换,我正试图在我的网站中使用。我有 2 个 50% 高度、100% 宽度的元素,一个放在主体之前和之后(带有伪选择器)。我希望这 2 个元素滑到屏幕中间,覆盖背景内容。当 "is-changing" class 通过 Javascript.
添加到 body 时触发转换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
属性(通常这将是空的,例如 content: ""
)。没有这个属性,你的伪元素将不会存在于DOM中。 运行 你的代码片段并检查它证实了这一点,因为伪元素无处可寻。
其次,您正在创建多个伪元素。 body::before
是它自己的伪元素,而 body.is-changing::before
是一个单独的伪元素。如果您希望创建一组常量元素作为加载显示的 "doors",您可能需要考虑创建两个位于视口上方和下方 position: fixed
的真实元素,然后滑动添加 class 时 in 或 out。也许这些可能是 div.upper-door
和 div.lower-door
.
此外,在我看来,您的转换需要过渡,否则伪元素将只是 "snap" 来回。通过使用 css 动画,您可以在此过渡期间的不同点控制元素的位置。您的 JavaScript 将基本保持不变,除了使用 document.querySelector()
定位 .upper-door
和 .lower-door
div,或者简单地使用 ID 而不是 classes 并使用getElementById()
,如果这对您更有意义。您的 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 动画的资源。
您可以使用以下
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>
您错过了在 pseudo-elements
上添加 content
属性,这是 强制性 以使其在页面上可用。您还错过了在 pseudo-elements
上添加 transition
属性 来实现您的滑动动画 up/down。
这是一个包含工作演示的片段,我只使用了与您的问题相关的代码:
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 about
after
pseudo-element.Learn more about
before
pseudo-element.