为什么window.onresize函数内设置CSS top属性的代码不生效?
问题原因分析
- DOM重排时序滞后
resize事件触发时浏览器尚未完成窗口变动后的全页DOM重排计算,此时调用$('#section4').offset().top拿到的是重排前的旧坐标值,你基于旧值设置top后,浏览器后续完成重排时要么会覆盖你设置的行内样式,要么设置的本身就是不符合新布局的旧值,看起来就像代码未生效。等你手动在控制台执行时,页面重排已经完全结束,拿到的是正确的最新坐标,所以设置可以生效。 - 同事件回调执行顺序冲突
如果页面内还有其他绑定在resize事件上的回调逻辑,且这些逻辑执行顺序晚于你的当前回调,同时会修改.overlay-wrap4的top属性、或者修改#section4的布局,就会把你当前回调设置的top值覆盖。手动执行时所有resize关联的回调都已经执行完毕,不存在后续逻辑覆盖的问题。 - 元素定位属性临时异常
如果有其他逻辑在resize过程中临时将.overlay-wrap4的position属性设置为static,此时设置top属性是完全无效的(static定位元素不支持top/right等偏移属性)。等resize流程结束后,对应逻辑又把position改回了absolute/relative/fixed,这时候你手动执行设置top自然生效。
解决方案
- 把设置样式的逻辑用
requestAnimationFrame包裹,延迟到浏览器重排完成后执行,修改后的代码参考:
window.onresize = function() { console.log("well called") // 等待重排完成后再执行样式设置 requestAnimationFrame(() => { $('.overlay-wrap4').css('top', $('#section4').offset().top + "px"); $('.overlay-wrap4').css('height', $('#section4').height() + "px"); }) }
- 如果怀疑是其他逻辑覆盖样式,可以在设置top的代码后加一行
console.log($('.overlay-wrap4').css('top')),确认刚设置后的值是否符合预期,如果刚设置完正确后续变动,说明有其他逻辑修改了元素属性,可以用Chrome开发者工具的DOM断点监控.overlay-wrap4的属性变化,定位修改位置。 - 强制保证
.overlay-wrap4的定位属性有效,可添加CSS规则:.overlay-wrap4 { position: absolute !important; }(根据实际业务调整定位类型)
内容的提问来源于stack exchange,提问作者jpohnlmary
相关产品推荐
相关产品推荐

