我正在使用Bootstrap 5.3.3和JS DataTables 2.0.5构建一个爱好网页.在页面上,我有一个包含一些球员数据的表格.在表格中,当单击某些单元格时,会显示一个带有额外信息的弹出窗口.当桌子以全宽显示时,所有所需的模块都已到位,弹出器工作正常.然而,如果我调整屏幕大小以使某些列折叠,则这些列的弹出窗口不会显示.

JS Fiddle中的重复示例:

<head>
  <meta charset="utf-8">
  <title>Responsive Table Popover</title>
  <meta name="description" content="">
  <meta name="author" content="">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
  <link href="https://cdn.datatables.net/2.0.5/css/dataTables.bootstrap5.min.css" rel="stylesheet">
  <link href="https://cdn.datatables.net/responsive/3.0.2/css/responsive.bootstrap5.min.css" rel="stylesheet">
</head>
<body>
  <div class="container">
    <table id="players-data" class="table table-striped" style="font-size:13px; width: 100%;">
        <thead style="white-space: nowrap;">
            <tr>
                <th>Player</th>
                <th>Details 1</th>
                <th>Details 2</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    </div>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"> </script>
    <script charset="utf8" src="https://cdn.datatables.net/2.0.5/js/dataTables.min.js"></script>
    <script charset="utf8" src="https://cdn.datatables.net/2.0.5/js/dataTables.bootstrap5.min.js"></script>
    <script charset="utf8" src="https://cdn.datatables.net/responsive/3.0.2/js/dataTables.responsive.min.js"></script>
    <script charset="utf8" src="https://cdn.datatables.net/responsive/3.0.2/js/responsive.bootstrap5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
    <script type="text/javascript">
      let players = [
        {player: 'Best', details_1: 'Cool', details_2: 'Sharp', details_1_extra: 'Extra Cool', details_2_extra: 'Extra Sharp'},
        {player: 'Worst', details_1: 'Hot', details_2: 'Slow', details_1_extra: 'Extra Hot', details_2_extra: 'Extra Slow'}
      ];

      $('#players-data').DataTable({
        data: players,
        columns: [
            {data: 'player', render: DataTable.render.text(), sortable: true},
            {data: 'details_1', sortable: false, class: "text-center", render: function (data, type, row) {
                if (data)
                {
                    return `<a 
                        tabindex="0" 
                        type="button" 
                        class="btn btn-link btn-sm" 
                        data-bs-container="body" 
                        data-bs-trigger="focus" 
                        data-bs-toggle="popover" 
                        data-bs-placement="bottom" 
                        data-bs-html="true" 
                        data-bs-custom-class="custom-popover"
                        data-bs-content="${row.details_1_extra}">
                        ${data}
                    </a>`;
                } else {
                    return data;
                }
            }},
            {data: 'details_2', sortable: false, class: "text-center", render: function (data, type, row) {
                if (data)
                {
                    return `<a 
                        tabindex="0" 
                        type="button" 
                        class="btn btn-link btn-sm" 
                        data-bs-container="body" 
                        data-bs-trigger="focus" 
                        data-bs-toggle="popover" 
                        data-bs-placement="bottom" 
                        data-bs-html="true" 
                        data-bs-custom-class="custom-popover" 
                        data-bs-content="${row.details_2_extra}">
                        ${data}
                    </a>`;
                } else {
                    return data;
                }
            }}
        ],
        destroy: true,
        searching: false, 
        paging: true, 
        info: false,
        ordering: true,
        stateSave: true,
        responsive: true,
        drawCallback: function (settings) {
            const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
            const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl));
        }
    });
    </script>
</body>

When table is full width (all columns are shown) popovers on both columns are working fine: enter image description here

当"详细信息2"列因屏幕尺寸而折叠时,无论您单击单元格文本,弹出窗口都不再显示在其中:

enter image description here

为了让波比无论如何都能发挥作用,我的代码中缺少了什么?

推荐答案

当调整datatable的大小并且在解折叠折叠的单元格时,datatable实际上添加了另一行,其中包含折叠的单元格,但在ul/li/span元素中,即它创建了新的多姆元素,该元素没有附加弹出框或任何其他监听器.

新添加元素示例:

<tr data-dt-row="1" class="child">
  <td class="child" colspan="1">
    <ul data-dtr-index="1" class="dtr-details">
      <li class=" text-center" data-dtr-index="1" data-dt-row="1" data-dt-column="1">
        <span class="dtr-title">Details 1</span> <span class="dtr-data"><a tabindex="0" type="button" class="btn btn-link btn-sm" data-bs-container="body" data-bs-trigger="focus" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-html="true" data-bs-custom-class="custom-popover" data-bs-content="Extra Hot">
                        Hot
                    </a></span></li>
      <li class=" text-center" data-dtr-index="2" data-dt-row="1" data-dt-column="2"><span class="dtr-title">Details 2</span> <span class="dtr-data"><a tabindex="0" type="button" class="btn btn-link btn-sm" data-bs-container="body" data-bs-trigger="focus" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-html="true" data-bs-custom-class="custom-popover" data-bs-content="Extra Slow">
                        Slow
                    </a></span></li>
    </ul>
  </td>
</tr>

因此,您需要做的是当展开隐藏单元格时,即当datable添加这些元素时,查找并启动这些新添加的元素的弹出窗口.

这可以通过在整个表上添加单独的监听器来实现,或者更准确地说,在折叠具有.dtr-control个类的元素上添加单独的监听器,然后找到新添加的行(这是控件的父行的下一个sibling 行,具有类.child),并在其中找到所有新添加的弹出窗口,并启动它们:

$('#players-data').on('click', 'td.dtr-control',  function (evt) {

const popovers = $(this).parent().next('.child').find('[data-bs-toggle="popover"]')
.each((i,el)=>new bootstrap.Popover(el));

});

这是一个演示:

<head>
  <meta charset="utf-8">
  <title>Responsive Table Popover</title>
  <meta name="description" content="">
  <meta name="author" content="">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
  <link href="https://cdn.datatables.net/2.0.5/css/dataTables.bootstrap5.min.css" rel="stylesheet">
  <link href="https://cdn.datatables.net/responsive/3.0.2/css/responsive.bootstrap5.min.css" rel="stylesheet">
</head>

<body>
  <div class="container">
    <table id="players-data" class="table table-striped" style="font-size:13px; width: 100%;">
      <thead style="white-space: nowrap;">
        <tr>
          <th>Player</th>
          <th>Details 1</th>
          <th>Details 2</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
  </div>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous">
  </script>
  <script charset="utf8" src="https://cdn.datatables.net/2.0.5/js/dataTables.min.js"></script>
  <script charset="utf8" src="https://cdn.datatables.net/2.0.5/js/dataTables.bootstrap5.min.js"></script>
  <script charset="utf8" src="https://cdn.datatables.net/responsive/3.0.2/js/dataTables.responsive.min.js"></script>
  <script charset="utf8" src="https://cdn.datatables.net/responsive/3.0.2/js/responsive.bootstrap5.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
  <script type="text/javascript">
    let players = [{
        player: 'Best',
        details_1: 'Cool',
        details_2: 'Sharp',
        details_1_extra: 'Extra Cool',
        details_2_extra: 'Extra Sharp'
      },
      {
        player: 'Worst',
        details_1: 'Hot',
        details_2: 'Slow',
        details_1_extra: 'Extra Hot',
        details_2_extra: 'Extra Slow'
      }
    ];

    $('#players-data').DataTable({
      data: players,
      columns: [{
          data: 'player',
          render: DataTable.render.text(),
          sortable: true
        },
        {
          data: 'details_1',
          sortable: false,
          class: "text-center",
          render: function(data, type, row) {
            if (data) {
              return `<a 
                        tabindex="0" 
                        type="button" 
                        class="btn btn-link btn-sm" 
                        data-bs-container="body" 
                        data-bs-trigger="focus" 
                        data-bs-toggle="popover" 
                        data-bs-placement="bottom" 
                        data-bs-html="true" 
                        data-bs-custom-class="custom-popover"
                        data-bs-content="${row.details_1_extra}">
                        ${data}
                    </a>`;
            } else {
              return data;
            }
          }
        },
        {
          data: 'details_2',
          sortable: false,
          class: "text-center",
          render: function(data, type, row) {
            if (data) {
              return `<a 
                        tabindex="0" 
                        type="button" 
                        class="btn btn-link btn-sm" 
                        data-bs-container="body" 
                        data-bs-trigger="focus" 
                        data-bs-toggle="popover" 
                        data-bs-placement="bottom" 
                        data-bs-html="true" 
                        data-bs-custom-class="custom-popover" 
                        data-bs-content="${row.details_2_extra}">
                        ${data}
                    </a>`;
            } else {
              return data;
            }
          }
        }
      ],
      destroy: true,
      searching: false,
      paging: true,
      info: false,
      ordering: true,
      stateSave: true,
      responsive: true,
      drawCallback: function(settings) {
        const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
        const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl));
      }
    });


    $('#players-data').on('click', 'td.dtr-control', function(evt) {

      const popovers = $(this).parent().next('.child').find('[data-bs-toggle="popover"]')
        .each((i, el) => new bootstrap.Popover(el));

    });
  </script>
</body>

Javascript相关问答推荐

为什么有些库公开了执行相同任务的方法,但每个方法都处于同步/同步上下文中?

Angular:ng-contract未显示

如何从对象嵌套数组的第二级对象中过滤出键

仅在React和JS中生成深色

如何访问react路由v6加载器函数中的查询参数/搜索参数

如何通过onClick为一组按钮分配功能;

react 路由加载程序行为

对象和数字减法会抵消浏览器js中的数字

如何才能拥有在jQuery终端中执行命令的链接?

将状态向下传递给映射的子元素

jQuery s data()[storage object]在vanilla JavaScript中?'

我怎么在JS里连续加2个骰子的和呢?

如何在文本字段中输入变量?

当id匹配时对属性值求和并使用JavaScript返回结果

当使用';字母而不是与';var#39;一起使用时,访问窗口为什么返回未定义的?

使用getBorbingClientRect()更改绝对元素位置

创建以键值对为有效负载的Redux Reducer时,基于键的类型检测

按下单键和多值

在表单集中保存更改时删除';禁用';

Phaser3 preFX addGlow不支持zoom