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の場合

f:id:a2h1r0:20200420103931p:plain

デバッグOFFの場合

f:id:a2h1r0:20200420104057p:plain

という感じ.

ここでわかること

どんな書き方でも,#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);

f:id:a2h1r0:20200420104952p:plain

つまり

.styleを使った要素の変更,追加がうまくいかない. .styleを使わずに.setAttributeを使うことで回避できた感じ. よく見ると,.getAttributeの方もnullで他と違うね.

参考サイト様

qiita.com