// import DOM from './data/domData'; import { smoothOffset } from './data/stateData'; /** * スムーススクロール関数 * * @param target スクロール位置となる対象要素 * @param offset ヘッダーの高さなど、ターゲット座標の調整値 * @param divisor 近づく割合(数値が大きいほどゆっくり近く) */ export function smoothScroll( target, offset, divisor ) { divisor = divisor || 12; let toY; let nowY = window.pageYOffset; //現在のスクロール値 const range = divisor / 2 + 1; //どこまで近づけば処理を終了するか(無限ループにならないように divisor から算出) //ターゲットの座標 const targetRect = target.getBoundingClientRect(); //ターゲットの座標取得 const targetY = targetRect.top + nowY - offset; //現在のスクロール値 & ヘッダーの高さを踏まえた座標 //スクロール終了まで繰り返す処理 const loopFunc = () => { toY = nowY + Math.round( ( targetY - nowY ) / divisor ); //次に移動する場所(近く割合は除数による。) window.scrollTo( 0, toY ); //スクロールさせる nowY = toY; //nowY更新 if ( document.body.clientHeight - window.innerHeight < toY ) { //最下部にスクロールしても対象まで届かない場合は下限までスクロールして強制終了 window.scrollTo( 0, document.body.clientHeight ); return; } if ( toY >= targetY + range || toY <= targetY - range ) { //+-rangeの範囲内へ近くまで繰り返す window.setTimeout( loopFunc, 10 ); } else { //+-range の範囲内にくれば正確な値へ移動して終了。 window.scrollTo( 0, targetY ); } }; loopFunc(); //初回実行; } /** * スムーススクロールイベントを登録する * * @param {*} dom #付きリンクを検索する親要素 */ export function addSmoothScrollEvent( dom ) { const root = dom || document; const linkElems = root.querySelectorAll( 'a[href*="#"]' ); for ( let i = 0; i < linkElems.length; i++ ) { linkElems[ i ].addEventListener( 'click', function ( e ) { const href = e.currentTarget.getAttribute( 'href' ); // href取得 const splitHref = href.split( '#' ); const targetID = splitHref[ 1 ]; const target = document.getElementById( targetID ); // リンク先の要素(ターゲット)取得 if ( target ) { // e.preventDefault(); smoothScroll( target, smoothOffset ); // スマホメニューが開いていれば閉じる document.documentElement.setAttribute( 'data-drawer', 'closed' ); // 目次メニューが開いていれば閉じる // const indexModal = DOM.indexModal; // if (null !== indexModal && indexModal.classList.contains('is-open')) { // indexModal.classList.remove('is-open'); // } } else { return true; } return false; } ); } }