WordPressでJavascriptのstyle.marginTopが動かない
1行のために数時間使った
まずは該当コード
<?php // YouTube埋め込み ?> <?php if (!empty($data_list['youtube'][0])) { // URLから動画IDのみ抽出 $videoId = ltrim($data_list['youtube'][0], 'https://youtu.be/'); ?> <?php // 幅取得用 ?> <div id='get-width'></div> <?php // 提供元 ?> <div id='presented-by'> <a href="https://www.hogehoge.com/" data-lightbox="group"><img src="hogehoge.png"></a> </div> <!-- 1. The <iframe> (and video player) will replace this <div> tag. --> <div id='youtube'></div> <script> //*** 動画のアスペクト比 ***// var aspectWidth = 16, aspectHeight = 9; jQuery(function ($) { $('#presented-by').hide(); }); // 動画の横幅は100%で比率に合わせて表示 var youtubeWidth = document.getElementById('get-width').clientWidth, youtubeHeight = (youtubeWidth/aspectWidth) * aspectHeight; // 提供元の表示位置を中央に調整 var presentedBy = document.getElementById('presented-by'); presentedBy.style.marginTop = youtubeHeight/2 - presentedBy.clientHeight/2; // 2. This code loads the IFrame Player API code asynchronously. var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // 3. This function creates an <iframe> (and YouTube player) // after the API code downloads. var player; var videoId = <?php echo json_encode($videoId); ?>; function onYouTubeIframeAPIReady() { player = new YT.Player('youtube', { width: youtubeWidth, height: youtubeHeight, videoId: videoId, events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); } // 4. The API will call this function when the video player is ready. function onPlayerReady(event) { event.target.playVideo(); } // 5. The API calls this function when the player's state changes. // The function indicates that when playing a video (state=1), // the player should play for six seconds and then stop. var done = false; function onPlayerStateChange(event) { // 動画終了後と一時停止中に画像を表示 var status = player.getPlayerState(); if (status == 0 || status == 2) { jQuery(function ($) { $('#presented-by').fadeIn(1000); }); } else { jQuery(function ($) { $('#presented-by').fadeOut(1000); }); } } </script> <?php } ?>
の中の
presentedBy.style.marginTop = youtubeHeight/2 - presentedBy.clientHeight/2;
この1行.
これがどーしても動かない.
いや,動かないだけならデバッグしろよって話なんですが
謎1
WordPressで設計しているのですが,デバッグをtrueにすると動く.falseでは動かない.
謎2
console.log(presentedBy.style.marginTop);
とかしてみると,デバッグをONにすると動くということで,もちろん値が返ってくる. しかし,OFFにすると,値が空('')で返ってくる.
予想と結果
デバッグモード入れたら動く&値が取れてないっぽいということは,何かしらの読み込み順の問題?
→ BJ Lazy Loadという読み込み遅延系のプラグインを入れてたこともあり,とりあえず全てのプラグインを無効化
結果:無駄
WordPress全体のデバッグは外して,Javascriptのみデバッグを入れてみる(使ったことないから合ってるかは知らない)
→ define('SCRIPT_DEBUG', true);を追記
結果:無駄
さらにログを見る
もちろん,なんのエラーも出ていない.空が取得されているので,要素も定義済み.
var presentedBy = document.getElementById('presented-by'); presentedBy.style.marginTop = youtubeHeight/2 - presentedBy.clientHeight/2; console.log(presentedBy.style.marginTop); style = presentedBy.getAttribute('style'); console.log(style); cssText = presentedBy.style.cssText; console.log(cssText);
こんなのを書いてみる.
デバッグONの場合
デバッグOFFの場合
という感じ.
ここでわかること
どんな書き方でも,#presented-by要素のstyleが空になってる.
解決策
var presentedBy = document.getElementById('presented-by'); presentedBy.setAttribute('style', 'margin-top: 100px;'); console.log(presentedBy.style.marginTop);
これで動く.
もうちょっと見てみる
var presentedBy = document.getElementById('presented-by'); presentedBy.style.marginTop = youtubeHeight/2 - presentedBy.clientHeight/2; console.log(presentedBy.style.marginTop); cssText = presentedBy.style.cssText; console.log(cssText); presentedBy.setAttribute('style', 'margin-top: 100px;'); console.log(presentedBy.style.marginTop); style = presentedBy.getAttribute('style'); console.log(style);
つまり
.styleを使った要素の変更,追加がうまくいかない. .styleを使わずに.setAttributeを使うことで回避できた感じ. よく見ると,.getAttributeの方もnullで他と違うね.