如何获得固定位置的菜单,例如slashdot的评论过滤菜单

时间:2020-03-05 18:51:28  来源:igfitidea点击:

Slashdot有一个小部件,可让我们调整评论阈值以过滤掉降级的评论。如果我们滚动到页面顶部,它将在一个位置,而当我们向下滚动时,在某个地方,其原始位置将要从页面上滚动下来,它将切换到固定位置,并停留在屏幕上。 (要查看示例,请单击此处。)

我的问题是,如何在向上滚动菜单时将菜单放在一个位置,并在用户向下滚动时切换到固定位置,以达到相同的效果?我知道这将涉及CSS和javascript的组合。我并不一定要寻找工作代码的完整示例,但是我的代码需要经历哪些步骤?

解决方案

回答

好吧,我知道了。我将在这里发布,以防其他人使用。该解决方案使用原型,以及一个内部库,该库为我提供了registerEvent,getElementX和getElementY函数,这些函数可以完成我们想做的事情。

var MenuManager = Class.create({
    initialize: function initialize(menuElt) {
        this.menu = $(menuElt);
        this.homePosn = { x: getElementX(this.menu), y: getElementY(this.menu) };
        registerEvent(document, 'scroll', this.handleScroll.bind(this));
        this.handleScroll();
    },
    handleScroll: function handleScroll() {
        this.scrollOffset = document.viewport.getScrollOffsets().top;
        if (this.scrollOffset > this.homePosn.y) {
            this.menu.style.position = 'fixed';
            this.menu.style.top = 0;
            this.menu.style.left = this.homePosn.x;
        } else {
            this.menu.style.position = 'absolute';
            this.menu.style.top = null;
            this.menu.style.left = null;
        }
    }
});

只需使用菜单的ID调用构造函数,该类就会从菜单中获取它。

回答

感谢我们共享此代码的努力。
我做了一些小改动,使其可以与当前版本的Prototype一起使用。

var TableHeaderManager = Class.create({
    initialize: function initialize(headerElt) {
        this.tableHeader = $(headerElt);
        this.homePosn = { x: this.tableHeader.cumulativeOffset()[0], y: this.tableHeader.cumulativeOffset()[1] };
        Event.observe(window, 'scroll', this.handleScroll.bind(this));
        this.handleScroll();
    },
    handleScroll: function handleScroll() {
        this.scrollOffset = document.viewport.getScrollOffsets().top;
        if (this.scrollOffset > this.homePosn.y) {
            this.tableHeader.style.position = 'fixed';
            this.tableHeader.style.top = 0;
            this.tableHeader.style.left = this.homePosn.x;
        } else {
            this.tableHeader.style.position = 'absolute';
            this.tableHeader.style.top = null;
            this.tableHeader.style.left = null;
        }
    }
});