【发布时间】:2011-07-04 16:59:52
【问题描述】:
只是想知道是否有人知道如何重新创建我不久前看到的导航栏样式,我刚刚找到了我看到它的网站,但不确定他们是如何到达那里的。基本上希望它随着页面滚动然后锁定到顶部...
【问题讨论】:
标签: javascript jquery positioning
只是想知道是否有人知道如何重新创建我不久前看到的导航栏样式,我刚刚找到了我看到它的网站,但不确定他们是如何到达那里的。基本上希望它随着页面滚动然后锁定到顶部...
【问题讨论】:
标签: javascript jquery positioning
听起来像是 Jquery ScrollTop 的应用程序和导航栏元素的 CSS 属性的一些操作。例如,在某些滚动条件下,导航栏元素从计算坐标的绝对定位变为固定定位。
【讨论】:
您描述的效果通常以某种类型的动画开始,例如 TheDeveloper 的回答。默认动画通常通过改变元素的位置来滑动元素,或者通过改变元素的不透明度等来淡入/淡出元素。
获得“bouce back”或“snap to”效果通常涉及缓动。所有主要框架都有某种形式的缓动可用。这完全取决于个人喜好;任何一个你都不会出错。
jQuery 有easing plugins,您可以将其与.animate() 函数一起使用,或者您可以使用jQueryUI。
MooTools 的核心库的 FX 类有 easing built in。
Yahoo 的 YUI 也有easing built in。
如果您能记住它是什么网站,您可以随时再次访问它并查看其来源以了解使用的框架和效果。
【讨论】:
只需在http://lesscss.org/ 上快速“查看源代码”,您就会看到:
window.onscroll = function () {
if (!docked && (menu.offsetTop - scrollTop() < 0)) {
menu.style.top = 0;
menu.style.position = 'fixed';
menu.className = 'docked';
docked = true;
} else if (docked && scrollTop() <= init) {
menu.style.position = 'absolute';
menu.style.top = init + 'px';
menu.className = menu.className.replace('docked', '');
docked = false;
}
};
它们绑定到窗口的onscroll 事件,该事件在窗口滚动时触发。当菜单“锁定”到页面顶部时,docked 标志设置为 true,同时该标志设置为 true,菜单设置为 position:fixed。剩下的只是一些简单的“我们要从页面上滚动菜单吗”和“我们要回到我们开始的地方了吗”位置检查逻辑。
您必须小心onscroll 事件,它们可以快速连续触发很多,因此您的处理程序需要非常快并且应该尽可能地预先计算。
在 jQuery 中,它看起来几乎相同:
$(window).scroll(function() {
// Pretty much the same as what's on lesscss.org
});
你经常看到这种“浮动几乎固定位置垂直工具栏”的东西,比如cracked.com上的东西。
【讨论】:
menu.className?这究竟是做什么的?
menu 是一个DOM 元素,所以menu.className 将是它的class 属性。
className.replace。我遇到的问题是,当它脱离时它不会向下滚动,它要么卡在顶部,要么与之前的 div 元素的顶部对齐。不知道你有没有什么想法。
mu is too short answer is working,我只是发布这个给你 jquery 脚本!
var docked = false;
var menu = $('#menu');
var init = menu.offset().top;
$(window).scroll(function()
{
if (!docked && (menu.offset().top - $("body").scrollTop() < 0))
{
menu.css({
position : "fixed",
top: 0,
});
docked = true;
}
else if(docked && $("body").scrollTop() <= init)
{
menu.css({
position : "absolute",
top: init + 'px',
});
docked = false;
}
});
【讨论】:
穆的回答让我走得很远。我尝试了 replicationg lesscss.org 的方法,但遇到了关于浏览器调整大小和缩放的问题。我花了一段时间才知道如何正确应对以及如何重置初始位置 (@987654323 @) 没有 jQuery 或任何其他库。
在 JSFiddle 上查找预览: http://jsfiddle.net/ctietze/zeasg/
这里是详细的纯 JavaScript 代码,以防 JSFiddle 拒绝工作。
这是一个可重复使用的版本。我将滚动检查放入一个类中,因为所涉及的辅助方法使我的主命名空间变得混乱:
var windowScrollTop = function () {
return window.pageYOffset;
};
var Menu = (function (scrollOffset) {
var Menu = function () {
this.element = document.getElementById('nav');
this.docked = false;
this.initialOffsetTop = 0;
this.resetInitialOffsetTop();
}
Menu.prototype = {
offsetTop: function () {
return this.element.offsetTop;
},
resetInitialOffsetTop: function () {
this.initialOffsetTop = this.offsetTop();
},
dock: function () {
this.element.className = 'docked';
this.docked = true;
},
undock: function () {
this.element.className = this.element.className.replace('docked', '');
this.docked = false;
},
toggleDock: function () {
if (this.docked === false && (this.offsetTop() - scrollOffset() < 0)) {
this.dock();
} else if (this.docked === true && (scrollOffset() <= this.initialOffsetTop)) {
this.undock();
}
}
};
return Menu;
})(windowScrollTop);
var menu = new Menu();
window.onscroll = function () {
menu.toggleDock();
};
var updateMenuTop = function () {
// Shortly dock to reset the initial Y-offset
menu.undock();
menu.resetInitialOffsetTop();
// If appropriate, undock again based on the new value
menu.toggleDock();
};
var zoomListeners = [updateMenuTop];
(function(){
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0];
var lastWidth = 0;
function pollZoomFireEvent() {
var widthNow = w.innerWidth || e.clientWidth || g.clientWidth;
if (lastWidth == widthNow) {
return;
}
lastWidth = widthNow;
// Length changed, user must have zoomed, invoke listeners.
for (i = zoomListeners.length - 1; i >= 0; --i) {
zoomListeners[i]();
}
}
setInterval(pollZoomFireEvent, 100);
})();
【讨论】:
scrollOffset() 是 Menu 初始化时注入的属性(仅参数)。在这种情况下,它只是通过引用传入windowScrollTop。我这样做是为了将菜单与window.pageYOffset 分离,即使我认为没有其他方法可以应用。所以你也可以将scrollOffset作为方法添加到Menu,直接包装window.pageYOffset。