我有一个自定义幻灯片页面,其中包含数百张标记中的大图片。另外,还有一个布局的调整,光靠CSS是无法完成的,需要javascript。该调整取决于计算出的几个页面元素的 CSS 样式。
问题是:在 (document).ready
上获取计算的 CSS 样式似乎不起作用。这是完全有道理的,因为当 DOM 仅仅注册时,布局/绘制还没有发生。
(window).load
是这里显而易见的答案。但在这种情况下,(window).load
的等待时间长得令人发狂,因为下载所有 100 多个大图像实际上需要 30 秒(在慢速连接上更长!)。原则上这对于幻灯片来说没问题,因为一旦加载了前两个图像,幻灯片就开始可用,早在所有图像加载之前。问题是,我希望此时也能进行脚本化 CSS 布局修正。
要检查是否加载了 imgs,我使用 imageLoaded ,这很棒,并且解决了与 imgs 一起使用时 jquery 的 load
事件的问题。但是,如何检查页面元素(例如 div)上类似“加载”的事件(以及计算样式的可用性)? (我意识到 div 不会触发加载事件。)原则上,在 (document).ready
和 (window).load
之间是否存在可靠的跨浏览器 DOM 事件> 我可以监听一组特定的元素,以获得计算的样式?或者我被迫在这两个极端时间之间做出选择?
最佳答案
CSS 加载
向您要检查的 CSS 文件添加独特的引用样式,如下所示:
#ensure-cssload-0 {
display: none;
}
然后,使用 JS 函数 cssLoad()
反复检查 CSS 是否已下载(不确定这与 CSS 实际绘制/渲染时是否有显着差异):
var onCssLoad = function (options, callback) {
var body = $("body");
var div = document.createElement(constants.TAG_DIV);
for (var key in options) {
if (options.hasOwnProperty(key)) {
if (key.toLowerCase() === "css") {
continue;
}
div[key] = options[key];
}
}
var css = options.css;
if (css) {
body.appendChild(div);
var handle = -1;
handle = window.setInterval(function () {
var match = true;
for (var key in css) {
if (css.hasOwnProperty(key)) {
match = match && utils.getStyle(div, key) === css[key];
}
}
if (match === true) {
window.clearTimeout(handle);
body.removeChild(div);
callback();
}
}, 100);
}
}
您可以将其用作:
onCssLoad({
"id": <insert element CSS applies to>,
css: <insert sample CSS styles>
}, function () {
console.log("CSS loaded, you can show the slideshow now :)");
});
关于 CSS 计算
Source: http://atomicrobotdesign.com/blog/javascript/get-the-style-property-of-an-element-using-javascript/
之前的解决方案仅告诉 CSS 文件是否已“下载”,而在您的问题中,您提到您需要知道元素的样式何时“计算” 或“渲染” 或“绘制”。我希望这可以解决这个问题。
向您要检查的 CSS 文件添加独特的引用样式,如下所示:
#ensure-cssload-0 {
ignored-property: 'computed';
}
现在,使用 getPropertyValue
和 getCompulatedStyle
检查 CSS:
function getStyle(elem, prop) {
return window.getComputedStyle(elem, null).getPropertyValue(prop);
}
现在,只需使用带有回调的 while
循环即可:
function checkStyle(elem, prop, callback) {
while ( getStyle(elem, prop) !== 'computed' ) {
// see explanation below
}
callback()
}
自 JavaScript doesn't have a pass
statement ( like in Python ),我们使用一个空代码块。
如果您想检索应用于元素的所有 CSS 样式(警告:这也会显示继承的样式),请查看 this SO answer .
避免 while() 循环
通常不建议使用 while 循环来检查任何内容,因为它挂起浏览器不会让 JavaScript 线程执行任何其他操作(现在所有浏览器都是多线程的,请参阅 this comic )。
这是Chuck suggested ,这个解决方案要好得多:
function checkStyle(elem, prop, callback) {
if ( getStyle(elem, prop) !== 'computed' ) {
// see explanation below
window.setTimeout( function() {checkStyle(elem, prop, callback);}, 100 )
} else {
callback()
}
}
这好多了。现在该函数每 100 毫秒异步检查一次(如果需要,您可以更改此值)。在设置超时时对函数进行包装是必要的,因为 setTimeout()
还不允许传递任何参数。
希望这有帮助。请参阅本文的源代码以获取更多链接...
关于javascript - 如何在window.load之前获取计算出的CSS样式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12607894/