/** * 为所有 table.table-bordered 添加可滚动父元素(仅在移动设备上) * 在页面加载时自动执行 */ (function() { 'use strict'; /** * 检测是否为移动设备 */ function isMobileDevice() { // 方法1:检查 User Agent const userAgent = navigator.userAgent || navigator.vendor || window.opera; const mobileRegex = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i; // 方法2:检查触摸支持 const hasTouchScreen = (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)); // 方法3:检查屏幕宽度 const isSmallScreen = window.innerWidth <= 991; // 综合判断:User Agent 匹配 或 (有触摸支持 且 屏幕较小) return mobileRegex.test(userAgent) || (hasTouchScreen && isSmallScreen); } function wrapTablesWithScroll() { const isMobile = isMobileDevice(); // 查找所有 class 包含 "table table-bordered" 的表格 const tables = document.querySelectorAll('table.table.table-bordered'); let wrappedCount = 0; tables.forEach(function(table) { // 检查是否已经被包裹 const parent = table.parentElement; // 如果父元素已经有 overflow-x 样式或 table-responsive 类,跳过 if (parent && ( parent.style.overflowX === 'auto' || parent.classList.contains('table-responsive') || window.getComputedStyle(parent).overflowX === 'auto' )) { return; } // 判断是否需要包裹 let needWrap = false; if (isMobile) { // 移动设备:始终包裹 needWrap = true; } else { // 桌面设备:检查表格实际宽度 const tableWidth = table.scrollWidth || table.offsetWidth; const parentWidth = parent ? (parent.clientWidth || parent.offsetWidth) : window.innerWidth; // 调试信息 console.log(`表格检测 - scrollWidth: ${table.scrollWidth}, offsetWidth: ${table.offsetWidth}, parentWidth: ${parentWidth}`); // 如果表格宽度超过 1000px 或超过父容器宽度,则需要包裹 if (tableWidth > 1000 || tableWidth > parentWidth) { needWrap = true; console.log(`需要包裹:tableWidth=${tableWidth}, 阈值=1000`); } } if (!needWrap) { return; } // 创建包裹元素 const wrapper = document.createElement('div'); wrapper.style.overflowX = 'auto'; wrapper.style.webkitOverflowScrolling = 'touch'; // iOS 平滑滚动 // 在表格前插入包裹元素 table.parentNode.insertBefore(wrapper, table); // 将表格移入包裹元素 wrapper.appendChild(table); wrappedCount++; }); if (wrappedCount > 0) { const deviceType = isMobile ? '移动设备' : '桌面设备(宽表格)'; console.log(`✓ ${deviceType}:已为 ${wrappedCount} 个表格添加横向滚动功能`); } else if (!isMobile) { console.log('✓ 桌面设备:所有表格宽度正常,无需添加滚动'); } return wrappedCount; } // 执行函数(多次尝试,确保表格完全渲染) function executeWrap() { // 立即执行一次 wrapTablesWithScroll(); // 延迟执行,等待表格完全渲染 setTimeout(wrapTablesWithScroll, 100); setTimeout(wrapTablesWithScroll, 500); setTimeout(wrapTablesWithScroll, 1000); } // 页面加载完成后执行 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', executeWrap); } else { // DOM 已经加载完成,直接执行 executeWrap(); } // 监听窗口大小变化 let resizeTimer; window.addEventListener('resize', function() { clearTimeout(resizeTimer); resizeTimer = setTimeout(wrapTablesWithScroll, 250); }); // 监听动态添加的内容(使用 MutationObserver) const observer = new MutationObserver(function(mutations) { let shouldWrap = false; mutations.forEach(function(mutation) { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { // 元素节点 // 检查新添加的节点是否是 table 或包含 table if (node.matches && node.matches('table.table.table-bordered')) { shouldWrap = true; } else if (node.querySelectorAll) { const tables = node.querySelectorAll('table.table.table-bordered'); if (tables.length > 0) { shouldWrap = true; } } } }); }); if (shouldWrap) { setTimeout(wrapTablesWithScroll, 100); } }); // 开始观察 observer.observe(document.body, { childList: true, subtree: true }); })();