Javascriptにて、ある要素が表示されたらとある画像を表示する、という動作をしたいのですが、スクロールされていって表示されたら画像を読み込む、というサンプルコードを教えて下さい。

要素はDIVなどのIDを指定するイメージです。
よろしくお願い致します。

回答の条件
  • 1人1回まで
  • 13歳以上
  • 登録:2016/03/12 21:15:36
  • 終了:2016/03/13 19:04:47

ベストアンサー

id:a-kuma3 No.1

a-kuma3回答回数4325ベストアンサー獲得回数17732016/03/13 01:37:35

ポイント300pt

こんな感じでしょうか。

<script>
window.addEventListener("load", function() {
    function display_image_lazy() {
        Array.from(document.body.querySelectorAll("[data-image]")).forEach(function(e) {
            var y1 = window.innerHeight;
            var y2 = e.getBoundingClientRect().top;
            if (y2 <= y1) {
                if (e.dataset.image) {
                    var img = document.createElement("img");
                    img.src = e.dataset.image;
                    e.parentNode.insertBefore(img, e.nextSibling);
                    e.dataset.image = "";
                }
            }
        });
    }
    display_image_lazy();
    window.addEventListener("scroll", display_image_lazy, false);
}, false);
</script>

要素が表示されたときの画像は、data-image 属性で指定します。

...
<div data-image="/img/foo.jpg">foo</div>
...
<div data-image="/img/bar.jpg">bar</div>

data-image 属性を持つ要素が表示されたときに data-image 属性で指定された URL の IMG 要素をその直後に挿入するようにしました。
こういった感じの方がメンテナンス性が良いと思いますが、要素の ID と画像の対応をスクリプトに持っていたいのであれば、こんな感じになります。

<script>
window.addEventListener("load", function() {
    // 要素の ID と画像の URL の対応
    var image_map = {
        "foo" : "/img/foo.jpg",
        "bar" : "/img/bar.jpg",
    };
    function disp_image_lazy() {
        Array.from(document.body.querySelectorAll(".lazy_image")).forEach(function(e) {
            var y1 = window.innerHeight;
            var y2 = e.getBoundingClientRect().top;
            if (y2 <= y1) {
                if (image_map[e.id]) {
                    var img = document.createElement("img");
                    img.src = image_map[e.id];
                    e.parentNode.insertBefore(img, e.nextSibling);
                    delete image_map[e.id];
                }
            }
        });
    }
    disp_image_lazy();
    window.addEventListener("scroll", disp_image_lazy, false);
}, false);
</script>

画像が表示される要素はクラスで "lazy_image" が指定されているものにしています。
タグの様な緩い指定だと遅くなりそうなので。

...
<div class="lazy_image" id="foo">foo</div>
...
<div class="lazy_image" id="bar">bar</div>
他1件のコメントを見る
id:a-kuma3

「とあるIDの要素が見えたら」は、とある ID を "foo" とした場合、こうなります。

<script>
window.addEventListener("load", function() {
    // とある要素が見えてるかどうかを判定して処理をする
    function display_image_lazy() {
        //                                          ↓とある ID
        Array.from(document.body.querySelectorAll("#foo")).forEach(function(e) {
            var y1 = window.innerHeight;
            var y2 = e.getBoundingClientRect().top;
            if (y2 <= y1) {

                ★ ここに、見えたときの処理

            }
        });
    }

    // いきなり見えていることもあるので、最初に呼んでおく
    display_image_lazy();

    // スクロールしたときのイベントで、毎回見えているかどうかを判定する
    window.addEventListener("scroll", display_image_lazy, false);

}, false);
</script>

上記のコードでは、とある要素のIDが見えたときに、何度も実行されます。
多分、最初に見えたときだけ実行、というような処理は必要になると思います。

2016/03/13 18:25:13
id:iori753

ありがとうございますm(__)m

2016/03/13 19:04:27

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません