如何准确确定元素是否可滚动?

2022-06-22 00:00:00 jquery html knockout.js

我正在处理一个定制的挖空绑定,它确定是否正在滚动特定元素,并使用该元素相对于视区的顶部来更新绑定可观测对象。目前,绑定似乎起作用了,但我担心是否在某些情况下它不起作用。

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>

css:

.longdiv {
    width: 200px;
    height: 200px;
    overflow: scroll;
    border: 1px solid black;
}

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());

JSFiddle

绑定获取元素并使用jQuery遍历父链,查看父元素是否有溢出:滚动集。如果它找到一个带有overflow:scroll的div,它会将一个事件处理程序绑定到该元素的scroll事件。如果它没有找到具有overflow:scroll的父级,则会绑定到窗口的scroll事件。

给出一个结构如下的文档,我要找的就是:

body > div > div > div > p

是最接近p的可以滚动的包含元素,因此我可以将事件处理程序附加到它。

我的问题是:查看Overflow:Scroll是否足以测试父元素是否可以滚动?如果不是,我应该看什么?

编辑:根据您的有用意见和答案,以下是我提出的解决方案:

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;
    }
}

解决方案

您想知道元素是可以滚动还是当前可以滚动?

元素可以滚动吗?

如果元素具有固定的height(或max-height)且overflow-yscrollauto,则可以滚动。但由于tell if an element's height is fixed or not不容易,所以只勾选overflow-y

可能就足够了
e.css('overflow-y') == 'scroll' || e.css('overflow-y') == 'auto'

元素现在可以滚动吗?

如果元素的scrollHeight大于元素的clientHeight,并且元素具有滚动条,则元素现在可以立即滚动,这可以通过比较clientWidthoffsetWidth(考虑边距和边框)或检查overflow-yscroll还是auto来确定。

相关文章