$(document).height();文档高度

本文介绍了使用jQuery获取网页中元素的各种高度、位置和滚动条信息的方法,包括文档总高度、窗口高度、元素距离顶部的距离及滚动条的高度,是前端开发者进行页面布局和交互设计时的实用指南。

$(document).height();//文档高度

$(window).height();//是文档窗口高度

$("div").offset().top//是标签距离顶部高度

$(window).scrollTop();//是滚动条高度 和$(document).scrollTop()效果一样 但是$(window).scrollTop() 兼容性好

$(".footer").height();//是标签高度

 

`textarea.scrollHeight` 是 `0` 的问题非常典型,尤其是在 **Vue 2 + Element UI** 中动态设置内容后尝试手动调整高度时。 我们来深入分析:为什么 `scrollHeight` 会是 `0`?以及如何彻底解决。 --- ## 🔍 为什么会 `scrollHeight === 0`? ### ✅ 根本原因总结: > ❌ **`<textarea>` 元素不可见(display: none)或尚未渲染到 DOM 中 → 导致无法计算真实滚动高度** 浏览器只有在元素 **“处于文档流中且可见”** 的情况下才能正确计算 `scrollHeight`。否则返回 `0` 或错误值。 --- ## 🧨 常见导致 `scrollHeight = 0` 的场景 | 场景 | 说明 | |------|------| | 1. 组件被 `v-if="false"` 包裹 | 元素未插入 DOM,`$el` 为 `null` | | 2. 在 `el-dialog` 中,对话框还未完全打开 | `display: none`,元素不可见 | | 3. 使用了 `v-show="false"` | 虽然 DOM 存在,但 `display: none`,无法测量 | | 4. 异步数据更新太快,DOM 还没挂载 | 即使用了 `this.$nextTick()`,也可能不够 | --- ## ✅ 正确解决方案 ### ✅ 方案一:确保元素已“可见”后再读取 `scrollHeight` #### 示例:在 `el-dialog` 中的 textarea ```html <el-dialog :visible.sync="dialogVisible" @opened="onDialogOpened"> <el-input ref="textareaRef" v-model="form.description" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" /> </el-dialog> ``` ```js data() { return { dialogVisible: false, form: { description: '' } }; }, methods: { openDialog() { this.form.description = '这是一段很长的内容...\n换行测试'; this.dialogVisible = true; // ❌ 不要在这里调 resize —— dialog 还没显示! }, onDialogOpened() { // ✅ 此时 dialog 已经 visible,DOM 可见 this.$nextTick(() => { this.adjustTextareaHeight(); }); }, adjustTextareaHeight() { const textarea = this.$refs.textareaRef?.$el?.querySelector('textarea'); if (!textarea) { console.warn('找不到 textarea 元素'); return; } // 强制重置并重新计算高度 textarea.style.height = 'auto'; const height = textarea.scrollHeight; // 现在应该不是 0 了! if (height > 0) { textarea.style.height = height + 'px'; console.log('✅ 成功设置高度:', height); } else { console.error('❌ scrollHeight 仍为 0,请检查是否可见'); } } } ``` --- ### ✅ 方案二:使用 `offsetHeight` / `clientHeight` 替代判断是否可见 你可以加一个判断: ```js const el = this.$refs.textareaRef?.$el; if (!el || el.offsetWidth === 0 || el.offsetHeight === 0) { console.warn('元素不可见,跳过高度计算'); return; } // 否则可以安全测量 const textarea = el.querySelector('textarea'); textarea.style.height = 'auto'; textarea.style.height = textarea.scrollHeight + 'px'; ``` 👉 `offsetWidth/offsetHeight === 0` 表示元素不可见。 --- ### ✅ 方案三:延迟执行(兜底) 如果上述方法都不行(比如动画过渡中),可以用 `setTimeout` 微延迟: ```js this.$nextTick(() => { setTimeout(() => { const textarea = this.$refs.textareaRef?.$el?.querySelector('textarea'); if (textarea && textarea.scrollHeight > 0) { textarea.style.height = 'auto'; textarea.style.height = textarea.scrollHeight + 'px'; } else { console.warn('scrollHeight 仍然为 0,可能需要更长等待'); } }, 50); // 小小延迟,确保 display 已变为 block }); ``` > ⚠️ 注意:不要滥用 `setTimeout`,优先用事件驱动如 `@opened`。 --- ### ✅ 方案四:触发一次强制重绘(Force Reflow) 有时候浏览器优化了渲染流程,即使元素可见也不立即布局。可以通过强制 reflow 解决: ```js adjustTextareaHeight() { const textarea = this.$refs.textareaRef?.$el?.querySelector('textarea'); if (!textarea) return; // 🔥 强制浏览器重新计算布局 const dummy = document.body.offsetHeight; // 读取任意 layout 属性即可触发 reflow textarea.style.height = 'auto'; const sh = textarea.scrollHeight; if (sh > 0) { textarea.style.height = sh + 'px'; } else { console.error('scrollHeight 依然为 0,建议检查 DOM 可见性'); } } ``` 这个技巧利用了“读取 offsetXXX 属性会强制同步布局”的机制。 --- ## ✅ 验证 `scrollHeight` 是否可用的小工具函数 ```js function getVisibleScrollHeight(textarea) { if (!textarea) return 0; const style = window.getComputedStyle(textarea); const parentStyle = window.getComputedStyle(textarea.parentNode); // 检查是否隐藏 if ( style.display === 'none' || parentStyle.display === 'none' || style.visibility === 'hidden' || parseInt(style.width) === 0 || parseInt(style.height) === 0 ) { return -1; // 表示不可见 } return textarea.scrollHeight; } ``` 使用方式: ```js this.$nextTick(() => { const ta = this.$refs.textareaRef?.$el?.querySelector('textarea'); const h = getVisibleScrollHeight(ta); if (h > 0) { ta.style.height = h + 'px'; } else if (h === -1) { console.warn('textarea 当前不可见,无法测量高度'); } }); ``` --- ## ✅ 最佳实践建议 | 场景 | 推荐做法 | |------|---------| | `el-dialog` 内部 | 使用 `@opened` 事件触发 resize | | `v-show` 控制 | 确保 `v-show="true"` 后再调用 | | 动态加载数据 | `this.$nextTick(() => { ... })` + 判断可见性 | | 多层嵌套组件 | 手动暴露 `resize` 方法或使用 `$attrs/$listeners` | --- ## ✅ 总结 | 问题 | 原因 | 解决方案 | |------|------|-----------| | `scrollHeight === 0` | 元素未渲染或不可见 | 等待 `@opened`、`v-if` 生效 | | `$refs.textareaRef` 存在但 `scrollHeight=0` | 浏览器未重排 | 用 `offsetHeight` 触发 reflow | | 动态赋值后不撑开 | `autosize` 未检测到变化 | 手动调 `resizeTextarea()` 或原生撑高 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值