アンカースクロールで、position:fixed
する要素の分の高さをスクロール量から差し引いたりその他調整的なごにょごにょをする中で不都合が出てきました。
- jQuery使用
position:fixed
する要素の分の高さを各処理の関数に持ち回りたい- この高さの値はブラウザ幅によって変動(中のコンテンツが回り込むため)
resize
イベントで更新したい
position:fixed
は固定で付与されるわけではなく、ある程度スクロールしたら画面上部にくっつく- クラスが付与されたら更新したい(jQueryにカスタムイベントを追加して解決)
- この高さの値はブラウザ幅によって変動(中のコンテンツが回り込むため)
この条件を解決する手段として、「PHPで引数の先頭に&
付けて参照渡しするのと同じことができれば」と思いました。
が、ググってもJSに関しては情報が見当たりません。どうもおかしいと思ったところ、
……え、ないの?
正確にはプリミティブ型は値渡し、オブジェクト型は参照渡しという仕様のようです。
今回は、「position:fixed
する要素の分の高さ」という整数値を与えたかったのですが、このままだと値渡しになってしまう。
処理を分割した関数に渡すと、resize
やクラス付与のイベント毎に更新される値は、関数内までは反映されないわけです。
逆に言えば、オブジェクト型ならば自動的に参照渡しになるわけです。
そのため、無理やり配列にして渡すという力業で解決しました。概略としては以下のようなイメージ。
$(function() {
var navbarHeight = [0]; //参照渡しするため、配列の0番目の要素に初期値0をセット
var $navbar = $("#navbar");
navbarHeight[0] = $navbar.innerHeight(); //高さ取得
//クラス付与のタイミングで高さ再取得する処理
//スクロール量に応じて`position:fixed`を付与・削除
anchorFix(navbarHeight); //実行(配列型のnavbarHeightを渡すことで参照渡しにしてresizeイベントで更新されるグローバル変数と連動させる)
//スクロール対象を取得
var screlm = scrollElm();
//ページ内スクロール
pageScroll(screlm, navbarHeight);
$(window).on("resize", function() { //リサイズされると処理
var timer = false;
var time = 300; //0.3秒
if (timer !== false) { //timerがfalseでない場合は処理せずキューをクリア
clearTimeout(timer);
}
if(ifProductPage()) { //メーカーリストページの場合
timer = setTimeout(function() { //falseならば発火
navbarHeight[0] = $navbar.innerHeight(); //高さ再取得
}, time);
}
});
});
//スクロール対象を取得
function scrollElm() {
//処理
}
//上部固定
function anchorFix(navbarHeight) {
//処理
//※ここでresizeやクラス付与イベント毎に変わるnavbarHeightを使いたい
}
うーん、無理やり頑張ってる感が滲み出ていますね……。