剑道网格滚动到选定的行

Posted

技术标签:

【中文标题】剑道网格滚动到选定的行【英文标题】:Kendo Grid scroll to selected row 【发布时间】:2013-07-01 11:12:41 【问题描述】:

我希望能够调用将 Kendo 网格滚动到所选行的函数。我已经尝试了一些方法,但没有一个有效,

例如我试过这个:

var grid = $("#Grid").data("kendoGrid"),
    content = $(".k-grid-content");
content.scrollTop(grid.select());

我也试过这个:

var gr = $("#Grid").data("kendoGrid");
var dataItem = gr.dataSource.view()[gr.select().closest("tr").index()];
var material = dataItem.id;
var row = grid.tbody.find(">tr:not(.k-grouping-row)").filter(function (i) 
    return (this.dataset.id == material);
);
content.scrollTop(row);

谁能指出我正确的方向? :)

---已编辑---

由于其他原因,我无法绑定到更改事件,因此我必须能够调用一个函数,将列表滚动到选定的行。这就是我尝试使用@Antonis 为我提供的答案。

var grid = $("#Grid").data("kendoGrid")
grid.element.find(".k-grid-content").animate(  
    scrollTop: this.select().offset().top  
 , 400);

当我尝试这样做时,它会稍微向下滚动列表,但不会滚动到所选行。我是否通过调用 scrollTop 以错误的方式使用网格对象?

这也是:

var grid = $("#ItemGrid").data("kendoGrid");
grid.scrollToSelectedRow = function () 
    var selectedRow = this.select();
    if (!selectedRow)     
        return false;    
    
    this.element.find(".k-grid-content").animate(
        scrollTop: selectedRow.offset().top  
    , 400);
    return true;
    ;

grid.scrollToSelectedRow();

【问题讨论】:

scrollTop() 采用整数参数作为距顶部的像素偏移量,而不是要滚动到的元素。例如.scrollTop(0) 将滚动到顶部(从顶部偏移 0 个像素)。 【参考方案1】:

所以这里的大多数答案都犯了两个错误,一个只是效率问题,另一个是实际的错误。

    使用element.find(".k-grid-content")。这是非常不必要的。 grid.content 为您提供完全相同的东西更容易(更快)。

    使用.offset() 查找行的位置。 这是不正确的: 这将告诉您该行相对于文档本身的位置。如果您的页面允许您滚动整个页面(而不仅仅是网格),则此数字将不正确。

    改为使用.position() - 这为您提供相对于偏移父级的位置。 为了让.position() 为您提供正确的数字,grid.content 中的表格必须包含position: relative最好通过 CSS 样式表应用:

    .k-grid-content 表
      位置:相对;
    

无论如何,假设您已经有一个网格本身的引用(我将其称为 grid),并且您将内容窗格设置为 relative 位置,那么您所要做的就是:

grid.content.scrollTop(grid.select().position().top);

或者,对于动画,

grid.content.animate( scrollTop: grid.select().position().top , 400);

如前所述,grid.content 为您提供内容窗格,即您想要实际滚动的部分。它是一个 jQuery 对象。

jQuery 对象有一个.scrollTop 方法,所以这部分非常简单。当您使用 scrollTop 属性时,.animate 方法的工作方式类似。现在我们只需要知道在哪里滚动

为此,grid.select() 返回一个对应于所选行的 jQuery 对象。这就是您要滚动的地方。为了获得它的位置,我们使用 jQuery .position() 方法。返回值是一个带有topleft字段的对象;我们想滚动到它的垂直位置,所以我们使用top

当然,这在change 回调中最容易使用; grid 只是 this (因为回调是在网格本身上调用的),并且在选择更改时会自动调用 change。但是你可以在任何时候调用这个代码来滚动到选择;您可以通过以下方式获得grid

grid = $('#theGridsId').data('kendoGrid');

【讨论】:

应该是 grid.content.animate ? @AstroSharp:是的,我已经编辑了答案。等待同行评审。 这在 onDataBound 中非常有效,但是当我放入 kendo tabstrip 时,位置的值在 onDatabound 中始终为零,并且仅在我到达它的相应选项卡时才有效 onChange。有什么想法吗?【参考方案2】:

您可以在选择一行时自动执行此操作。 将函数绑定到 'change' 事件,在其中,您可以滚动到选定的行。 (假设您只能选择一行,由 'this.select()' 给出)

JSFiddle example

“更改”处理程序

//    bind to 'change' event
function onChangeSelection(e) 

    //    animate our scroll
    this.element.find(".k-grid-content").animate(  // use $('html, body') if you want to scroll the body and not the k-grid-content div
        scrollTop: this.select().offset().top  //  scroll to the selected row given by 'this.select()'
     , 400);

【讨论】:

感谢您的回答@Antonis。我已经根据您的回答编辑了我的问题。问题是由于其他原因我不能使用更改事件。我需要能够调用网格,然后滚动到选定的元素。 好吧,你绝对可以做到这一点。我会尽量找一些空闲时间,给你做个例子。但是你可以自己试试,看看我是怎么做到的。您必须首先获得选定的行,然后滚动到它。 看一个简单的例子。我做了一个按钮,只要你点击它就会调用滚动功能 --> jsfiddle.net/blackjim/9GCYE/12 滚动有一个小错误。尝试使用scrollToSelectedRow 函数中的调试器修复它。不幸的是,我现在没有太多时间来修复它。 感谢这个例子,我发现它在 jsfiddle 中可以正常工作。我已经为您的示例中的网格实现了新的滚动功能。我没有收到任何错误,但它还没有滚动。我想知道示例最后一行中的“kendoScroller”,由于某种原因,我的编译器不会接受它作为已知函数。这是滚动条工作的重要属性吗? 不,删除这一行。我不记得是不是我写的。也许我正在尝试什么,但我忘记了。【参考方案3】:

这是更新的代码 http://jsfiddle.net/27Phm/12/

//    bind to 'change' event
function onChangeSelection(e) 
    try 
        var $trSelect = this.select();
        var $kcontent = this.element.find(".k-grid-content");
        if ($trSelect && $trSelect.length == 1 && $kcontent) 
            var scrollContentOffset = this.element.find("tbody").offset().top;
            var selectContentOffset = $trSelect.offset().top;
            var IsMove = false;
            var distance = selectContentOffset - scrollContentOffset;
            distance += $kcontent.offset().top;
            if ($trSelect.prev().length == 1 && distance > $trSelect.prev().offset().top) 
                distance = (distance - $trSelect.prev().offset().top); //+ ($trSelect.height());
                //var toprows = $kcontent.scrollTop() / $trSelect.height(); //top rows above the scroll
                var selrowtotal = ($trSelect.offset().top - $kcontent.offset().top) + $trSelect.height();
                IsMove = selrowtotal > $kcontent.height() ? true : false;
                if (IsMove) $kcontent.scrollTop(distance);
            
            if (!IsMove && $trSelect.offset().top < $kcontent.offset().top) 
                distance = selectContentOffset - scrollContentOffset;
                $kcontent.scrollTop(distance - 15);`enter code here`
            
        
     catch (e) 

    

【讨论】:

看起来像这样一行: if (IsMove) $kcontent.scrollTop(distance);应该是: if (IsMove) $kcontent.scrollTop(selrowtotal - distance); 这个问题可以而且应该用一行来解决,如果你想非常清楚自己在做什么,可以用两行来解决。【参考方案4】:

我的偏移量有问题,所以位置对我来说效果更好:

grid.element.find(".k-grid-content").animate(  // use $('html, body') if you want to scroll the body and not the k-grid-content div
                    scrollTop: this.select().position().top  //  scroll to the selected row given by 'this.select()'
                 , 400);    

【讨论】:

element.find(".k-grid-content") 效率低得离谱;请改用.content【参考方案5】:

我在 Kendo 移动 MVVM 中找到了一个功能

parent.set('onShow', function (e) 
   e.view.scroller.reset();

app.xxx = kendo.observable(
   onShow: function()  e.view.scroller.reset(); 
);

【讨论】:

以上是关于剑道网格滚动到选定的行的主要内容,如果未能解决你的问题,请参考以下文章

过滤后如何在剑道 ui 网格上显示水平滚动条?

剑道网格列宽+可滚动

剑道网格的水平滚动

隐藏/显示剑道网格​​滚动条

剑道网格,水平滚动和列大小

如果启用了无限滚动,如何防止剑道网格两次加载数据?