Knockoutjs: ScrollIntoViewTrigger

一世执手 提交于 2019-12-01 19:36:06

Your scrollTo handler is fine like this:

ko.bindingHandlers.scrollTo = {
    update: function (element, valueAccessor, allBindings) {
        var _value = valueAccessor();
        var _valueUnwrapped = ko.unwrap(_value);
        if (_valueUnwrapped) {
            element.scrollIntoView();
        }
    }
};

But instead of working with a goToThis observable per view model, better would be to have 1 observable in your root which keeps track of the current scroll item and then pass an expression in your binding like this:

<div data-bind="scrollTo: $root.scrolledItem() == $data">

This way you don't need to reset anything and you don't need an goToThis observable per view model.

See http://jsfiddle.net/290ew0nr/1/

I use scrollintoview in my knockout app, but never thought to put it into a bindingHandler, probably because I don't feel scrollintoview is a relationship between the model and the view.

scrollintoview to me is more like a follow up action after we present data on view.

My approach is to use a css binding to mark the item I want to scrollintoview, for instance, I mark the element with css class current-item, and of course there should be only one item marked with this class in the end.

Then what I need to do is to scroll it into view after ko rebuild all the DOM. To allow ko to build the view before I ran scrollintoview, I need to delay the action.

// do my model logic above
// then fire my after-render callback
setTimeout(function() {
  $('.current-item').scrollintoview({direction: 'y'});
  // I am using a different scrollintoview library: https://github.com/litera/jquery-scrollintoview
}, 0);

BTW, ko provided a better way to do afterRender callback http://knockoutjs.com/documentation/template-binding.html#note_4_using_afterrender_afteradd_and_beforeremove

You could use a template, and put scrollintoview in that template's afterRender callback.

Just my 2 cents.

Another way to tackle this problem is with custom events. You could fire an event from your ViewModel when you need to do the scrolling (supplying any relevant data), and then you define a handler on the page to react to that event. That way you can do all the DOM manipulation in the event handler and keep your ViewModel HTML-agnostic.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!