【问题标题】:How to maintain jQuery DataTables scroll position after .draw()如何在 .draw() 之后保持 jQuery DataTables 滚动位置
【发布时间】:2015-02-24 03:44:57
【问题描述】:

我正在将 jQuery Datatables 插件用于小表(12 行)。一些<input type="text" ... 字段允许编辑。当输入字段失去焦点时,我需要验证其值并可能更改字段值。如果不发出 .draw() 之后,我无法让 DataTables 识别修改后的输入字段值,但这会导致表格滚动到表格顶部。

有没有办法在发出 .draw() 后保持当前滚动位置?

$('#mytable').on('blur', 'input', function (e) {

    var inputFieldId = this.id;
    var inputFieldVal = $(this).val();

    { ... perform validation of field value ... }

    $('#mytable').DataTable().rows().invalidate().draw();
});

编辑

我看到有人试图做与我相同的事情,他们表示以下代码对他们有用。这似乎是完成我需要的一种非常简单的方法,但我自己总是得到 scrollTop = 0 。有人知道我如何获取当前选定行的行索引吗?

var scrollPos = $(".dataTables_scrollBody").scrollTop();
$('#mytable').DataTable().rows().invalidate().draw(false);
$(".dataTables_scrollBody").scrollTop(scrollPos);

【问题讨论】:

  • 对不起,我没有看到您的更改,您的代码是正确的,但请尝试使用 scrollTo() $(".dataTables_scrollBody").scrollTo('#IDROW')。其中 'IDROW' 是 ROW 的 ID,或者只是您更改的输入的 ID
  • 万一你有多个具有相同className的dataTables,你应该使用ID选择器$("#divContrainer1 > .dataTables_scrollBody").scrollTop()
  • 是的,你可以这样做。有一个肮脏的黑客,但你可以。在下面寻找我的答案。

标签: jquery datatables jquery-datatables


【解决方案1】:
var table = $('table#example').DataTable({
    "preDrawCallback": function (settings) {
        pageScrollPos = $('div.dataTables_scrollBody').scrollTop();
    },
    "drawCallback": function (settings) {
        $('div.dataTables_scrollBody').scrollTop(pageScrollPos);
    }
});

这似乎对我有用。我只需要在绘制表格后找到div.dataTables_scrollBody

【讨论】:

  • 正确答案。
  • 节省了我的时间。谢谢
  • 我认为这是一个更好的答案。对我很有用。这是一个简单的即插即用,你就完成了。如果在选择滚动体之前添加表格 ID,会更安全。 $('table#example div.dataTables_scrollBody').scrollTop();
  • 我发现当我使用粘性标题时,有时会在页面顶部添加另一个表格标题。如果我将drawCallback 包装在setTimeout 中并将其设置为一个小的间隔,它将避免它。 tableConfig.drawCallback = () => setTimeout(() => $('div.dataTables_scrollBody').scrollTop(pageScrollPos);, 50);
【解决方案2】:

只是想在此处添加此内容,尽管情况略有不同 - 它适用于我的情况,并且可能对到达这里寻找答案的其他一些人有用。

我正在使用服务器端处理并使用table.ajax.reload() 每 10 秒刷新一次表数据。这个函数接受一个参数来保持当前的分页值,但不能保持滚动位置。该解决方案与 OP 提到的解决方案非常相似,并在回调中设置滚动位置。不知道为什么它对他不起作用,但这是我成功使用的间隔代码:

setInterval( function () {
    scrollPos = $(".dataTables_scrollBody").scrollTop();
    myTable.ajax.reload(function() {
        $(".dataTables_scrollBody").scrollTop(scrollPos);
    },false);
}, 10000 );

【讨论】:

  • 非常简单的解决方案
【解决方案3】:

我使用 DataTables 1.10 解决的方法是使用preDrawCallBack 保存 ScrollTop 位置,然后使用DrawCallback 设置它。

var pageScrollPos = 0;

var table = $('#example').DataTable({
  "preDrawCallback": function (settings) {
    pageScrollPos = $('body').scrollTop();
  },
  "drawCallback": function (settings) {
    $('body').scrollTop(pageScrollPos);
  }
});

【讨论】:

    【解决方案4】:

    如果您将page 参数传递给绘图函数,表格将不会滚动移动,但会从.DataTable 源重新读取。例如。在“保存”更新 DataTable 的数据之后:

    $("your-selector").DataTable().row(t_itemid).invalidate();
    $("your-selector").DataTable().row(t_itemid).draw('page');
    

    注意:我在 DataTable 实例化中使用了 id 列,这使得直接处理单行变得容易。但我相信page 参数会给出想要的结果。

    【讨论】:

    • $table.draw('page') 比其他任何解决方案都好用。直接设置 scrollTop 会滚动,但也会使数据表对象失去对其所在位置的跟踪,并且其他控件会误报数据,例如正在显示的开始/结束行等
    • 非常适合我。
    【解决方案5】:

    我不认为你可以这样做,但你可以使用回调函数来代替:

    $(document).ready(function() {
        var selected = [];
    
        $("#example").dataTable({
            "processing": true,
            "serverSide": true,
            "ajax": "scripts/ids-arrays.php",
            "rowCallback": function( row, data ) {
                if ( $.inArray(data.DT_RowId, selected) !== -1 ) {
                    $(row).addClass('selected');
                }
            }
        });
    
        $('#example tbody').on('click', 'tr', function () {
            var id = this.id;
            var index = $.inArray(id, selected);
    
            if ( index === -1 ) {
                selected.push( id );
            } else {
                selected.splice( index, 1 );
            }
    
            $(this).toggleClass('selected');
        } );
    } );
    

    参考:https://datatables.net/examples/server_side/select_rows.html

    【讨论】:

    • 谢谢。我使用有人说为他们工作的解决方案编辑了我的帖子,但我的 scrollTop 始终等于 0。您在编辑的示例中看到任何优点吗?我想我需要将 scrollTop 设置为当前选定的行索引,但是鉴于我的事件触发器,我不确定如何获取当前行索引。我还没有尝试过你的例子,因为我不完全理解它是如何工作的。
    • 您可以为您的行元素之一添加 ID 属性,然后是 $('body').scrollTo('#target');编辑元素后。如果我的解释不够清楚,请告诉我。
    【解决方案6】:

    这个黑客怎么样?不涉及scrollTop()先打开jquery.dataTables.js 找这行,去掉:

    divBodyEl.scrollTop = 0
    

    然后将以下代码放在您的 draw()/clear() 调用之前:

    var $tbl=$('#my_table_id');
    if (!document.getElementById('twrapper')) $tbl.wrap( '<div id="twrapper" style="display:block; height:'+$tbl.height()+'px;"></div>' );
    else $('#twrapper').css('height',$tbl.height()+'px');
    

    我花了一些时间才弄清楚这一点。

    【讨论】:

      【解决方案7】:

      以下代码在 Datatables 服务器端重新加载时保留滚动位置。

      var table =  $('#mytable').DataTable();
      
      var start_row = table.scroller.page()['start'];
      
      table.ajax.reload(function () {
      
          table.scroller().scrollToRow(start_row, false);
      
      }, false);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-05
        • 1970-01-01
        • 1970-01-01
        • 2011-11-28
        • 2010-10-03
        • 2019-08-03
        • 1970-01-01
        相关资源
        最近更新 更多