JSFiddle - React, Tailwind, and code Playground
by Dan Bonelli
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
Scroll position: <span data-bind="text: scrollPosition"></span>
<div class="longdiv">
<p data-bind="scroll: scrollPosition">This is some text.</p>
<div class="shim"></div>
</div>
CSS
.longdiv {
width: 200px;
height: 200px;
overflow: auto;
border: 1px solid black;
}
.shim {
height: 1000px;
}
JavaScript
function scrollable(element) {
var vertically_scrollable, horizontally_scrollable;
var e = $(element);
if ( e.css('overflow') == 'scroll'
|| e.css('overflow') == 'auto'
|| e.css('overflowY') == 'scroll'
|| e.css('overflowY') == 'auto'
|| e.css('height') != 'none'
|| e.css('max-height') != 'none'
) {
return true;
} else {
return false;
}
}
ko.bindingHandlers.scroll = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var firstScrollableContainer = null;
var binding = allBindings.get('scroll');
$(element).parents().each(function (i, parent) {
if (scrollable(parent)) {
firstScrollableContainer = parent;
return false;
}
});
firstScrollableContainer = firstScrollableContainer || window;
binding(element.getBoundingClientRect().top);
var handler = function() {
binding(element.getBoundingClientRect().top);
};
if (firstScrollableContainer !== window) {
$(firstScrollableContainer).scroll(handler);
}
$(window).scroll(handler);
}
};
var ViewModel = function() {
var self = this;
self.scrollPosition = ko.observable(0);
};
ko.applyBindings(new ViewModel());