スクロール位置を固定するJavaScriptサンプル

クライアントの要望

  • ボタンクリックで同一画面内の下部にあるコンテンツまでスクロールさせたい(スマホ対応したいのでFlash禁止)
  • ブラウザのウィンドウサイズに関係なく、下部のコンテンツが縦横ともに中央に来るようにしたい
  • ブラウザのズーム率(IEでいうフォントサイズ、Firefoxでいうズーム)に関係なくスクロール位置を固定したい
  • あらゆるブラウザ(特にスマホ)に対応したい

という要望を受けて作ったコードの備忘録です。けっこうベタ書きしたので、ちょっと無駄な部分もあります。

実際に作ったJavaScriptのコード

[javascript] var scroller = {
scrollstep : 1,

setMarginTop : function() {
var ta = document.getElementById(“topEnter”);
var myh = (this.getBrowserHeight() – $(“div#topEnter”).height()) / 2;
if ( myh & 20 ) {
myh = 20;
}
var mycss = “position: relative; top: ” + myh + “px; margin: 0 auto; clear: both; width: 900px; height: 650px;”;
if (window.navigator.userAgent.indexOf(“MSIE 7”) == -1) {
ta.style.cssText = mycss;
}
},

setOnClickHandler : function() {
var links = document.links;
for(var i = 0; i & links.length; i++) {
var link = links[i];
var currentUrl = location.href.split(‘#’);
var splitLinkHref = link.href.split(‘#’);
if(currentUrl[0] == splitLinkHref[0] && document.getElementById(splitLinkHref[1])){
this.addEvent(link, ‘click’, this.scrollTgt);
}
}
},

addEvent : function(eventTarget, eventName, func) {
if(eventTarget.addEventListener) {
eventTarget.addEventListener(eventName, func, false);
}else if(window.attachEvent) {
eventTarget.attachEvent(‘on’+eventName, function() {func.apply(eventTarget);});
}
},

getBrowserWidth : function() {
if (window.navigator.userAgent.indexOf(“MSIE 7”) 0) {
return document.documentElement.clientWidth * document.documentElement.clientWidth / document.documentElement.scrollWidth;
} else if (window.innerWidth) {
return window.innerWidth;
} else if (document.documentElement && document.documentElement.clientWidth != 0) {
return document.documentElement.clientWidth;
} else if (document.body) {
return document.body.clientWidth;
}
return 0;
},

getBrowserHeight : function() {
if (window.navigator.userAgent.indexOf(“MSIE 7”) 0) {
return document.documentElement.clientHeight * document.documentElement.clientWidth / document.documentElement.scrollWidth;
} else if (window.innerHeight) {
return window.innerHeight;
} else if (document.documentElement && document.documentElement.clientHeight != 0) {
return document.documentElement.clientHeight;
} else if ( document.body ) {
return document.body.clientHeight;
}
return 0;
},

scrollTgt : function(event) {
if(event){
event.preventDefault();
} else if(window.event){
window.event.returnValue = false;
}
var posx = $(“div#container1”).offset().left – (scroller.getBrowserWidth() – $(“div#container1”).width()) / 2;
var posy = $(“div#container1”).offset().top – (scroller.getBrowserHeight() – $(“div#container1”).height()) / 2;
var recmax = 36000 / scroller.getBrowserHeight();
if (recmax 120) {
var recnum = 120;
} else if (recmax 50) {
var recnum = recmax;
} else {
var recnum = 50;
}
scroller.scrollRec(posx, posy, recnum);
},

scrollRec : function(posx, posy, recnum) {
var mvx = posx – (document.documentElement.scrollLeft || document.body.scrollLeft);
var mvy = posy – (document.documentElement.scrollTop || document.body.scrollTop);
var mvxabs = Math.abs(mvx);
var mvyabs = Math.abs(mvy);
if(this.scrollstep & recnum && mvxabs = 0 && mvyabs = 0) {
if(mvxabs 2) {
mvx = Math.ceil(mvx / 8);
} else if(mvx & 0) {
mvx = -1;
} else {
mvx = 1;
}
if(mvyabs 2) {
mvy = Math.ceil(mvy / 8);
} else if(mvy & 0) {
mvy = -1;
} else {
mvy = 1;
}
this.scrollstep++;
scrollBy(mvx, mvy);
setTimeout(“scroller.scrollRec(” + posx + “, ” + posy + “, ” + recnum + “)”,10);
} else {
this.scrollstep = 1;
//scrollTo(posx, posy);
}
}
}
window.onload = function() {
scroller.setMarginTop();
scroller.setOnClickHandler();
}

jQuery(document).ready(function() {
jQuery(‘#mycarousel’).jcarousel({
vertical: true,
scroll: 2
});
});

$(window).load(function() {
$(‘#slider’).nivoSlider({
effect:’fade’,
slices:5,
animSpeed:500, //画像が切り替わるスピード
pauseTime:3000, //画像が切り替わるまでの時間
keyboardNav:true, //Use left & right arrows
pauseOnHover:true, //オンマウスで画像が止まる
manualAdvance:false, //Force manual transitions
captionOpacity:0.8, //Universal caption opacity
beforeChange: function(){},
afterChange: function(){},
slideshowEnd: function(){}
});
});
[/javascript]