据我所知,pageXOffset/pageYOffset
自Netscape 4时代以来,物业已经可用.
似乎scrollX/scrollY
大概是在Netscape 6中引入的.
替代问题:
Q2.是否有一个浏览器实现scrollX/scrollY但不支持pageXOffset/pageYOffset?
我将添加第三个问题,因为没有人能够回答以前的问题:
Q3.scrollX/scrollY被添加到CCSOM的最新编辑器草稿中,工作草案只获得了pageXOffset/pageYOffset,为什么它们都保留了这两个属性?
在推迟attirbute时,MDN说:
此布尔属性设置为向浏览器指示在解析文档之后但在触发DOMContentLoaded之前要执行脚本.defer属性应仅用于外部脚本.
在DOMContentLoaded
MDN上也说:
完全加载和解析初始HTML文档时会触发DOMContentLoaded事件,而无需等待样式表 ...
所以DOMContentLoaded
在CSSOM
准备好之前就被解雇了.这意味着延迟脚本在准备好之前执行CSSOM
.但如果这是真的,那些scrips必须无法获得正确的css属性值,并且不能正确应用css.但事实并非如此,我们知道所有延迟脚本都能正常运行.
PS:请不要谷歌说在执行任何内联javscript之前构建CSSOM
但谷歌在技术上是不正确的.在CSSOM准备好之前,内联JavaScript会被执行.从我的测试中我发现MDN是正确的,如果在css文件(或js是内联)之前下载了js文件(延迟和非延迟),那么在CSSOM准备好之前执行js.所以js可能会错误地处理样式.为了避免这种情况,我们需要在所有js逻辑之前进行强制回流.
因此,如果用户访问我们的网站时所有需要缓存的js和css没有缓存,或者在css之前下载了js,那么他可能会看到错误渲染的页面.为了避免这种情况,我们应该在所有网站的js文件中添加强制重排.
为了构建渲染树,浏览器需要 DOM 和 CSSOM。CSSOM 只有在下载 CSS 后才能构建。本质上,一旦下载了 CSS,页面就应该可以正常渲染了。但是,为什么我们会在页面上看到 Flash Of Unstyled Content(FOUC)呢?浏览器在什么时间窗口显示无样式内容?
请帮助我理解这一点。
参考: https://developers.google.com/web/fundamentals/performance/ritic-rendering-path/render-blocking-css
所以,我有#Wrapper
一个固定宽度的DIV .在那个DIV里面,我有另一个#Panel
也有固定宽度的DIV :
<div id="Wrapper">
<p>...</p>
<div id="Panel">Panel</div>
<p>...</p>
</div>
Run Code Online (Sandbox Code Playgroud)
有时,Panel的宽度大于Wrapper的宽度,在这种情况下,我想通过JavaScript扩展Wrapper,以便它完美地包裹Panel.
现场演示: http ://jsfiddle.net/H6rML/
我打算.scrollWidth
在Wrapper 上使用来确定Panel的宽度.然而,问题是包装器具有水平填充,并且由于.scrollWidth
某种原因仅包括包装器的左填充.所以:
Wrapper.scrollWidth === Wrapper.LeftPadding + Panel.Width
Run Code Online (Sandbox Code Playgroud)
所以,给定:
#Wrapper {
width: 200px;
padding: 10px;
}
#Panel {
width: 300px;
}
Run Code Online (Sandbox Code Playgroud)
Wrapper.scrollWidth
返回310px
,这不是很有用.如果.scrollWidth
没有包含任何填充并且仅返回Panel的宽度,我可以使用它(我会手动将填充添加到该值).如果两个填充都包含在内,我也可以使用它.但为什么只包括左边填充?(顺便说一句,这种行为似乎是跨浏览器.)
一些额外的说明:
我无法直接在Wrapper上设置宽度.在我的实际代码中,我在一个祖先元素上设置宽度,该元素比Wrapper高几级,我使用自定义API来设置宽度.这就是我需要检索完整320px
值的原因.
我想要一个不依赖于Wrapper内容的解决方案.在我的演示中,它是一个Panel,但在其他情况下,可能会有一个不同的元素溢出,甚至是多个元素.这就是为什么我.scrollWidth
选择Wrapper.
有没有办法获得值320px
而无需手动添加正确的填充.scrollWidth
值?
顺便说一句,根据标准,应该包括正确的填充:
scrollWidth属性必须返回运行这些步骤的结果:
如果元素没有任何关联的CSS布局框,则返回零并终止这些步骤.
如果元素是根元素而Document不在quirks模式下则返回max(文档内容宽度,innerWidth的值).
如果元素是HTML body元素并且Document处于quirks模式,则返回max(文档内容宽度,innerWidth的值).
返回'padding-left'属性的计算值,加上'padding-right'的计算值,加上元素的内容宽度.
资料来源:http://www.w3.org/TR/cssom-view/
为什么浏览器没有相应的行为?
为了进一步提高我的帖子的清晰度,让我总结两个主要问题:
(1)如果标准声明右边的填充应该包含在.scrollWidth
值中,那么浏览器为什么不相应地表现呢?
(2)是否可以检索正确的值(320px
在我的情况下),而无需手动添加正确的填充? …
关于浏览器内的Javascript,该window.getComputedStyle()
方法应该给出应用于元素的CSS属性的最终使用值.根据MDN文档,这意味着"在完成所有计算后".
但是,似乎"所有计算"都不包括保证金崩溃.在Firefox和Chrome中(至少),指令getComputedStyle().marginBottom
在计算任何边距折叠之前返回计算值.
例如,考虑以下元素:
<div style="margin: 10px 0 15px 0"></div>
Run Code Online (Sandbox Code Playgroud)
它的顶部和底部边距将被折叠,因为(大致)其内容高度为零(参见W3C CSS2建议书).CSSOM方法将返回以下值:
getComputedStyle().marginTop ? 10px
getComputedStyle().marginBottom ? 15px
getBoundingClientRect().top ? {top of margin box} + marginTop
getBoundingClientRect().bottom ? idem top
Run Code Online (Sandbox Code Playgroud)
但是,由于边缘折叠,布局在边界客户矩形之前显示10px的边距,之后的边距为5px,即max(0, marginBottom - marginTop)
.
为什么不getComputedStyle().marginBottom
直接返回5px,实际使用的值"在所有计算完成后",而不是指定的15px?这是W3C推荐的行为吗?(我在w3.org文档中没有看到任何相关内容.)
这是一个错误还是一个功能?
你能告诉我为什么我们只需要使用这个getPropertyValue
方法就可以使用这个方法getComputedStyle
吗?
例如,据我所知,这将起作用:
var s = getComputedStyle(element, null).opacity;
Run Code Online (Sandbox Code Playgroud)
这相当于以下内容:
var s = getComputedStyle(element, null).getPropertyValue('opacity');
Run Code Online (Sandbox Code Playgroud)
我们可以getComputedStyle
不用getPropertyValue
吗?
我正在解析返回的颜色字符串,getComputedStyle
以从中获取R
、G
、B
和A
值。
到目前为止(在 Chrome 和 Firefox 中),颜色值似乎总是以易于解析的rgb
或格式返回:rgba
const [, r, g, b, a] = str.replace(/\s/g, "").match(/rgba?\((\d+(?:\.\d+)?),(\d+(?:\.\d+)?),(\d+(?:\.\d+)?)(?:,(\d+(?:\.\d+)?))?\)/i);
Run Code Online (Sandbox Code Playgroud)
然而,我无法在其MDN 页面上列出的任何规格中找到有关颜色格式的任何承诺。getComputedStyle
颜色格式有保证吗getComputedStyle
?还是完全取决于浏览器的实现?
我不想检查 HEX 和 HSLA 值(实际上还有其他可能的值 - 我不完全确定)。
用于在控制台中测试颜色值的快速代码片段:
const [, r, g, b, a] = str.replace(/\s/g, "").match(/rgba?\((\d+(?:\.\d+)?),(\d+(?:\.\d+)?),(\d+(?:\.\d+)?)(?:,(\d+(?:\.\d+)?))?\)/i);
Run Code Online (Sandbox Code Playgroud)
如果我用CSSOM添加了样式,insertRule
我注意到了两件事.
在Firebug中查看时,添加的样式不会出现在html中.
如果附加样式标记(例如:从头部移动到主体)到另一个元素(在Firefox和Chrome中发生),则添加的样式不起作用.
如果在添加标记后添加样式,则它们可以正常工作.他们仍然没有在Firebug中展示.附加表格时必须重新分配(重新?),这使得它看起来更奇怪.
因为没有在Firebug中显示,它可能是Firebug的怪癖,但是没有动态添加的常规样式显示出来.
对于追加后不起作用的样式我想知道这是否是标准,因为这发生在Firefox和Chrome中.看看标准,我没有看到任何关于这一点.除非我只是不理解他们.
var style = document.createElement('style'),
sheet = style.sheet;
document.head.appendChild(style);
//When line 6 is un-commented the styles work
//if line 8 is also commented out.
//document.querySelector('.container').appendChild(style);
//Get the sheet when line 6 is un-commented
sheet = style.sheet
sheet.insertRule('.test{color: red}');
document.querySelector('.container').appendChild(style);
//styles don't apply after the previous line
Run Code Online (Sandbox Code Playgroud)
为清晰起见编辑:
如果您<style></style>
在<head></head>
html中添加标签,则可以应用样式style.sheet.insertRule(styleString)
,并且添加的样式将适用于该文档.
如果您已经是附加<style></style>
的<head></head>
像<head><style></style></head>
,并试图追加<style></style>
其他地方像<div><style></style></div>
所有样式都将丢失,而不要再次申请.
这是正常的吗?
代码流程:
作品:
<style>
任何地方style.sheet.insertRule(styleString) …
假设我有
<head>
<style type="text/css" id="style1">
.foo {
...
}
</style>
<style type="text/css" id="style2">
.bar {
...
}
</style>
</head>
<body>
<div class="foo">
</div>
</body>
Run Code Online (Sandbox Code Playgroud)
在Chrome DevTools中,<div class="foo">
元素的样式检查器将具有指向定义<style id="style1">
标签的链接.foo
。
是否有任何DOM API可以有效地进行查找?
我能想到的找到<style>
元素的唯一方法是像这样的低效率的蛮力搜索:
function findStyleElementForClass(cls) {
if (!cls.startsWith('.')) cls = '.' + cls
for (var i = 0; i < document.styleSheets.length; i++) {
var sheet = document.styleSheets[i]
var rules = sheet.rules || sheet.cssRules
for (var j = 0; j < rules.length; j++) {
if …
Run Code Online (Sandbox Code Playgroud) 自从我阅读/了解CSSOM以来,这个问题的答案一直很清晰,直到今天。我似乎无法能够找到最初的文章,但它解释很清楚,结合实例,即JavaScript执行被延迟,直到CSSOM从所有内置<style>
和<link>
标签<head>
(除了那些不适用,基于@media
查询)。
或者至少那是我当时所做的,直到今天我才有理由怀疑它。
Google的《 Web基础知识/性能》子章节中的粗体字声明似乎支持了这一点:
...浏览器会延迟脚本执行和DOM构建,直到完成CSSOM的下载和构建为止。
但是,在我提供的这个答案下,与另一位SO用户就该主题进行了友好的交谈,这一说法受到了严峻的挑战,他在其中提出了以下论据以证明是相反的:
<head>
<script>document.write("<!--");</script>
<style> body { background-color: red; } </style>
-->
</head>
Run Code Online (Sandbox Code Playgroud)
好的,让我们确定一下。让我们更换<style>
同
<link rel="stylesheet" type="text/css" href="test.php" />
Run Code Online (Sandbox Code Playgroud)
...并test.php
挂几秒钟:
<link rel="stylesheet" type="text/css" href="test.php" />
Run Code Online (Sandbox Code Playgroud)
如果我是对的(并且js
执行推迟到CSSOM构建完成),那么在构建CSSOM之前和执行之前,该页面将悬空10秒钟,<script>
这将注释掉<link />
并允许页面呈现。
如果他是正确的,则在满足条件时运行js,并且<link />
请求永远不会离开,因为到目前为止这是一个注释。
惊喜:
<link />
请求离开,浏览器标签会显示加载图标10秒钟。我也是对的!还是我 我很困惑,那就是我...任何人都可以对此有所了解吗?到底是怎么回事?
这和document.write
吗?
它与加载.php
文件而不是文件有关.css
吗?
如果有什么不同,我在Ubuntu的Chrome中进行了测试。
我恳请链接可靠的(重新)资源或提供雄辩的示例/测试来备份您可能考虑提供的所有答案。
cssom ×10
css ×9
javascript ×8
dom ×4
html ×4
browser ×2
colors ×1
performance ×1
properties ×1