【STINGER5】サイドバーのスクロール広告が消える!ズレる時の対処法と解説【WordPress】
当サイト「はぴすぷ」ではWordPressのテーマ「STINGER5」を使っています。
自分で色々と手を加えていく内に、サイドバーのスクロールしても付いてくるコンテンツが、思った位置に止まってくれなくなっていることに気づきました。
原因を探るべく、それっぽいものを削除していくと、どうやら一番下に付けていたA8.netのローテーションバナーが原因のようです。
まぁ、外せば直るんですが、外したくはない…。
というわけで解決方法を探しました!
スポンサーリンク
有力そうなサイトが2つ見つかる
どちらもコピペするだけですぐに解決できそう!良かった!
今日のブログのネタはコレでサクッと終わらせよう(^q^)
そう思って取りかかりました。
まずは1つ目
手を入れる箇所が3行程と少ないので、先にこちらを参考にさせてトライしてみました。
広告収益効果もアップ!wordpressのSTINGER5でサイドバーが消える問題を解決するには
試してみると、記事の途中なのにサイドバーの一番下の広告が画面の下端に貼りつくようになりました…。
まず、参考にしたサイトのサイドバーが動いてなかった(´・ω・`)
何かエラー出てて、scrolladのdivに色塗ったりして動かしてみるも、付いて来ませんでした。
ちくしょう(´ε`;)
というわけで次!
2つ目の解決策
こっちは結構いじっているのか、変更箇所は載っていなくて、全文コピーして置き換えてねと言うこと!
【Stinger5】スクロール広告がずれるのを改善しよう【プラグイン不要】
怖いのでバックアップは取っておいて、さっそくコピペして上書きして保存!
そして画面を更新っと!
なんじゃこりゃあああ!!
サイドバーがえらいとこに表示されてスクロールも変な感じに動く…。
しかし、参考にしているサイトのサイドバーはちゃんと機能している…。
ん?何か書いている。
僕の場合はこれだけで解決しましたが
どうしても解決しないという場合はプラグインで対応しましょう。
Q2W3 Fixed Widget
Standard Widget Extension
どちらかを使えば良い感じに固定できるでしょう。Q2W3 Fixed Widgetがおすすめです。
記事の終わりにこう書いてるし、もしかしたらプラグイン使うようにしたのかな…?
一応、ソースを覗いてみる。
記事の内容の「scroll.js」を使っていそうな感じ。
どうしようかな…。あんまりプラグインは入れたくない…。
勉強の為に自分で何とかする
一応今回のサイドバーがうまく動かないのは、「STINGER5」に内蔵されている「js/scroll.js」が原因です。
ファイルを開いてみると分かりますが、こちらの方が作成したものをほぼそのまま取り込んでいます。
ライブドアみたいにスクロールしたらサイドバーの広告を固定する
とりあえず、何をしているかソースを追いつつ考える。
CSS分からん…。辛い…。
苦戦すること半日程!何とか謎が解けました!
対応すること
サイドバーや、スクロール広告の高さを監視して、変化があれば吸収してあげる。
何でそんなことをしないといけないかと言うと。
本来jQueryは画面が準備出来たよ!っていうタイミングで実行されるので自分のサイト内で完結する場合は問題ないことが多いです。
ですが、広告とかSNS連携ボタンというのは、同じくらいのタイミングで外部サイトにファイル取りに行って、それから作り始めます。
つまり「scroll.js」の初期処理が始まる時には、まだ広告等の準備が出来てないので、その高さ分だけズレたりします。
なので、「scroll.js」でスクロールを検知するタイミングで、変化があったかをチェックして反映してあげます。
対応したソースコード
こちらをコピペしてもらうか、GitHubのページからダウンロードして下さい。
分かりやすいかはあれですが、コメントかなり足しておいたので少しは理解しやすくなるかなと!
/*-------------------------------- 広告のフロート -------------------------------*/ // jQueryの開始方法を変更 $(function() { /* Ads Sidewinder by Hamachiya2. http://d.hatena.ne.jp/Hamachiya2/20120820/adsense_sidewinder */ var main = $('main'); // メインカラムのID var side = $('#side aside'); // サイドバーのID var wrapper = $('#scrollad'); // 広告を包む要素のID // 要素がなければ何もしない if (main.length === 0 || side.length === 0 || wrapper.length === 0) { return; } var w = $(window); var wrapperHeight = wrapper.outerHeight(); var wrapperTop = wrapper.offset().top; var sideHeight = side.outerHeight(); var sideTop = side.offset().top; var sideLeft = side.offset().left; var sideMargin = { top: side.css('margin-top') || 0, right: side.css('margin-right') || 0, bottom: side.css('margin-bottom') || 0, left: side.css('margin-left') || 0 }; var winLeft; var pos; var scrollAdjust = function() { // サイドバーかスクロール広告の高さが変わっていたら更新する // 広告が浮いてる状態で高さが更新されるとwrapperTopにズレが発生する可能性あり if (sideHeight != side.outerHeight() || wrapperHeight != wrapper.outerHeight()) { sideHeight = side.outerHeight(); wrapperHeight = wrapper.outerHeight(); wrapperTop = wrapper.offset().top; } var mainHeight = main.outerHeight(); var mainAbs = main.offset().top + mainHeight; var winTop = w.scrollTop(); winLeft = w.scrollLeft(); var winHeight = w.height(); // スクロール広告の頭が画面上部からはみ出そうで、メインコンテンツがサイドバーが長い=広告を浮かす必要がある var nf = (winTop > wrapperTop) && (mainHeight > sideHeight) ? true : false; // スクロール広告の頭からサイドバーが終わるまでの高さ var wrapperTop2SideBottomHeight = sideHeight - (wrapperTop - sideTop); /** * 浮かす必要が無いならstaticでそのまま。 * 画面上部の高さ+広告以下の高さを合わせて、コンテンツの高さを超えるならabsoluteで終端を揃える。 * それ以外はfixedで広告の頭を固定で浮かして表示する。 */ pos = !nf ? 'static' : (winTop + wrapperTop2SideBottomHeight) > mainAbs ? 'absolute' : 'fixed'; if (pos === 'fixed') { /** * スクロール広告の下にコンテンツ置いても大丈夫なように上基準に変更 * 広告の頭が画面上部に合うように引っ張り上げる。 * サイドバーが開始する高さまでは除去しないとずれる。 */ side.css({ position: pos, top: sideTop - wrapperTop, bottom: '', left: sideLeft - winLeft, margin: 0 }); } else if (pos === 'absolute') { side.css({ position: pos, top: mainAbs - sideHeight, bottom: '', left: sideLeft, margin: 0 }); } else { side.css({ position: pos, marginTop: sideMargin.top, marginRight: sideMargin.right, marginBottom: sideMargin.bottom, marginLeft: sideMargin.left }); // ずれた時の為に、通常の領域に戻った時に再調整する wrapperTop = wrapper.offset().top; } }; var resizeAdjust = function() { side.css({ position:'static', marginTop: sideMargin.top, marginRight: sideMargin.right, marginBottom: sideMargin.bottom, marginLeft: sideMargin.left }); sideLeft = side.offset().left; winLeft = w.scrollLeft(); if (pos === 'fixed') { side.css({ position: pos, left: sideLeft - winLeft, margin: 0 }); } else if (pos === 'absolute') { side.css({ position: pos, left: sideLeft, margin: 0 }); } }; w.on('load', scrollAdjust); w.on('scroll', scrollAdjust); w.on('resize', resizeAdjust); });
変更した点
インデントのせいで全文いじってます(^q^)
- インデントが5スペースだったので4スペースに置き換え
- jQueryの開始コードをシンプルにしてインデント1段減らす
- 三項演算子で冗長だった部分を||の短絡評価に置き換え(JSLintがやれっていうので!)
- いくつかグローバル変数になってたのを修正
- スクロール時に高さの監視と吸収
- スクロール広告の下に他の要素置いても大丈夫なように上基準で浮かすように変更
- 浮いてる時に高さが変わるとズレる可能性があるので、上部まで戻れば直るように保険をかける
差分が分かりやすく確認できるようにGitHub上に履歴残してあります。気になる人は見てみて下さい。
実は2つ目に紹介した方法と大体は同じ
後から確認してみると、変数の持ち方や、高さの測定・計算の仕方などで違いはありますが、大体同じようなことをしていました。
浮いてる時に更新した時にズレるかもしれないな~と思っていたので、保険かけてるっぽい所は参考にさせてもらいました。
同じようなことしてるのに何で、最初にあんなおかしなことになったのかですが、以下が原因でした。
var side = jQuery('#side aside'); // サイドバーのID
これの「#side」が付いて無かったんです。
最新?の「STINGER5」だと、投稿ページに<aside>タグが2つ存在します。
なので、サイドバーの<aside>タグだけが対象にならずバグっていました…。
終わりに
これで広告を載せても、正しく表示されるようになりました!
「はぴすぷ」では、サイドバーでスクロールしても付いてくる広告枠でランキング上位記事を表示するようにしています。
それが見出しと1位~2位が隠れちゃって、何のリストか分からない状態だったので早めに直せて良かったです。
さくっと終わらせるつもりが、かなり時間かかってしまった!
次に困る誰かの役に立てば幸いです。それでは。