【问题标题】:Trigger Knockout BindingHandler linked to KnockoutObservable on document.body.scrollTop触发 Knockout BindingHandler 链接到 document.body.scrollTop 上的 KnockoutObservable
【发布时间】:2023-03-03 15:56:01
【问题描述】:

我正在尝试触发 Knockout BindingHandler 作为 document.body.scrolltop 值大于或等于特定值的直接结果。我试图根据声明创建一个可观察的。首先,这可能吗?还是应该将布尔结果作为计算的一部分进行更新?

scrollPosition: KnockoutObservable<boolean> = ko.observable(document.body.scrollTop >= 200)

我也试过了:

scrollPosition: KnockoutComputed<boolean> = ko.computed(() => {
    if (document.body.scrollTop >= 100) {
        return true;
    }
    else {
        return false;
    }
});

其余相关代码为:

HTML

<a href="javascript:void(0);" id="topLink" data-bind="topScroll: scrollPosition"><i class="glyphicon glyphicon-stats"></i></a>

CSS

#topLink {
    position: fixed;
    bottom: 40px;
    right: 40px;
    background: rgba(72,72,72,1);
    width: 50px;
    height: 50px;
    display: none;
    text-decoration: none;
    -webkit-border-radius: 35px;
    -moz-border-radius: 35px;
    border-radius: 35px;
    -webkit-transition: all 0.3s linear;
    -moz-transition: all 0.3s ease;
    -ms-transition: all 0.3s ease;
    -o-transition: all 0.3s ease;
    transition: all 0.3s ease;
}

BindingHandler

ko.bindingHandlers.topScroll = {
    update: function (element, valueAccessor) {
        // This will be called once when the binding is first applied to an element,
        // and again whenever any observables/computeds that are accessed change
        // Update the DOM element based on the supplied values here.

        var value = valueAccessor();

        if (ko.unwrap(value)) {

            $(element).css("display", "block");
        }
    }
};

我的目标是在顶部滚动超出特定值时显示返回顶部样式链接。有人可以指出我哪里出错了吗?

【问题讨论】:

    标签: jquery html css knockout.js bindinghandlers


    【解决方案1】:

    ...首先,这可能吗?还是应该将布尔结果作为计算的一部分进行更新?

    scrollPosition = ko.observable(document.body.scrollTop &gt;= 200)

    您希望scrollPosition 是动态的。你实际上想要的是body.scrollTop 成为一个可观察的。但事实并非如此。所以严格来说:,这是不可能的。

    我的建议是在body 元素上创建一个custom binding handler,以检测用户何时滚动 (akin to this) 并因此更新一个 observable。

    以下是您在视图中如何使用它的伪代码:

    <body data-bind="changeOnScroll: shouldShowLink">
    

    自定义绑定处理程序可能是这样的(伪代码):

    ko.bindingHandlers.changeOnScroll = {
        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // This will be called when the binding is first applied to an element
            // Set up any initial state, event handlers, etc. here
    
            element.onscroll = function() {
                var obs = valueAccessor();
                obs(element.scrollTop > 200); // set the observable
            }
        },
        update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // This will be called once when the binding is first applied to an element,
            // and again whenever any observables/computeds that are accessed change
            // Update the DOM element based on the supplied values here.
    
            // Nothing here, since it's a one-way binding from DOM to observable.
        }
    };
    

    我使用过onscroll,但如果您有可用于规范化事件处理的 jQuery,您也可以使用它。

    【讨论】:

    • 非常感谢 Jeroen 的回复。我想如果我早点发现你的解释和回答,那将是一条更快地解决我所使用的解决方案的道路!
    【解决方案2】:

    在看到 Jeroen 的答案之前,我已经找到了一个我很满意的解决方案。我已将一个固定的 true 传递给 BindingHandler 数据绑定。

    <a href="javascript:void(0);" id="topLink" data-bind="topScroll: true"><i class="glyphicon glyphicon-stats"></i></a>
    

    然后将BindingHandler修改为如下……

    ko.bindingHandlers.topScroll = {
        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // This will be called when the binding is first applied to an element
            // Set up any initial state, event handlers, etc. here
            $(window).scroll(function() {
    
                if ($(this).scrollTop() >= 150) {         // If page is scrolled more than 150px
    
                    $(element).css("display", "block");  // show the arrow
                } else {
                    $(element).css("display", "none");   // don't show the arrow
                }
            });
    
            $(element).click(function () {      // When arrow is clicked
                $('body,html').animate({
                    scrollTop: 0                       // Scroll to top of body
                }, 'slow');
            });
    
        }    
    };  
    

    【讨论】:

      猜你喜欢
      • 2021-02-13
      • 2018-06-03
      • 2013-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-09
      • 2014-05-03
      • 1970-01-01
      相关资源
      最近更新 更多