在 document.body.scrollTop 上触发链接到 KnockoutObservable 的 Knockout BindingHandler
Trigger Knockout BindingHandler linked to KnockoutObservable on document.body.scrollTop
我试图触发 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;
}
绑定处理程序
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");
}
}
};
我的目标是在顶部滚动超出特定值时显示返回顶部样式 link。有人可以指出我哪里出错了吗?
... Firstly, is this possible? Or should I be updating the boolean result as part of a computed?
scrollPosition = ko.observable(document.body.scrollTop >= 200)
您希望 scrollPosition
是动态的。您实际上 想要的是 body.scrollTop
成为可观察的。但事实并非如此。所以严格来说:没有,这是不可能的。
我的建议是创建一个 custom binding handler on the body
element that detects when the user is scrolling (akin to this) 并随后更新一个可观察对象。
这是关于如何在视图中使用它的伪代码:
<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,您也可以使用 jQuery。
在看到 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');
});
}
};
我试图触发 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;
}
绑定处理程序
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");
}
}
};
我的目标是在顶部滚动超出特定值时显示返回顶部样式 link。有人可以指出我哪里出错了吗?
... Firstly, is this possible? Or should I be updating the boolean result as part of a computed?
scrollPosition = ko.observable(document.body.scrollTop >= 200)
您希望 scrollPosition
是动态的。您实际上 想要的是 body.scrollTop
成为可观察的。但事实并非如此。所以严格来说:没有,这是不可能的。
我的建议是创建一个 custom binding handler on the body
element that detects when the user is scrolling (akin to this) 并随后更新一个可观察对象。
这是关于如何在视图中使用它的伪代码:
<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,您也可以使用 jQuery。
在看到 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');
});
}
};