如何在 .draw() 之后保持 jQuery DataTables 滚动位置
Posted
技术标签:
【中文标题】如何在 .draw() 之后保持 jQuery DataTables 滚动位置【英文标题】:How to maintain jQuery DataTables scroll position after .draw() 【发布时间】: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() 是的,你可以这样做。有一个肮脏的黑客,但你可以。在下面寻找我的答案。 【参考方案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);
【讨论】:
以上是关于如何在 .draw() 之后保持 jQuery DataTables 滚动位置的主要内容,如果未能解决你的问题,请参考以下文章
如何将SpriteBatch.draw()等效为Sprite.draw()?