You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iPhone端DataTables列切换按钮点击后样式不切换的问题修复

解决iPhone上DataTables列切换按钮样式不更新的问题

我用DataTables结合Bootstrap实现了表格列的显示/隐藏切换功能,通过按钮控制列可见性:列显示时按钮应用btn-secondary样式,隐藏时应用btn-outline-secondary样式。该功能在桌面端运行正常,但在iPhone设备上测试时,点击按钮隐藏列后,列已成功隐藏,但按钮样式无法切换回btn-outline-secondary。

原始代码示例

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
<span>Show / Hide:  </span>
<button type="button" class='toggle-vis btn btn-outline-secondary' data-column='0'>ID</button>
<button type="button" class='toggle-vis btn btn-outline-secondary' data-column='1'>Date</button>
<button type="button" class='toggle-vis btn btn-outline-secondary' data-column='2'>Time</button>
<button type="button" class='toggle-vis btn btn-outline-secondary' data-column='3'>Item</button>
<button type="button" class='toggle-vis btn btn-outline-secondary' data-column='4'>Quantity</button>


<table class='table table-bordered' id='dataTable' width='100%' cellspacing='0'>
    <thead>
        <tr>
            <th>ID</th>
            <th>Date</th>
            <th>Time</th>
            <th>Item</th>
            <th>Quantity</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>1/10</td>
            <td>12:00</td>
            <td>Apple</td>
            <td>3</td>
        </tr>
        <tr>
            <td>2</td>
            <td>4/10</td>
            <td>14:00</td>
            <td>Apple</td>
            <td>1</td>
        </tr>
        <tr>
            <td>3</td>
            <td>4/10</td>
            <td>14:00</td>
            <td>Orange</td>
            <td>3</td>
        </tr>
</table>

<script src='https://code.jquery.com/jquery-3.7.0.js' type='text/javascript'></script>
<script src='https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js' type='text/javascript'></script>

<script>
$(document).ready(function() {
    // Initialize DataTable
    const table = $('#dataTable').DataTable({
        "columnDefs": [
            // Hide columns based on unique column indices
            { "visible": false, "targets": 2 }
        ]
    });

    // Handle button click events
    document.querySelectorAll('button.toggle-vis').forEach((el) => {
        el.addEventListener('click', function(e) {
            e.preventDefault();
            let columnIdx = e.target.getAttribute('data-column');
            let column = table.column(columnIdx);

            // Toggle the visibility
            column.visible(!column.visible());

            if (column.visible()) {
                e.target.classList.replace('btn-outline-secondary', 'btn-secondary');
            } else {
                e.target.classList.replace('btn-secondary', 'btn-outline-secondary');
            }
        });
    });

    // Initialize button classes based on initial column visibility
    table.columns().every(function() {
        var column = this;
        var columnIdx = column.index();

        if (column.visible()) {
            var button = document.querySelector("button.toggle-vis[data-column='" + columnIdx + "']");
            button.classList.replace('btn-outline-secondary', 'btn-secondary');
        }
        if (!column.visible()) {
            var button = document.querySelector("button.toggle-vis[data-column='" + columnIdx + "']");
            button.classList.replace('btn-secondary', 'btn-outline-secondary');
        }
    });
});
</script>

问题根源

iPhone的Safari浏览器在处理点击事件时,e.target可能指向按钮内部的文本节点而非按钮元素本身,导致后续的class操作无法作用到正确的DOM元素。此外,classList.replace()方法在目标类不存在时不会执行任何操作,也可能导致样式切换失效。

修复方案

  1. 使用this替代e.target:在事件监听器中,this始终指向触发事件的按钮元素,避免因事件冒泡导致的目标元素错误。
  2. 替换class操作逻辑:先移除不需要的类,再添加目标类,确保样式切换的可靠性,避免依赖replace()的局限性。

修改后的JavaScript代码

$(document).ready(function() {
    // Initialize DataTable
    const table = $('#dataTable').DataTable({
        "columnDefs": [
            // Hide columns based on unique column indices
            { "visible": false, "targets": 2 }
        ]
    });

    // Handle button click events
    document.querySelectorAll('button.toggle-vis').forEach((el) => {
        el.addEventListener('click', function(e) {
            e.preventDefault();
            // 使用this获取当前按钮元素,避免e.target指向子节点
            const button = this;
            let columnIdx = button.getAttribute('data-column');
            let column = table.column(columnIdx);

            // Toggle the visibility
            column.visible(!column.visible());

            // 先移除旧类再添加新类,确保样式切换生效
            if (column.visible()) {
                button.classList.remove('btn-outline-secondary');
                button.classList.add('btn-secondary');
            } else {
                button.classList.remove('btn-secondary');
                button.classList.add('btn-outline-secondary');
            }
        });
    });

    // Initialize button classes based on initial column visibility
    table.columns().every(function() {
        var column = this;
        var columnIdx = column.index();
        var button = document.querySelector("button.toggle-vis[data-column='" + columnIdx + "']");
        
        if (column.visible()) {
            button.classList.remove('btn-outline-secondary');
            button.classList.add('btn-secondary');
        } else {
            button.classList.remove('btn-secondary');
            button.classList.add('btn-outline-secondary');
        }
    });
});

可选优化:使用jQuery简化代码

如果项目已引入jQuery,可使用jQuery的事件绑定和class操作提升兼容性与可读性:

$(document).ready(function() {
    const table = $('#dataTable').DataTable({
        "columnDefs": [
            { "visible": false, "targets": 2 }
        ]
    });

    // jQuery绑定点击事件,自动处理目标元素问题
    $('.toggle-vis').on('click', function(e) {
        e.preventDefault();
        const $button = $(this);
        const columnIdx = $button.data('column');
        const column = table.column(columnIdx);

        column.visible(!column.visible());

        // 链式调用切换class
        if (column.visible()) {
            $button.removeClass('btn-outline-secondary').addClass('btn-secondary');
        } else {
            $button.removeClass('btn-secondary').addClass('btn-outline-secondary');
        }
    });

    // 初始化按钮样式
    table.columns().every(function() {
        const column = this;
        const $button = $(`.toggle-vis[data-column="${column.index()}"]`);
        if (column.visible()) {
            $button.removeClass('btn-outline-secondary').addClass('btn-secondary');
        } else {
            $button.removeClass('btn-secondary').addClass('btn-outline-secondary');
        }
    });
});

内容的提问来源于stack exchange,提问作者jayden__2002

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:44:56