McC*_*key 12 html jquery knockout.js
我正在开发一个自定义的knockout绑定,用于确定是否正在滚动特定元素,并使用元素相对于视口的顶部更新绑定的observable.现在,绑定似乎有效,但我担心是否存在某些情况不会发生.
HTML:
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>
Run Code Online (Sandbox Code Playgroud)
CSS:
.longdiv {
width: 200px;
height: 200px;
overflow: scroll;
border: 1px solid black;
}
Run Code Online (Sandbox Code Playgroud)
JS:
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 ($(parent).css('overflow')=='scroll') {
firstScrollableContainer = parent;
return false;
}
});
firstScrollableContainer = firstScrollableContainer || window;
binding(element.getBoundingClientRect().top);
$(firstScrollableContainer).scroll(function() {
binding(element.getBoundingClientRect().top);
});
}
};
var ViewModel = function() {
var self = this;
self.scrollPosition = ko.observable(0);
};
ko.applyBindings(new ViewModel());
Run Code Online (Sandbox Code Playgroud)
绑定接受元素并使用jQuery走向父链,以查看父元素是否有溢出:scroll set.如果它找到一个带溢出的div:scroll,它会将一个事件处理程序绑定到该元素的scroll事件.如果找不到具有溢出的父级:滚动,则它会绑定到窗口的滚动事件.
所以我正在寻找,给出一个像这样结构的文档:
body > div > div > div > p
Run Code Online (Sandbox Code Playgroud)
是最接近p的包含元素,可以滚动,以便我可以附加一个事件处理程序.
我的问题是:正在查看溢出:滚动一个足够的测试,看看是否可以滚动父元素?如果没有,我应该看什么?
编辑:基于您的有用的评论和答案,这是我提出的解决方案:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Raf*_*lKr 12
这可能是最好的解决方案:
$.fn.isHScrollable = function () {
return this[0].scrollWidth > this[0].clientWidth;
};
$.fn.isVScrollable = function () {
return this[0].scrollHeight > this[0].clientHeight;
};
$.fn.isScrollable = function () {
return this[0].scrollWidth > this[0].clientWidth || this[0].scrollHeight > this[0].clientHeight;
};
Run Code Online (Sandbox Code Playgroud)
然后你可以检查元素是否可滚动如下:
$(parent).isScrollable();
Run Code Online (Sandbox Code Playgroud)
Mic*_*est 10
你想知道一个元素是否可以滚动或当前可以滚动?
如果元素具有固定height(或max-height)并且overflow-y是scroll或,则可以滚动auto.但由于要判断元素的高度是否固定并不容易,所以只需检查overflow-y:
e.css('overflow-y') == 'scroll' || e.css('overflow-y') == 'auto'
Run Code Online (Sandbox Code Playgroud)
如果元素scrollHeight大于它clientHeight并且它有滚动条,则可以立即滚动元素,这可以通过比较clientWidth和offsetWidth(考虑边距和边界)或检查是否overflow-y为scroll或来确定auto.
将两个答案合并在一起,并添加一些我自己的东西,这就是我用来检查垂直滚动的方法。它可以很容易地转换为其他情况。(H 和 VH)
function isScrollable(e){
if( e.scrollTopMax !== undefined )
return e.scrollTopMax > 0; //All Hail Firefox and it's superior technology!
if( e == document.scrollingElement ) //If what you're checking is BODY (or HTML depending on your css styles)
return e.scrollHeight > e.clientHeight; //This is a special case.
return e.scrollHeight > e.clientHeight && ["scroll", "auto"].indexOf(getComputedStyle(e).overflowY) >= 0
}
Run Code Online (Sandbox Code Playgroud)
我在 Firefox 和 Chromium 上对此进行了测试。两者都是Linux。不过,您可能仍然想亲自检查一下。