html - CSS 最后一个类型在加载时不匹配

标签 html css google-chrome internet-explorer opera

我想我在 chrome 和 opera 中发现了一个错误,并且想要一个解决方案来使 css 选择器 section:last-of-type 在文档仍在加载时工作。该错误仅在文档仍在加载时出现:这是 NodeJS 中暴露错误的最小示例:

发生的情况是在文档仍在加载时最后类型不匹配。在 IE 中它匹配,然后匹配两次,然后在加载时再次正确匹配。它在 Firefox 中运行良好。

last-of-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}`);

一次加载相同的内容就可以了。它确认语法正确。

last-of-type-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 的所有元素的列表。并给最后一个元素一个特殊的类 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.bodynull .

我把 css 选择器 section:not(:last-of-type)在正匹配之前避免使用 !important指令。

关于html - CSS 最后一个类型在加载时不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49515634/

相关文章:

Javascript - 粘性按钮取决于标题宽度

html - 为什么 'max-width' 被忽略到表格单元格上?

html - 调整大小以始终适合浏览器的背景视频

javascript - 更改折叠的导航栏列表背景颜色

javascript - 在不同的事件上应用不同的样式?

html - 如何在 ionicframework 中显示图像标题?

html - 为什么 CSS 样式在 Chrome 开发者工具中显示为灰色?

python - 如何在 Selenium 中正确启动 Chrome

javascript - 如何防止 window.location.pathname 转义 URL 中的字符

html - 使用 css 使边框宽度为其父元素高度的一半?