Aug
11
实现页面不同位置间平滑滚动的两种解决方案
雪糕先生 2009/08/11
14:36

在网页设计中,当页面较长或是想实现一个导航效果时,我们经常会用锚点来实现同一页面间不同位置的跳转。但是这样做也许会造成用户的一种困惑——当用锚点跳转时,页面内容瞬间发生了改变,用户也许就会想:我还在原来的那个页面上吗?如果我们能把这种情况做成平滑滚动的效果(而非瞬间跳转到页面的另一个位置),就可以获得一个好的用户体验。
对于这种情况的解决方案可能已经有不少,这里我找到两个感觉比较好的与大家分享:
解决方案一:
这个方法使用起来非常简单(当然功能单一,也没有乱七八糟的参数可配置):将smoothscroll.js文件在head标签中引用,页面中所有锚点跳转的效果都变成了平滑滚动。
smoothscroll.js 文件内容如下
HTML
解决方案二:
ScrollTo是一款用来实现页面间不同位置平滑滚动的jquery插件。相比解决方案一,它的功能就强大多了,有不少参数可以配置,跳转的位置也不仅限于锚点(可以是DOM对象,绝对坐标位置、相对位置等等),而且跳转的范围不仅可以设置为整个屏幕,而且可以指定为某个节点内。 例如(以下例子均假设跳转链接id=’link’):
滚动至屏幕的最顶端(重置屏幕位置)
$('#top').click(function(){
/*第一个参数0表示滑动至屏幕原点,第二个参数表示滑动速度*/
$.scrollTo(0 , 800 );
});
滚动至页面某一坐标(绝对位置)
$('#link').click(function(){
/*第一个参数表示滑动至屏幕距上110px、距左290px处,第二个参数表示滑动速度*/
$.scrollTo(0{top:'110px',left:'290px'}, 800 );
});
滚动至页面某一坐标(相对位置)
$('#link').click(function(){
/*第一个参数表示相对当前上移110px、右移290px,第二个参数表示滑动速度*/
$.scrollTo(0{top:'-=110px',left:'+=290px'}, 800 );
});
对于这种情况的解决方案可能已经有不少,这里我找到两个感觉比较好的与大家分享:
解决方案一:
这个方法使用起来非常简单(当然功能单一,也没有乱七八糟的参数可配置):将smoothscroll.js文件在head标签中引用,页面中所有锚点跳转的效果都变成了平滑滚动。
smoothscroll.js 文件内容如下
引用
/* Smooth scrolling
Changes links that link to other parts of this page to scroll
smoothly to those links rather than jump to them directly, which
can be a little disorienting.
sil, http://www.btoss.com/
v1.0 2003-11-11
v1.1 2005-06-16 wrap it up in an object
*/
var ss = {
fixAllLinks: function() {
// Get a list of all links in the page
var allLinks = document.getElementsByTagName('a');
// Walk through the list
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if ((lnk.href && lnk.href.indexOf('#') != -1) &&
( (lnk.pathname == location.pathname) ||
('/'+lnk.pathname == location.pathname) ) &&
(lnk.search == location.search)) {
// If the link is internal to the page (begins in #)
// then attach the smoothScroll function as an onclick
// event handler
ss.addEvent(lnk,'click',ss.smoothScroll);
}
}
},
smoothScroll: function(e) {
// This is an event handler; get the clicked on element,
// in a cross-browser fashion
if (window.event) {
target = window.event.srcElement;
} else if (e) {
target = e.target;
} else return;
// Make sure that the target is an element, not a text node
// within an element
if (target.nodeName.toLowerCase() != 'a') {
target = target.parentNode;
}
// Paranoia; check this is an A tag
if (target.nodeName.toLowerCase() != 'a') return;
// Find the <a name> tag corresponding to this href
// First strip off the hash (first character)
anchor = target.hash.substr(1);
// Now loop all A tags until we find one with that name
var allLinks = document.getElementsByTagName('a');
var destinationLink = null;
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if (lnk.name && (lnk.name == anchor)) {
destinationLink = lnk;
break;
}
}
if (!destinationLink) destinationLink = document.getElementById(anchor);
// If we didn't find a destination, give up and let the browser do
// its thing
if (!destinationLink) return true;
// Find the destination's position
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent &&
(thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
// Stop any current scrolling
clearInterval(ss.INTERVAL);
cypos = ss.getCurrentYPos();
ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
ss.INTERVAL =
setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);
// And stop the actual click happening
if (window.event) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (e && e.preventDefault && e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
}
},
scrollWindow: function(scramount,dest,anchor) {
wascypos = ss.getCurrentYPos();
isAbove = (wascypos < dest);
window.scrollTo(0,wascypos + scramount);
iscypos = ss.getCurrentYPos();
isAboveNow = (iscypos < dest);
if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
// if we've just scrolled past the destination, or
// we haven't moved from the last scroll (i.e., we're at the
// bottom of the page) then scroll exactly to the link
window.scrollTo(0,dest);
// cancel the repeating timer
clearInterval(ss.INTERVAL);
// and jump to the link directly so the URL's right
location.hash = anchor;
}
},
getCurrentYPos: function() {
if (document.body && document.body.scrollTop)
return document.body.scrollTop;
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
if (window.pageYOffset)
return window.pageYOffset;
return 0;
},
addEvent: function(elm, evType, fn, useCapture) {
// addEvent and removeEvent
// cross-browser event handling for IE5+, NS6 and Mozilla
// By Scott Andrew
if (elm.addEventListener){
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent){
var r = elm.attachEvent("on"+evType, fn);
return r;
} else {
alert("Handler could not be removed");
}
}
}
ss.STEPS = 25;
ss.addEvent(window,"load",ss.fixAllLinks);
Changes links that link to other parts of this page to scroll
smoothly to those links rather than jump to them directly, which
can be a little disorienting.
sil, http://www.btoss.com/
v1.0 2003-11-11
v1.1 2005-06-16 wrap it up in an object
*/
var ss = {
fixAllLinks: function() {
// Get a list of all links in the page
var allLinks = document.getElementsByTagName('a');
// Walk through the list
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if ((lnk.href && lnk.href.indexOf('#') != -1) &&
( (lnk.pathname == location.pathname) ||
('/'+lnk.pathname == location.pathname) ) &&
(lnk.search == location.search)) {
// If the link is internal to the page (begins in #)
// then attach the smoothScroll function as an onclick
// event handler
ss.addEvent(lnk,'click',ss.smoothScroll);
}
}
},
smoothScroll: function(e) {
// This is an event handler; get the clicked on element,
// in a cross-browser fashion
if (window.event) {
target = window.event.srcElement;
} else if (e) {
target = e.target;
} else return;
// Make sure that the target is an element, not a text node
// within an element
if (target.nodeName.toLowerCase() != 'a') {
target = target.parentNode;
}
// Paranoia; check this is an A tag
if (target.nodeName.toLowerCase() != 'a') return;
// Find the <a name> tag corresponding to this href
// First strip off the hash (first character)
anchor = target.hash.substr(1);
// Now loop all A tags until we find one with that name
var allLinks = document.getElementsByTagName('a');
var destinationLink = null;
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if (lnk.name && (lnk.name == anchor)) {
destinationLink = lnk;
break;
}
}
if (!destinationLink) destinationLink = document.getElementById(anchor);
// If we didn't find a destination, give up and let the browser do
// its thing
if (!destinationLink) return true;
// Find the destination's position
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent &&
(thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
// Stop any current scrolling
clearInterval(ss.INTERVAL);
cypos = ss.getCurrentYPos();
ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
ss.INTERVAL =
setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);
// And stop the actual click happening
if (window.event) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (e && e.preventDefault && e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
}
},
scrollWindow: function(scramount,dest,anchor) {
wascypos = ss.getCurrentYPos();
isAbove = (wascypos < dest);
window.scrollTo(0,wascypos + scramount);
iscypos = ss.getCurrentYPos();
isAboveNow = (iscypos < dest);
if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
// if we've just scrolled past the destination, or
// we haven't moved from the last scroll (i.e., we're at the
// bottom of the page) then scroll exactly to the link
window.scrollTo(0,dest);
// cancel the repeating timer
clearInterval(ss.INTERVAL);
// and jump to the link directly so the URL's right
location.hash = anchor;
}
},
getCurrentYPos: function() {
if (document.body && document.body.scrollTop)
return document.body.scrollTop;
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
if (window.pageYOffset)
return window.pageYOffset;
return 0;
},
addEvent: function(elm, evType, fn, useCapture) {
// addEvent and removeEvent
// cross-browser event handling for IE5+, NS6 and Mozilla
// By Scott Andrew
if (elm.addEventListener){
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent){
var r = elm.attachEvent("on"+evType, fn);
return r;
} else {
alert("Handler could not be removed");
}
}
}
ss.STEPS = 25;
ss.addEvent(window,"load",ss.fixAllLinks);
HTML
引用
<script type="text/javascript" src="http://btoss.com/smoothscroll.js"></script>
ScrollTo是一款用来实现页面间不同位置平滑滚动的jquery插件。相比解决方案一,它的功能就强大多了,有不少参数可以配置,跳转的位置也不仅限于锚点(可以是DOM对象,绝对坐标位置、相对位置等等),而且跳转的范围不仅可以设置为整个屏幕,而且可以指定为某个节点内。 例如(以下例子均假设跳转链接id=’link’):
滚动至屏幕的最顶端(重置屏幕位置)
$('#top').click(function(){
/*第一个参数0表示滑动至屏幕原点,第二个参数表示滑动速度*/
$.scrollTo(0 , 800 );
});
滚动至页面某一坐标(绝对位置)
$('#link').click(function(){
/*第一个参数表示滑动至屏幕距上110px、距左290px处,第二个参数表示滑动速度*/
$.scrollTo(0{top:'110px',left:'290px'}, 800 );
});
滚动至页面某一坐标(相对位置)
$('#link').click(function(){
/*第一个参数表示相对当前上移110px、右移290px,第二个参数表示滑动速度*/
$.scrollTo(0{top:'-=110px',left:'+=290px'}, 800 );
});
分类
热门文章
- [44187]五种方法安装Windows...
- [26672]您可能需要与该网络的 in...
- [13132]开机自动检测网络状态运行程...
- [11667]双路由器上网的连接和设置方...
- [11316]Google提供的免费天气...
- [11315]雪糕乐园小游戏集2.04版...
- [11030]2012东埔英歌舞
- [10976]EvaPhone - 无需...
- [10294]各种BIOS的设置细解
- [10174]WINDOWS 7 如何快...