// UTF-8/** * scrollsmoothly.js * Copyright (c) 2008 KAZUMiX * http://d.hatena.ne.jp/KAZUMiX/20080418/scrollsmoothly * Licensed under the MIT License: * http://www.opensource.org/licenses/mit-license.php *  * 更新履歴 * 2009/02/12 * スクロール先が画面左上にならない場合の挙動を修正 * 2008/04/18 * 公開 **/(function(){   var easing = 0.25;   var interval = 20;   var d = document;   var targetX = 0;   var targetY = 0;   var targetHash = '';   var scrolling = false;   var splitHref = location.href.split('#');   var currentHref_WOHash = splitHref[0];   var incomingHash = splitHref[1];   var prevX = null;   var prevY = null;   // ドキュメント読み込み完了時にinit()を実行する   addEvent(window, 'load', init);   // ドキュメント読み込み完了時の処理   function init(){     // ページ内リンクにイベントを設定する     setOnClickHandler();     // 外部からページ内リンク付きで呼び出された場合     if(incomingHash){       if(window.attachEvent && !window.opera){         // IEの場合はちょっと待ってからスクロール         setTimeout(function(){scrollTo(0,0);setScroll('#'+incomingHash);},50);       }else{         // IE以外はそのままGO         scrollTo(0, 0);         setScroll('#'+incomingHash);       }     }   }   // イベントを追加する関数   function addEvent(eventTarget, eventName, func){     if(eventTarget.addEventListener){       // モダンブラウザ       eventTarget.addEventListener(eventName, func, false);     }else if(window.attachEvent){       // IE       eventTarget.attachEvent('on'+eventName, function(){func.apply(eventTarget);});     }   }      function setOnClickHandler(){     var links = d.links;     for(var i=0; i<links.length; i++){       // ページ内リンクならスクロールさせる       var link = links[i];       var splitLinkHref = link.href.split('#');       if(currentHref_WOHash == splitLinkHref[0] && d.getElementById(splitLinkHref[1])){         addEvent(link, 'click', startScroll);       }     }   }   function startScroll(event){     // リンクのデフォルト動作を殺す     if(event){ // モダンブラウザ       event.preventDefault();       //alert('modern');     }else if(window.event){ // IE       window.event.returnValue = false;       //alert('ie');     }     // thisは呼び出し元になってる     setScroll(this.hash);   }   function setScroll(hash){     // ハッシュからターゲット要素の座標をゲットする     var targetEle = d.getElementById(hash.substr(1));     if(!targetEle)return;     //alert(scrollSize.height);     // スクロール先座標をセットする     var ele = targetEle;     var x = 0;     var y = 0;     while(ele){       x += ele.offsetLeft;       y += ele.offsetTop;       ele = ele.offsetParent;     }     var maxScroll = getScrollMaxXY();     targetX = Math.min(x, maxScroll.x);     targetY = Math.min(y, maxScroll.y);     targetHash = hash;     // スクロール停止中ならスクロール開始     if(!scrolling){       scrolling = true;       scroll();     }   }   function scroll(){     var currentX = d.documentElement.scrollLeft||d.body.scrollLeft;     var currentY = d.documentElement.scrollTop||d.body.scrollTop;     var vx = (targetX - currentX) * easing;     var vy = (targetY - currentY) * easing;     var nextX = currentX + vx;     var nextY = currentY + vy;     if((Math.abs(vx) < 1 && Math.abs(vy) < 1)       || (prevX === currentX && prevY === currentY)){       // 目標座標付近に到達していたら終了       scrollTo(targetX, targetY);       scrolling = false;       location.hash = targetHash;       prevX = prevY = null;       return;     }else{       // 繰り返し       scrollTo(parseInt(nextX), parseInt(nextY));       prevX = currentX;       prevY = currentY;       setTimeout(function(){scroll()},interval);     }   }      function getDocumentSize(){     return {width:Math.max(document.body.scrollWidth, document.documentElement.scrollWidth), height:Math.max(document.body.scrollHeight, document.documentElement.scrollHeight)};   }   function getWindowSize(){     var result = {};     if(window.innerWidth){       var box = d.createElement('div');       with(box.style){         position = 'absolute';         top = '0px';         left = '0px';         width = '100%';         height = '100%';         margin = '0px';         padding = '0px';         border = 'none';         visibility = 'hidden';       }       d.body.appendChild(box);       var width = box.offsetWidth;       var height = box.offsetHeight;       d.body.removeChild(box);       result = {width:width, height:height};     }else{       result = {width:d.documentElement.clientWidth || d.body.clientWidth, height:d.documentElement.clientHeight || d.body.clientHeight};     }     return result;   }      function getScrollMaxXY() {     if(window.scrollMaxX && window.scrollMaxY){       return {x:window.scrollMaxX, y:window.scrollMaxY};     }     var documentSize = getDocumentSize();     var windowSize = getWindowSize();     return {x:documentSize.width - windowSize.width, y:documentSize.height - windowSize.height};   }    }());
