| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- /**
- * 为所有 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
- });
- })();
|