jjzjj

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

coder 2023-08-09 原文

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

有关html - CSS 最后一个类型在加载时不匹配的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby - capybara field.has_css?匹配器 - 2

    我在MiniTest::Spec和Capybara中使用以下规范:find_field('Email').must_have_css('[autofocus]')检查名为“电子邮件”的字段是否具有autofocus属性。doc说如下:has_css?(path,options={})ChecksifagivenCSSselectorisonthepageorcurrentnode.据我了解,字段“Email”是一个节点,因此调用must_have_css绝对有效!我做错了什么? 最佳答案 通过JonasNicklas得到了答案:No

  5. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  6. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  7. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  8. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  9. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  10. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

随机推荐