CSS 最后一个类型在加载时不匹配
CSS last of type does not match while still loading
我想我在 chrome 和 opera 中发现了一个错误,并且想要一个解决方案来使 css 选择器 section:last-of-type
在文档仍在加载时工作。该错误仅在文档仍在加载时出现:这是 NodeJS 中暴露错误的最小示例:
发生的情况是在文档仍在加载时最后一个类型不匹配。在 IE 中它匹配,然后匹配两次,然后在加载时再次正确匹配。它在 Firefox 中运行良好。
最后-type.js
"use strict";
const http = require(`http`);
const PORT = 8080;
const htmlStart = `<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<title>html streaming</title>
<meta name="viewport" content="width=device-width">
<style>
section {
position: absolute;
left: 0;
right: 0;
}
section:last-of-type {
animation: comin 1.4s ease 0s;
left: 0;
opacity: 1;
}
@keyframes comin {
0% {
left: 100%;
}
100% {
left: 0;
}
}
section:not(:last-of-type) {
animation: comout 1.4s ease 0s;
left: -100%;
opacity: 0;
}
@keyframes comout {
0% {
left: 0;
opacity: 1;
}
100% {
left: -100%;
opacity: 0;
}
}
</style>
<script>
var headLoaded = Date.now();
document.addEventListener("DOMContentLoaded", function() {
console.log((Date.now() - headLoaded) / 1000);
});
</script>
</head>
<body>
<h1>last-of-type test</h1>
<section>
<h2>First slide</h2>
<p>Some text 111111111</p>
</section>
<section>
<h2>2</h2>
<p>22222222222222</p>
</section>
`;
const htmlEnd = `
<p>html finised loading</p>
</body></html>`;
const INTERVAL = 8000; // ms
const server = http.createServer((request, response) => {
response.setHeader(`Content-Type`, `text/html`);
response.writeHead(200);
response.write(htmlStart);
setTimeout(function () {
response.write(`<section>
<h2>3</h2>
<p>33333333333</p>
</section>`);
}, INTERVAL);
setTimeout(function () {
response.end(htmlEnd);
}, 3 * INTERVAL);
});
server.listen(PORT);
console.log(`Listening on ${PORT}`);
一次加载相同的内容就可以了。它确认语法正确。
最后类型-test.html
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<title>html streaming</title>
<meta name="viewport" content="width=device-width">
<style>
section {
position: absolute;
left: 0;
right: 0;
}
section:last-of-type {
animation: comin 1.4s ease 0s;
left: 0;
opacity: 1;
}
@keyframes comin {
0% {
left: 100%;
}
100% {
left: 0;
}
}
section:not(:last-of-type) {
animation: comout 1.4s ease 0s;
left: -100%;
opacity: 0;
}
@keyframes comout {
0% {
left: 0;
opacity: 1;
}
100% {
left: -100%;
opacity: 0;
}
}
</style>
<script>
var headLoaded = Date.now();
document.addEventListener("DOMContentLoaded", function() {
console.log((Date.now() - headLoaded) / 1000);
});
</script>
</head>
<body>
<h1>last-of-type test</h1>
<section>
<h2>First slide</h2>
<p>some text</p>
</section>
<section>
<h2>2</h2>
<p>22222222222222</p>
</section>
<section>
<h2>3</h2>
<p>33333333333</p>
</section>
</body></html>
如有任何提示,我们将不胜感激。
一种可能的解决方法是在加载页面时使用 MutationObserver。在那里您可以获得 section
的所有元素的列表,并为最后一个元素指定一个特殊的 class last
。 MutationObserver
会在每次 dom 更改时调用,即使页面仍在加载中也是如此。加载页面后,您可以删除此观察者。
"use strict";
const http = require(`http`);
const PORT = 8080;
const htmlStart = `<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<title>html streaming</title>
<meta name="viewport" content="width=device-width">
<style>
section {
position: absolute;
left: 0;
right: 0;
}
section:not(:last-of-type) {
animation: comout 1.4s ease 0s;
left: -100%;
opacity: 0;
}
section:last-of-type, section.last {
animation: comin 1.4s ease 0s;
left: 0;
opacity: 1;
}
@keyframes comin {
0% {
left: 100%;
}
100% {
left: 0;
}
}
@keyframes comout {
0% {
left: 0;
opacity: 1;
}
100% {
left: -100%;
opacity: 0;
}
}
</style>
<script>
var observer = new MutationObserver(function() {
var list = document.querySelectorAll("section");
if (list.length === 0) return;
for (var i = 0; i < list.length; i++) {
list[i].classList.remove("last");
}
list[list.length - 1].classList.add("last");
});
var headLoaded = Date.now();
document.addEventListener("DOMContentLoaded", function() {
console.log((Date.now() - headLoaded) / 1000);
observer.disconnect();
var list = document.querySelectorAll("section");
for (var i = 0; i < list.length; i++) {
list[i].classList.remove("last");
}
});
</script>
</head>
<body>
<script>
observer.observe(document.body, { attributes: true, childList: true })
</script>
<h1>last-of-type test</h1>
<section>
<h2>First slide</h2>
<p>Some text 111111111</p>
</section>
<section>
<h2>2</h2>
<p>22222222222222</p>
</section>
`;
const htmlEnd = `
<p>html finised loading</p>
</body></html>`;
const INTERVAL = 8000; // ms
const server = http.createServer((request, response) => {
response.setHeader(`Content-Type`, `text/html`);
response.writeHead(200);
response.write(htmlStart);
setTimeout(function () {
response.write(`<section>
<h2>3</h2>
<p>33333333333</p>
</section>`);
}, INTERVAL);
setTimeout(function () {
response.end(htmlEnd);
}, 3 * INTERVAL);
});
server.listen(PORT);
console.log(`Listening on ${PORT}`);
观察者必须连接在<bod>
标签之后。否则 document.body
是 null
.
我将 css 选择器 section:not(:last-of-type)
放在正匹配之前以避免使用 !important
指令。
我想我在 chrome 和 opera 中发现了一个错误,并且想要一个解决方案来使 css 选择器 section:last-of-type
在文档仍在加载时工作。该错误仅在文档仍在加载时出现:这是 NodeJS 中暴露错误的最小示例:
发生的情况是在文档仍在加载时最后一个类型不匹配。在 IE 中它匹配,然后匹配两次,然后在加载时再次正确匹配。它在 Firefox 中运行良好。
最后-type.js
"use strict";
const http = require(`http`);
const PORT = 8080;
const htmlStart = `<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<title>html streaming</title>
<meta name="viewport" content="width=device-width">
<style>
section {
position: absolute;
left: 0;
right: 0;
}
section:last-of-type {
animation: comin 1.4s ease 0s;
left: 0;
opacity: 1;
}
@keyframes comin {
0% {
left: 100%;
}
100% {
left: 0;
}
}
section:not(:last-of-type) {
animation: comout 1.4s ease 0s;
left: -100%;
opacity: 0;
}
@keyframes comout {
0% {
left: 0;
opacity: 1;
}
100% {
left: -100%;
opacity: 0;
}
}
</style>
<script>
var headLoaded = Date.now();
document.addEventListener("DOMContentLoaded", function() {
console.log((Date.now() - headLoaded) / 1000);
});
</script>
</head>
<body>
<h1>last-of-type test</h1>
<section>
<h2>First slide</h2>
<p>Some text 111111111</p>
</section>
<section>
<h2>2</h2>
<p>22222222222222</p>
</section>
`;
const htmlEnd = `
<p>html finised loading</p>
</body></html>`;
const INTERVAL = 8000; // ms
const server = http.createServer((request, response) => {
response.setHeader(`Content-Type`, `text/html`);
response.writeHead(200);
response.write(htmlStart);
setTimeout(function () {
response.write(`<section>
<h2>3</h2>
<p>33333333333</p>
</section>`);
}, INTERVAL);
setTimeout(function () {
response.end(htmlEnd);
}, 3 * INTERVAL);
});
server.listen(PORT);
console.log(`Listening on ${PORT}`);
一次加载相同的内容就可以了。它确认语法正确。
最后类型-test.html
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<title>html streaming</title>
<meta name="viewport" content="width=device-width">
<style>
section {
position: absolute;
left: 0;
right: 0;
}
section:last-of-type {
animation: comin 1.4s ease 0s;
left: 0;
opacity: 1;
}
@keyframes comin {
0% {
left: 100%;
}
100% {
left: 0;
}
}
section:not(:last-of-type) {
animation: comout 1.4s ease 0s;
left: -100%;
opacity: 0;
}
@keyframes comout {
0% {
left: 0;
opacity: 1;
}
100% {
left: -100%;
opacity: 0;
}
}
</style>
<script>
var headLoaded = Date.now();
document.addEventListener("DOMContentLoaded", function() {
console.log((Date.now() - headLoaded) / 1000);
});
</script>
</head>
<body>
<h1>last-of-type test</h1>
<section>
<h2>First slide</h2>
<p>some text</p>
</section>
<section>
<h2>2</h2>
<p>22222222222222</p>
</section>
<section>
<h2>3</h2>
<p>33333333333</p>
</section>
</body></html>
如有任何提示,我们将不胜感激。
一种可能的解决方法是在加载页面时使用 MutationObserver。在那里您可以获得 section
的所有元素的列表,并为最后一个元素指定一个特殊的 class last
。 MutationObserver
会在每次 dom 更改时调用,即使页面仍在加载中也是如此。加载页面后,您可以删除此观察者。
"use strict";
const http = require(`http`);
const PORT = 8080;
const htmlStart = `<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<title>html streaming</title>
<meta name="viewport" content="width=device-width">
<style>
section {
position: absolute;
left: 0;
right: 0;
}
section:not(:last-of-type) {
animation: comout 1.4s ease 0s;
left: -100%;
opacity: 0;
}
section:last-of-type, section.last {
animation: comin 1.4s ease 0s;
left: 0;
opacity: 1;
}
@keyframes comin {
0% {
left: 100%;
}
100% {
left: 0;
}
}
@keyframes comout {
0% {
left: 0;
opacity: 1;
}
100% {
left: -100%;
opacity: 0;
}
}
</style>
<script>
var observer = new MutationObserver(function() {
var list = document.querySelectorAll("section");
if (list.length === 0) return;
for (var i = 0; i < list.length; i++) {
list[i].classList.remove("last");
}
list[list.length - 1].classList.add("last");
});
var headLoaded = Date.now();
document.addEventListener("DOMContentLoaded", function() {
console.log((Date.now() - headLoaded) / 1000);
observer.disconnect();
var list = document.querySelectorAll("section");
for (var i = 0; i < list.length; i++) {
list[i].classList.remove("last");
}
});
</script>
</head>
<body>
<script>
observer.observe(document.body, { attributes: true, childList: true })
</script>
<h1>last-of-type test</h1>
<section>
<h2>First slide</h2>
<p>Some text 111111111</p>
</section>
<section>
<h2>2</h2>
<p>22222222222222</p>
</section>
`;
const htmlEnd = `
<p>html finised loading</p>
</body></html>`;
const INTERVAL = 8000; // ms
const server = http.createServer((request, response) => {
response.setHeader(`Content-Type`, `text/html`);
response.writeHead(200);
response.write(htmlStart);
setTimeout(function () {
response.write(`<section>
<h2>3</h2>
<p>33333333333</p>
</section>`);
}, INTERVAL);
setTimeout(function () {
response.end(htmlEnd);
}, 3 * INTERVAL);
});
server.listen(PORT);
console.log(`Listening on ${PORT}`);
观察者必须连接在<bod>
标签之后。否则 document.body
是 null
.
我将 css 选择器 section:not(:last-of-type)
放在正匹配之前以避免使用 !important
指令。