CSS last 的类型在仍在加载时不匹配

Posted

技术标签:

【中文标题】CSS last 的类型在仍在加载时不匹配【英文标题】:CSS last of type does not match while still loading 【发布时间】:2018-09-06 00:35:41 【问题描述】:

我想我在 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>

任何提示将不胜感激。

【问题讨论】:

如果您认为您在浏览器中发现了错误,您应该向他们报告。除非您想询问有关如何解决该错误的问题,否则您不会在此处发布任何内容。 你可以的辛巴,我想找到解决办法 您能否发布一个指向您的 github 存储库的链接(假设它不是私有的)。 github.com/GrosSacASac/javascript-Set-Up/tree/master/general/… npm in npm run demo3 【参考方案1】:

一种可能的解决方法是在页面加载时使用MutationObserver。在那里你可以得到section 的所有元素的列表,并给最后一个元素一个特殊的类last。每次 dom 更改都会调用 MutationObserver,即使页面仍在加载。加载页面后,您可以删除此观察者。

"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`);

观察者必须连接在&lt;bod&gt;标签之后。否则document.bodynull

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

【讨论】:

几乎是一个 polyfill 到 :last-of-type

以上是关于CSS last 的类型在仍在加载时不匹配的主要内容,如果未能解决你的问题,请参考以下文章

jQuery UI 自动完成 - 输入与结果集不匹配时不显示结果

在css3中这些选择器怎么用, E[A^=v] E[A$=v] E[A*=v] E:nth-child(n) E:nth-last-child

IE浏览器“SEC7113: CSS 因 Mime 类型不匹配而被忽略”问题的解决方法

本地文件(无服务器)上的 Internet Explorer“由于 mime 类型不匹配而忽略 CSS”

本地文件(无服务器)上的 Internet Explorer“由于 mime 类型不匹配而忽略 CSS”

$("#table>tbody>tr:has(td:last:has(:checkbox:enabled))").css("background",