note

レスポンシブイメージjs改

前回作ったレスポンシブイメージjsを改修した際のメモ。

jqueryはどうしても読み込みに時間がかかり、画像リクエスト発生前に実行させるのが難しそうなので、jsネイティブに変更。
pc画面サイズの場合は、DOM読み込み直後にsrcのパスを削除して画像リクエスト発生前にpc画像のパスへ置換する流れ。
外部ファイルにすると画像リクエスト発生前のsrcパス削除が間に合わないため、DOM読み込み直後に実行したい処理だけをbody閉じタグ前に直接記述し、それ以降の処理を外部ファイルに。
ローカル環境でのテストで、firefoxのみ画像リクエスト発生前のパス置換に成功。chromeとIEはどうしても置換前に画像が読み込まれてしまう。記述場所を変えてみてもリクエスト発生前のsrc書き換えができない。
やはり、lazyloadのようにsrcは空にして後からjsで書き換える処理でないと無理のようです。
以下、今回テストで作成したコードです。

html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>Document</title>
<style>
img {
  max-width: 100%;
  height: auto;
}
/* page loading (jsと連動)*/
body::before {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  display: block;
  width: 100%;
  height: 100%;
  height: 100vh;
  background: #fff;
  opacity: 1;
}
@keyframes endLoading {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
body::after {
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: 9999;
  display: block;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  -webkit-transform: translateX(-50%) translateY(-50%);
  transform: translateX(-50%) translateY(-50%);
  border: 4px solid #005BAC;
  border-left-color: transparent;
  -webkit-animation: isLoading 1s infinite linear;
  animation: isLoading 1s infinite linear;
}
@-webkit-keyframes isLoading {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes isLoading {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
body:not(.is-loading)::before,
body:not(.is-loading)::after {
  pointer-events: none;
  -webkit-animation: endLoading 0.5s linear forwards;
  animation: endLoading 0.5s linear 0s forwards;
}
</style>
</head>
<body id="pagetop" class="is-loading">
<a href="#sp" data-responsive="#pc" class="js-responsive"><img src="./images/dummy-640x853.png" data-responsive="./images/dummy-768x576.png" class="js-responsive" alt="hoge"></a>
<br>
<br>
<img src="./images/dummy-sp.png" data-responsive="./images/dummy-pc.png" class="js-responsive" alt="fuga">

<script>
'use strict';
var isSpWidth = window.matchMedia('(max-width: 767px)');
var isPcWidth = window.matchMedia('(min-width: 768px)');
var $imgElms = document.querySelectorAll('img.js-responsive');
if (isPcWidth.matches) {
    for (var i = 0; i < $imgElms.length; i++) {
        $imgElms[i].src = '';
    }
    document.write('<style type="text/css" id="stylePageLoading">body::before,body::after{content:"";}</style>');
}
</script>
<script src="./js/rp.js"></script>
</body>
</html>
rp.js
document.addEventListener('DOMContentLoaded', function() {
    var isDevice = 0; // sp:0,pc:1
    changeResponsiveDisp();

    window.addEventListener('resize', function (event) {
        if((isSpWidth.matches && isDevice != 0) || (isPcWidth.matches && isDevice != 1) ) {
            location.href = location.href.split('#')[0]; // デバイス変更されたらリロード
        }
    });

    function changeResponsiveDisp() {
        var $rpElems = document.getElementsByClassName('js-responsive');
        if(isPcWidth.matches && isDevice != 1) { // pc表示
            isDevice = 1;
            for( var i=0; i < $rpElems.length; i++) {
                var $this = $rpElems[i];
                var data = $this.getAttribute('data-responsive');
                if(data) { // data-responsive 値あり (secまたはhrefdata値に置換)
                    if($this.tagName == 'IMG') {
                        $this.src = data;
                    }
                    if($this.tagName == 'A') {
                        $this.href = data;
                    }
                }
                if(i == $rpElems.length - 1 ){
                    endLoading();
                }
            }
        }
    }

    // end loading
    function endLoading() {
        var $body = document.getElementsByTagName('body');
        $body[0].classList.remove('is-loading');
        setTimeout(function() {
            var $stylePageLoading = document.getElementById('stylePageLoading');
            $stylePageLoading.parentNode.removeChild($stylePageLoading);
        }, 1000);
    }
    setTimeout(function() {
        if(isPcWidth.matches && document.querySelector('body.is-loading') != null) {
            endLoading();
        }
    }, 3000);
});