5

背景画像を持つ div がいくつかあります。背景画像の一部は非常に大きいため、これらの背景画像をgif画像でプリロードする方法を知りたいです。以下を実行しても機能しません。

HTML:

<div id="glykopeels" onload="loadImage()">Glykopeels Content</div>
<div id="facials" onload="loadImage2()">Facials Content</div>

CSS:

#glykopeels{
        background: #ebebeb url(http://lamininbeauty.co.za/images/products/preloader.gif) no-repeat top right;
        background-size: contain;
    }
#facials{
    background: #ebebeb url(http://lamininbeauty.co.za/images/products/preloader.gif) no-repeat top right;
    background-size: contain;
    }

JS:

function loadImage(){
        document.getElementById('glykopeels').style.background = '#ebebeb url(http://lamininbeauty.co.za/images/products/glykopeel.jpg);';
    }
function loadImage2(){
        document.getElementById('facials').style.background = '#ebebeb url(http://lamininbeauty.co.za/images/products/facial.jpg);';
    }

onload 関数でその要素に別の ID を定義し、その新しい ID に css を定義することも別の可能性だと思いますか? したがって、onload 関数内のその要素の id のみを変更しますか?

ありがとうございました

4

3 に答える 3

5

まず、div の onload 属性はありません。編集:以下のコメントをお読みください。非常に興味深いです!

次に、引用符の間に URL を配置する必要があります (必要に応じてエスケープします)。url('http://lamininbeauty.co.za/images/products/facial.jpg')

3 つ目は、というイメージはpreloader.gifありませんでしたが、 というイメージがあったloader.gifため、それを使用して、一番下の jsfiddle デモ リンクでソリューションの css 部分を「修正」しました。

SO のサーバー移動中に、私はあなたが望むことを正確に実行する簡単なカスタム関数を作成しました。IE6および FF12
でテスト済み。
これをテストするには: ブラウザのバッファをクリアしてください。そうしないと、実際の動作を確認できません (処理速度が速すぎます)。これは、画像が 2 回目のビューでバッファリングされる可能性があるためです (これも目標に最適です)。

JavaScript:

var repBg=function(a, t){ t=t||'*';  // by GitaarLAB
        var c=document.getElementsByTagName(t), i=c.length, r=[];
        while(i--){if (c[i].getAttribute(a)){r.push(c[i]);}} c=r; i=c.length;
        repBg.exec=function(){
            c[this['data-i']].style.background="#ebebeb url('"+this.src+"') no-repeat top right";
        };
        while(i--){ if (c[i].getAttribute(a)) {
            r=new Image();
            r.onload=repBg.exec;
            r['data-i']=i;
            r.src=c[i].getAttribute(a);
        }}  
};

// one could run repBg onload, but better to run it when the image has actually loaded, see html!
// window.onload=function(){  repBg('data-bg_img','div');  };

BODY で:属性 'data-bg_img' (html5 規則に従い、data- で始まる) をこの手法を使用する要素に追加し、次のように背景 URL を含めます。

<div id="glykopeels" data-bg_img="http://lamininbeauty.co.za/images/products/glykopeel.jpg">Glykopeels Content</div>

BODY の「オプション」の初期化:

<!--
trigger the replace background function when the loader image has actually loaded!
rewriting the onload with nothing to prevent infinite loop in IE6 (and greater?) !!
-->
<img src="http://lamininbeauty.co.za/images/products/loader.gif" style="display:none;" onload="this.onload=null; repBg('data-bg_img','div');">

マニュアル/説明:
画像には onload-event があるため、html (下部) に loading-image を配置します。これにより、独自の onload-event がトリガーさrepBg()れ、ブラウザーが実際にこの load-image をダウンロードするとすぐに呼び出されます。 !!!

この関数repBg()は最大 2 つの引数を取ります。

  • 選択する必要がある属性を含む最初の必須文字列、
  • 2 番目のオプションの引数は、tagname を定義できます (最初の引数を制限するため)。

呼び出されると、関数repBg()は 2 番目の引数に準拠する elementTagNames の本体を検索するか*、最初の引数でそれらをフィルター処理します。
フィルタリングされた htmlObjectCollection に残っている htmlObject ごとに、関数の最初の引数に対応する htmlObject の属性値 (url) を画像ソースとして、htmlObjectCollection の参照 ID (属性data-id) 参考のため。
これらの画像が読み込まれるとすぐに、onload イベントが発生します。参照された htmlObject の背景を新しく読み込まれた (大きな) 背景画像 (および残りの CSS) に置き換えるrepBgのメソッドを呼び出します。execモジュール性をさらに高めるには、その機能を拡張できます。

最後に、注意してください: 背景画像は、ソースに表示される順序でロードされます。

このフィドルで実際にそれを見ることができます: http://jsfiddle.net/epdDa/


更新バージョン 2: グレースフル フォールバック!! そして、コピーアンドペースト NOBRAIN ソリューション
私の最初のソリューションが適切なフォールバックを提供しなかったことは、私の生きている日光を悩ませました。そこで、グレースフル フォールバックを提供する別のソリューションを作成しました。また、 IE6と FF12
で完全にテストされています。次のように動作し ます: BODY で: div のクラスを「プリロード」に設定し、そのスタイル属性を通常ロードする必要がある backgroundimage に設定します。このような:

<div id="facials" class="preload" style="background: #ebebeb url('http://lamininbeauty.co.za/images/products/facial.jpg') no-repeat top right;">Facials Content</div>

簡単でしたよね?
次に、HTML の HEAD (これは重要です) に次のスクリプトを配置します。

// getElementsByClass original by dustin diaz, modified by GitaarLAB
document.getElementsByClassName=document.getElementsByClassName||function(searchClass,node,tag) {
    var classElements = [], i=0, j=0;
    if (!node){node = document;}
    if (!tag){tag = '*';}
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');
    for (; i < elsLen; i++) {
        if ( pattern.test(els[i].className) ) {
            classElements[j] = els[i]; j++;}
    } return classElements;
};

var repBg=(function(n,u,p,a,i,r){ // by GitaarLAB
    window.onload=function(){repBg(1);};
    i=new Image(); i.onload=function(){this.onload=null; repBg(2);};
    document.write("<style>."+n+"{background:"+p+" url("+u+") "+a+
        " !important; background-size: contain !important;}"+
        "</style>");
    i.src=u; r=0;
    return function(t){
        r=r+t; if(r>2){
            var c=document.getElementsByClassName(n), i=0, l=c.length, s;
            repBg.exec=function(){
                document.getElementById(this['data-id']).className='';
            };
            for(;i<l;i++){
                r=new Image();
                r.onload=repBg.exec;
                r['data-id']=c[i].getAttribute('id');
                s=c[i].getAttribute('style');
                try { // sane browsers
                    r.src=s.match(/url\('?([^'"]*)'?\)/i)[1];
                } catch(e) { // <IE8
                    r.src=s.cssText.match(/url\('?([^'"]*)'?\)/i)[1];
                }
            }
        }
    };
})('preload','http://lamininbeauty.co.za/images/products/loader.gif','#ebebeb','no-repeat top right');

説明:
一晩中かかりました..でも方法を見つけました。
javascript が有効になっている場合、関数 repBg は追加のスタイル ブロックをドキュメント ヘッド (配置されている場所、最後の css スクリプトの後に配置することに注意してください) に書き込むことから開始します。クラス「プリロード」(したがって、ページロード時にロードイメージを表示します)。
loading-image の load-test イメージがロードされ、さらにウィンドウがロードされた場合 (ボディ内のすべての要素を取得するため)、基本的にはバージョン 1 と同じです。今回のみ、から URL を取得して照合します。要素の style-attribute と onload は、その後、要素の style-attribute を空にします。

この関数は自動実行され、(上記のように) バージョン 1 と同様のバージョンで上書きされるため、関数 'repBg' の最後の行でパラメーターを調整するだけです。
注意: 初期状態でrepBgは、className、Url、cssPrepend、および cssAppend の最大 4 つの引数を受け入れます。

実際の動作を確認するには (説明に従ってブラウザのバッファを消去することを忘れないでください)、次のフィドルを
クリックしてください: http://jsfiddle.net/epdDa/1/

この機能を使用する人は誰でも、私の功績を認めていただければ幸いです。


更新:
追加の説明とコメントへの回答。

2 つのバージョンの主な相違点
技術的には、どちらのバージョンもほぼ同じ手法を使用しているため、実質的な違いはありません。

  • バージョン 1 では、javascript はページを機能させるために必要な接着剤ですが、有効な true xhtmlとプレーン html で機能します。
    ただし、javascript がオフになっていると、機能しないサイトが表示されます (loading-gif のみが表示されます)。あなたがどこに向かっているのかを含む、他のすべての現在の回答は、この問題に苦しんでいることに注意してください!
  • バージョン 2 では、javascript はページの相互作用 (Web サイトをコーディングする方法) を強化するスパイスにすぎませんが、html (または無効な xhtml) でのみ機能します。
    ただし、これにより、javascript がオフになっているユーザーでも通常の機能するページが表示されるようになります。IE:サイトを正しく表示するためにJavaScript は必要ありません。この概念は、「グレースフル フォールバック」または「グレースフル デグレード」と呼ばれます。バージョン 2 に対する私の投票は 1 番です。
    おまけ:このパスでは、昔ながらの信頼できるインライン スタイル、ID、およびクラスを使用しているため、プレーンなバニラ検証と SEMANTIC html が提供されます。バージョン 2 に 2 票

なぜインライン CSS を使用することにしたのですか? これが機能するためにインライン css を使用する必要があるのはなぜですか?
まず、インライン CSS を避けるために何時間も費やしました。(私はそれらを失いませんでした。うまくいかない方法を学びましたが、同じように便利です)。次に、あなたが行っていた方向を含む現在のすべての回答は、実際の背景画像の URL が CSS から分離されていましたが、CSS では、各 div に個別にローダー画像を設定していました。より理にかなっています。バージョン 2 は、構成可能なクラス名を使用するだけです。

ドキュメントの HEAD での css ブロックの読み取り書き込みの両方は、ちょっとした混乱です..
そして、リンクされた外部 css ファイルについて言及しましたか..??

私の意見では、コア原則が機能するためには、これには非常に多くの余分なコードと CPU サイクルが必要であり、ページロードごとにブラウザーをブロック/停止する必要があります。最後の有効な css ルールが適用されます。したがって、読み込み中の画像は、ページ読み込み時に指定された背景画像であるため、できるだけ早く表示されます。まさにそのような機能に必要なものです。そして、要素が「プリロード」クラスの一部ではなくなった場合はどうなりますか? 右: インライン css が有効になり、ブラウザがレンダリングできるのと同じ速さで更新されます (画像が既に読み込まれている場合)。良い。

したがって、単純に を使用して (真の) xhtml-support を犠牲document.writeにしても、現在のところ、この方法が「最善の」方法であることがわかります (前の 2 つのリンクで読むことができます)。そして、外部にリンクされた css でも動作します。バージョン 2 に対する私の 3 回目の (KISS-) 投票。

バージョン 2 に対する私の 4 番目の投票は、repBg関数がメソッド (= 関数) を「アップグレード」する準備がexecできているため、クラスの値リストから「プリロード」値のみを取り出すことができるためです。単純な replace() で十分です (現在は速度のために省略されています)。

バージョン 2 に対する私の 5 番目で最後の投票は、それが適切なフォールバック セットアップであるため、追加の「スパイス」を使用するように一部のブラウザーを修正またはブロックすることも比較的簡単であるということです。

最後に、速度については、バージョン 2 の方が常に高速に感じられると思います: onload-image は、ブラウザがフェッチできるのとほぼ同じ速さで表示されます (あたかも最初からこの余分な css が常に存在しているかのように)。 : それらの読み込みは既に head で開始されており、関数によって呼び出されるまでブラウザーは却下された画像をダウンロードしません。さらに、気を散らすことなくインタラクティブに見えます。しかし..実際の背景画像が読み込まれ、cssが更新されると:bam! 画像はそこにあり、上から下へのスキャン効果はありません。その効果は非常にきびきびと感じます。実際、私は確信しており、ギャラリの画像、スナップ感、および認識される初期ページロードの増加のために適応を行う予定です..注、これは私の意見です. あなたの走行距離は異なる場合があります。

幸運を!!(そして、このアイデア/機能が好き/使用する場合は投票してください、ありがとう!!)

于 2012-08-11T20:28:19.307 に答える
2

1)div要素にはloadイベントがありません。このイベントは body、images、および script タグのみです。編集: @icktoofay が指摘するように、HTML 仕様ではonload、すべての要素に対して が存在しますが、これは主要なブラウザーでは (まだ) サポートされていません。

2) このスクリプト タグを HTML ページの最後に配置します。

<script>
    function loadImages() {
        var glykopeels = document.getElementById('glykopeels');
        var facials = document.getElementById('facials');

         glykopeels.style.backgroundImage = 'url(http://lamininbeauty.co.za/images/products/glykopeel.jpg)';
         facials.style.backgroundImage = 'url(http://lamininbeauty.co.za/images/products/facial.jpg)';

3)あなたがしたように設定することができますが、文字列の最後にstyle.background置かないでください。そうしないと機能しません.;

フィドル: http://jsfiddle.net/pjyH9/

編集

ブラウザが新しい画像の最初のバイトを受信すると、バックグラウンドから loader.gif が削除されるため、ローダー画像が表示されないようです。別のアプローチを取りましょう。画像をキャッシュにロードし、画像がロードされたときに、指定された ID を持つ要素の背景に画像を設定する関数を次に示します。

function loadImageToBackground(elementId, imageUri) {
    var img = new Image();
    img.onload = function() {
       document.getElementById(elementId).style.backgroundImage = "url('" + imageUri +   "')";
    };
    img.src = imageUri;   
}

ローダーが必要な要素について:

// past the element id and the image url to the function
loadImageToBackground('glykopeels', ​'http://image....');

私はこれがうまくいくと確信しています。関数loadImageToBackgroundは基本的な作業を行います。必要に応じて、機能を拡張および追加できます。

ここに実際の例をいじります:http: //jsfiddle.net/pjyH9/19/ (それぞれ1.5MBの2つの画像をロードするため、ローダーの動作を確認できます)。

于 2012-08-11T15:41:51.207 に答える
1

あなたがやろうとしているのは、ロード後に背景画像を大きなJPG画像に切り替えることだと思います。あなたはあなたのために働くためにこのようなものを適応させることができるはずです:

<html>
  <head>
    <title>Image Load Test</title>
    <script type="text/javascript">
      function loadImage(preloader, imageDiv) {
        document.getElementById(imageDiv).style.background = '#ebebeb url('+preloader.src+') no-repeat top right';
        // I think resetting the background property also resets backgroundSize.
        // If you still want it 'contained' then you need to set the property again.
        document.getElementById(imageDiv).style.backgroundSize = 'contain';
      }
    </script>
    <style type="text/css">
      #testImage {
              background: #ebebeb url(small-image.gif) no-repeat top right;
              background-size: contain;
      }
      #preloads { display: none; }
    </style>
  </head>
  <body>
    <div id="testImage">Some Content</div>
    <div id="preloads">
      <img src="full-image.jpg" onload="loadImage(this, 'testImage')">
    </div>
  </body>
</html>

ここでの主な違いは、JPG 画像を にプリロードし、それを非表示に保つプロパティで隠していること<img>です<div>。イベントが s に対してdisplay: none何をするのか正確にはわかりませんが、あなたが望んでいるものではないことは確かです。要素にイベントを配置すると、画像が完全に読み込まれるとイベントが発生します。これあなたが望むものだと思います。onLoaddivonLoadimg

編集: JavaScript に行を追加して、プロパティをリセットしbackground-sizeました。それがあなたが望んでいたものではない場合は、その部分を無視してください。

于 2012-08-11T15:41:14.373 に答える