document.documentElement.scrollTop || document.body.scrollTop || window.pageXOffset

本文详细解释了在网页开发中如何正确获取页面滚动条的位置。针对不同的浏览器环境,介绍了使用document.documentElement.scrollTop、document.body.scrollTop以及window.pageYOffset的方法,并讨论了它们之间的区别及兼容性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

document.documentElement.scrollTop/document.body.scrollTop

document.documentElement对应的是获取html,所以他获取的位置是正确的,document.body.scrollTop是对应的body,在标准w3c下,document.body.scrollTop恒为0,所以此时应该用document.documentElement.scrollTop。

window.pageYOffset
获取垂直方向上,滚动条距离顶部的偏移量,查阅资料,此时兼容性最好,我的谷歌浏览器的版本是版本 68.0.3440.106(正式版本) (64 位),document.body.scrollTop的值一直是0,其他都能获取到正确的值

### Vue3 中 `ableRef.value.getBoundingClientRect is not a function` 错误解决方案 在 Vue3 中,如果遇到 `ableRef.value.getBoundingClientRect is not a function` 的错误提示,通常是因为所引用的目标对象未正确初始化或者其值为空。以下是具体原因分析以及解决办法: #### 原因分析 1. **DOM 元素尚未挂载** 当尝试访问 `getBoundingClientRect()` 方法时,组件可能还未完全渲染完毕,此时 `ableRef.value` 返回的是 `null` 或者未指向实际的 DOM 对象[^1]。 2. **引用的对象并非标准 DOM 元素** 如果 `ref` 绑定到了非原生 HTML 元素(例如某些第三方库封装的组件),那么它不会具备 `getBoundingClientRect()` 这一方法[^2]。 3. **跨框架冲突或不兼容情况** 特殊场景下,比如使用 Element Plus 等 UI 框架时,内部逻辑可能导致无法直接获取底层 DOM 结构[^3]。 --- #### 解决方案 ##### 方案一:确保 DOM 已加载完成后再执行操作 利用生命周期钩子函数,在确认虚拟 DOM 渲染完成后才去读取真实 DOM 节点的相关属性。 ```javascript import { onMounted, ref } from 'vue'; export default { setup() { const ableRef = ref(null); onMounted(() => { if (ableRef.value && typeof ableRef.value.getBoundingClientRect === 'function') { const rectInfo = ableRef.value.getBoundingClientRect(); console.log(rectInfo); } else { console.error('The reference does not point to a valid DOM element.'); } }); return { ableRef }; }, }; ``` 此处通过 `onMounted` 钩子保证只有当组件被插入到父级容器之后才会尝试调用 `getBoundingClientRect()` 函数[^4]。 --- ##### 方案二:判断并处理特殊类型的组件实例 如果是基于某个特定库构建出来的复杂控件而非简单标签,则需要先检查它的结构特性再决定下一步动作。 以 Element Plus 的 `<el-cascader>` 控制为例,假设我们想测量其中某一部分的实际尺寸: ```html <template> <el-cascader v-model="selectedValue" ref="cascaderPanel"></el-cascader> </template> <script> import { ref, nextTick } from 'vue'; import { ElCascaderPanel } from 'element-plus'; export default { components: { ElCascaderPanel }, setup() { const cascaderPanel = ref(null); const measureSize = async () => { await nextTick(); // Wait until the component has been rendered. let targetDom; if ('$el' in cascaderPanel.value) { targetDom = cascaderPanel.value.$el; // Access internal root node of custom component. } if (targetDom?.getBoundingClientRect instanceof Function) { const sizeData = targetDom.getBoundingClientRect(); console.info(sizeData); } else { throw new Error(`Unable to locate proper DOM structure within ${cascaderPanel}.`); } }; return { selectedValue: '', cascaderPanel, measureSize }; }, }; </script> ``` 这里展示了如何针对像 Element Plus 提供的选择框这类高级别抽象构件提取它们隐藏起来的真实 DOM 层次关系,并安全地应用几何查询命令[^5]。 --- ##### 方案三:提供回退机制应对低版本浏览器限制 考虑到极少数老旧平台可能缺乏对最新 Web API 的全面支持,可以引入 polyfill 来弥补差距。 下面给出一个简单的例子展示怎样创建自己的备用实现方式来模拟缺少的功能效果: ```javascript if (!Element.prototype.getBoundingClientRect) { Object.defineProperty(Element.prototype, 'getBoundingClientRect', { value: function getCustomRect() { const docElm = document.documentElement, body = document.body || {}, clientLeft = this.clientLeft || 0, clientTop = this.clientTop || 0, scrollX = window.pageXOffset || docElm.scrollLeft || body.scrollLeft || 0, scrollY = window.pageYOffset || docElm.scrollTop || body.scrollTop || 0; return { width: Math.max(this.offsetWidth - clientLeft * 2 , 0), height:Math.max( this.offsetHeight-clientTop*2 ,0 ), left:this.offsetLeft+scrollX-clientLeft , top :this.offsetTop +scrollY -clientTop }; } }); } ``` 这段脚本定义了一个新的全局扩展方法作为原始接口不可用时候的一种替代品[^6]。 --- ### 总结 综上所述,要成功规避掉类似于 `'is not a function'` 类型异常的发生,关键是做到以下几点: - 正确设置好时间序列顺序使得所有必要的前置条件都已满足; - 明晰区分不同种类目标实体之间的差异以便采取恰当策略加以处置; - 在必要场合准备好应急预案用来适配那些极端状况下的需求变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值