js获取html元素并设置高度为100vh-键盘高度

获取HTML元素并设置高度为(100vh - 键盘高度)

我将设计一个页面,展示如何获取HTML元素并动态设置其高度为视口高度减去键盘高度,这在移动设备上特别有用,可以避免键盘遮挡内容。

设计思路

  • 创建一个带有输入框的界面,模拟键盘弹出场景
  • 使用JavaScript检测窗口大小变化并动态计算合适的高度
  • 提供可视化反馈,显示当前计算的高度值
  • 设计响应式布局,确保在各种设备上都能正常工作

下面是完整的实现代码:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>动态高度调整示例</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
            color: #333;
            min-height: 100vh;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        
        .container {
            width: 90%;
            max-width: 800px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            padding: 25px;
            margin: 20px 0;
            display: flex;
            flex-direction: column;
            gap: 20px;
        }
        
        header {
            text-align: center;
            margin-bottom: 10px;
        }
        
        h1 {
            color: #2c3e50;
            font-size: 2.2rem;
            margin-bottom: 10px;
        }
        
        .description {
            color: #7f8c8d;
            font-size: 1.1rem;
            line-height: 1.6;
        }
        
        .content-box {
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            overflow: hidden;
            transition: height 0.3s ease;
            background: white;
        }
        
        .content-header {
            background: #3498db;
            color: white;
            padding: 15px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .content-body {
            padding: 20px;
            overflow-y: auto;
        }
        
        .height-info {
            display: flex;
            justify-content: space-between;
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
            margin-top: 10px;
        }
        
        .info-item {
            text-align: center;
            flex: 1;
        }
        
        .info-value {
            font-size: 1.8rem;
            font-weight: bold;
            color: #3498db;
        }
        
        .info-label {
            color: #7f8c8d;
            font-size: 0.9rem;
        }
        
        .input-group {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin: 20px 0;
        }
        
        .input-group label {
            font-weight: 600;
            color: #2c3e50;
        }
        
        .input-group input, .input-group textarea {
            padding: 15px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            transition: border-color 0.3s;
        }
        
        .input-group input:focus, .input-group textarea:focus {
            border-color: #3498db;
            outline: none;
        }
        
        .visual-keyboard {
            background: #e0e0e0;
            border-radius: 8px;
            padding: 15px;
            text-align: center;
            margin-top: 20px;
            display: none;
        }
        
        .keyboard-toggle {
            padding: 12px 20px;
            background: #e74c3c;
            color: white;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 600;
            transition: background 0.3s;
            margin-top: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }
        
        .keyboard-toggle:hover {
            background: #c0392b;
        }
        
        .instructions {
            background: #fff8e1;
            border-left: 4px solid #ffc107;
            padding: 15px;
            border-radius: 4px;
            margin-top: 20px;
        }
        
        .instructions h3 {
            color: #d35400;
            margin-bottom: 10px;
        }
        
        .instructions ul {
            padding-left: 20px;
        }
        
        .instructions li {
            margin-bottom: 8px;
            line-height: 1.5;
        }
        
        @media (max-width: 768px) {
            .container {
                width: 95%;
                padding: 15px;
            }
            
            h1 {
                font-size: 1.8rem;
            }
            
            .height-info {
                flex-direction: column;
                gap: 15px;
            }
            
            .visual-keyboard {
                display: block;
            }
        }
        
        @media (max-width: 480px) {
            h1 {
                font-size: 1.5rem;
            }
            
            .description {
                font-size: 1rem;
            }
            
            .info-value {
                font-size: 1.5rem;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>动态高度调整示例</h1>
            <p class="description">此页面演示如何获取HTML元素并设置其高度为(100vh - 键盘高度),适用于移动设备避免键盘遮挡内容。</p>
        </header>
        
        <div class="content-box" id="adjustableElement">
            <div class="content-header">
                <span>可调整高度的元素</span>
                <span id="currentHeight">高度: 400px</span>
            </div>
            <div class="content-body">
                <div class="input-group">
                    <label for="sampleInput">示例输入框(点击测试键盘弹出)</label>
                    <input type="text" id="sampleInput" placeholder="点击此处测试...">
                </div>
                
                <div class="input-group">
                    <label for="sampleTextarea">示例文本区域</label>
                    <textarea id="sampleTextarea" rows="4" placeholder="点击此处测试..."></textarea>
                </div>
                
                <button class="keyboard-toggle" id="keyboardToggle">
                    <i class="fas fa-keyboard"></i> 显示/隐藏虚拟键盘
                </button>
                
                <div class="visual-keyboard" id="visualKeyboard">
                    <p>虚拟键盘区域(模拟移动设备键盘)</p>
                    <div style="height: 200px; display: flex; justify-content: center; align-items: center; background: #c0c0c0; border-radius: 5px;">
                        <i class="fas fa-keyboard" style="font-size: 48px; color: #666;"></i>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="height-info">
            <div class="info-item">
                <div class="info-value" id="viewportHeight">0px</div>
                <div class="info-label">视口高度</div>
            </div>
            <div class="info-item">
                <div class="info-value" id="keyboardHeight">0px</div>
                <div class="info-label">键盘高度</div>
            </div>
            <div class="info-item">
                <div class="info-value" id="calculatedHeight">0px</div>
                <div class="info-label">计算高度</div>
            </div>
        </div>
        
        <div class="instructions">
            <h3>使用说明</h3>
            <ul>
                <li>在移动设备上,当键盘弹出时,页面高度会发生变化</li>
                <li>JavaScript会检测窗口大小变化并计算合适的高度</li>
                <li>元素高度会自动调整为: (视口高度 - 键盘高度)</li>
                <li>在桌面浏览器中,可以点击"显示/隐藏虚拟键盘"进行测试</li>
            </ul>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const adjustableElement = document.getElementById('adjustableElement');
            const currentHeightSpan = document.getElementById('currentHeight');
            const viewportHeightSpan = document.getElementById('viewportHeight');
            const keyboardHeightSpan = document.getElementById('keyboardHeight');
            const calculatedHeightSpan = document.getElementById('calculatedHeight');
            const keyboardToggle = document.getElementById('keyboardToggle');
            const visualKeyboard = document.getElementById('visualKeyboard');
            
            let keyboardVisible = false;
            let originalViewportHeight = window.innerHeight;
            
            // 初始更新
            updateHeights();
            
            // 监听窗口大小变化
            window.addEventListener('resize', function() {
                updateHeights();
            });
            
            // 键盘切换按钮
            keyboardToggle.addEventListener('click', function() {
                keyboardVisible = !keyboardVisible;
                
                if (keyboardVisible) {
                    visualKeyboard.style.display = 'block';
                    // 模拟键盘弹出,视口高度减少
                    window.dispatchEvent(new Event('resize'));
                } else {
                    visualKeyboard.style.display = 'none';
                    // 模拟键盘收起,恢复视口高度
                    window.dispatchEvent(new Event('resize'));
                }
            });
            
            // 更新高度函数
            function updateHeights() {
                const viewportHeight = window.innerHeight;
                const visualKeyboardHeight = keyboardVisible ? 200 : 0;
                
                // 在移动设备上,键盘弹出时会改变视口高度
                // 这里我们通过比较当前视口高度和原始视口高度来计算键盘高度
                const keyboardHeight = Math.max(0, originalViewportHeight - viewportHeight);
                
                // 计算合适的高度
                const calculatedHeight = viewportHeight - Math.max(keyboardHeight, visualKeyboardHeight);
                
                // 更新显示信息
                viewportHeightSpan.textContent = `${viewportHeight}px`;
                keyboardHeightSpan.textContent = `${keyboardHeight}px`;
                calculatedHeightSpan.textContent = `${calculatedHeight}px`;
                
                // 设置元素高度
                adjustableElement.style.height = `${calculatedHeight}px`;
                currentHeightSpan.textContent = `高度: ${calculatedHeight}px`;
            }
            
            // 初始化时保存原始视口高度
            setTimeout(() => {
                originalViewportHeight = window.innerHeight;
                updateHeights();
            }, 100);
            
            // 添加输入框聚焦时更新高度的逻辑(模拟移动设备行为)
            const inputs = document.querySelectorAll('input, textarea');
            inputs.forEach(input => {
                input.addEventListener('focus', function() {
                    // 在移动设备上,聚焦输入框时键盘弹出,这里我们模拟这个行为
                    if (window.innerWidth <= 768) { // 仅在移动设备上模拟
                        keyboardVisible = true;
                        visualKeyboard.style.display = 'block';
                        updateHeights();
                    }
                });
                
                input.addEventListener('blur', function() {
                    if (window.innerWidth <= 768) {
                        keyboardVisible = false;
                        visualKeyboard.style.display = 'none';
                        updateHeights();
                    }
                });
            });
        });
    </script>
</body>
</html>

功能说明

  1. 动态高度调整:页面中的内容区域会根据窗口大小自动调整高度
  2. 键盘高度模拟:提供了虚拟键盘显示/隐藏功能,模拟移动设备上键盘弹出场景
  3. 实时数据展示:显示当前视口高度、键盘高度和计算后的高度值
  4. 响应式设计:在移动设备和桌面设备上都能正常工作
  5. 使用说明:提供了详细的使用说明,帮助用户理解功能

技术实现

  • 使用JavaScript监听窗口resize事件
  • 通过比较窗口大小变化计算键盘高度
  • 动态设置元素高度为(视口高度 - 键盘高度)
  • 添加了移动设备检测和模拟功能

您可以直接将上述代码复制到HTML文件中,然后在浏览器中打开使用。在移动设备上测试效果更佳。

相关推荐
luquinn2 小时前
实现统一门户登录跳转免登录
开发语言·前端·javascript
烛阴2 小时前
TypeScript 类型魔法:像遍历对象一样改造你的类型
前端·javascript·typescript
前端无冕之王3 小时前
一份兼容多端的HTML邮件模板实践与详解
前端·css·数据库·html
wifi歪f7 小时前
🎉 Stenciljs,一个Web Components框架新体验
前端·javascript
知识分享小能手8 小时前
React学习教程,从入门到精通, React教程:构建你的第一个 React 应用(1)
前端·javascript·vue.js·学习·react.js·ajax·前端框架
wuzuyu3658 小时前
SyntaxError: Failed to execute ‘open‘ on ‘XMLHttpRequest‘: Invalid URL
ajax·html·api
tianchang9 小时前
JS 排序神器 sort 的正确打开方式
前端·javascript·算法
做你的猫10 小时前
深入剖析:基于Vue 3与Three.js的3D知识图谱实现与优化
前端·javascript·vue.js
做你的猫10 小时前
深入剖析:基于Vue 3的高性能AI聊天组件设计与实现
前端·javascript·vue.js