2017-03-24 10 views
5

मैं एक पृष्ठ बना रहा हूं जो प्रत्येक 750ms को बदलकर 3 अलग-अलग पृष्ठभूमि के माध्यम से लूप करता है। ऐसा करने के लिए, मैं जेएस के साथ बदलते हुए रिलीज पृष्ठभूमि छवि के साथ शरीर में एक कक्षा जोड़ रहा हूं। पहले लूप के माध्यम से, वे फ्लैश करते हैं क्योंकि छवि को लोड करना पड़ता है, इसलिए यह तुरंत नहीं होता है। इसलिए क्या कोई तरीका है जिसका उपयोग मैं छवियों को प्रीलोड करने के लिए कर सकता हूं?पृष्ठभूमि छवियों को प्रीलोड करना

सीएसएस:

&.backgrounds{ 
    background-position: center bottom; 
    background-repeat: no-repeat; 
    background-size: 130%; 

    &.freddy{ 
     background-image: url(/img/illustrations/snapchat/snapchat_holding_page_freddy.jpg); 
    } 

    &.irene{ 
     background-image: url(/img/illustrations/snapchat/snapchat_holding_page_irene.jpg); 
    } 

    &.joe{ 
     background-image: url(/img/illustrations/snapchat/snapchat_holding_page_joe.jpg); 
    } 
} 

जे एस:

setInterval(function() { 
    if ($('.backgrounds').hasClass('freddy')){ 
     $('.backgrounds').removeClass('freddy').addClass('irene'); 

    } else if ($('.backgrounds').hasClass('irene')){ 
     $('.backgrounds').removeClass('irene').addClass('joe'); 

    } else if ($('.backgrounds').hasClass('joe')){ 
     $('.backgrounds').removeClass('joe').addClass('freddy'); 

    } 
}, 750); 

उत्तर

4

मैं कुछ इस तरह करना होगा। loadImages एक वादा देता है जो सभी छवियों को लोड होने के बाद हल हो जाएगा। .then से जुड़ा हुआ cycleImages पर कॉल करता है, जो अंतराल को शुरू करता है। चूंकि आपको जेएस में यूआरएल की आवश्यकता होगी, वैसे भी प्री-लोडिंग करने के लिए, क्लास स्विचिंग के बजाय मैं सीधे background-image में हेरफेर कर रहा हूं, इस तरह आप सीएसएस से छवि यूआरएल को हटा सकते हैं और कुछ अनावश्यक बाइट्स को बचा सकते हैं। यह भविष्य में छवियों की सूची का विस्तार करना भी आसान बनाता है, आपको कथन के जटिल होने के बजाय केवल छवियों की सरणी में एक आइटम जोड़ने की आवश्यकता है।

function loadImages (images) { 
 
    // each image will be loaded by this function. 
 
    // it returns a Promise that will resolve once 
 
    // the image has finished loading 
 
    let loader = function (src) { 
 
    return new Promise(function (resolve, reject) { 
 
     let img = new Image(); 
 
     img.onload = function() { 
 
     // resolve the promise with our url so it is 
 
     // returned in the result of Promise.all 
 
     resolve(src); 
 
     }; 
 
     img.onerror = function (err) { 
 
     reject(err); 
 
     }; 
 
     img.src = src; 
 
    }); 
 
    }; 
 

 
    // create an image loader for each url 
 
    let loaders = []; 
 
    images.forEach(function (image) { 
 
    loaders.push(loader(image)); 
 
    }); 
 

 
    // Promise.all will return a promise that will resolve once all of of our 
 
    // image loader promises resolve 
 
    return Promise.all(loaders); 
 
} 
 

 

 
// the images we are going to display 
 
let myImages = [ 
 
    'http://www.gifpng.com/400x200', 
 
    'http://www.gifpng.com/400x200/ffffff/000000', 
 
    'http://www.gifpng.com/400x200/000000/ffffff' 
 
]; 
 

 
// $(document).ready(fn) is deprecated, 
 
// use the $(fn) form instead 
 
$(function() { 
 

 
    // after the images are loaded this will be called with an array of the loaded images 
 
    function cycleImages (images) { 
 
    let index = 0; 
 
    setInterval(function() { 
 
     // since we need an array of the image names to preload them anyway, 
 
     // just load them via JS instead of class switching so you can cut them 
 
     // out of the CSS and save some space by not being redundant 
 
     $('#backgrounds').css('backgroundImage', 'url("' + images[index] + '")'); 
 
     // increment, roll over to 0 if at length after increment 
 
     index = (index + 1) % images.length; 
 
    }, 750); 
 
    } 
 

 

 
    // load the images and start cycling through them after they are loaded 
 
    loadImages(myImages).then(cycleImages).catch(function (err) { 
 
    console.error(err); 
 
    }); 
 
});
#backgrounds { 
 
    height: 200px; 
 
    width: 400px; 
 
    border: 1px solid #000; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="backgrounds"></div>

संपादित करें: Just a student खाते में की टिप्पणियां ले रहा है, यहाँ एक संस्करण है कि केवल छवि स्विच करेंगे एक बार यह भरी हुई है है, लेकिन अभी अगर यह भरा हुआ है यह कर । यह उन छवियों को भी छोड़ देता है जो लोड करने में विफल रहे। चूंकि cycleImages अब .then के माध्यम से नहीं बुलाया गया है, इसलिए मैंने इसे भी बदल दिया है, इसलिए यह छवियों के वादे की एक सरणी के साथ एक लक्षित तत्व (एक jQuery ऑब्जेक्ट के रूप में) स्वीकार करता है। इस तरह आप पेज पर कई स्थानों पर आसानी से इसका उपयोग कर सकते हैं, यदि आप चाहें तो विभिन्न छवियों के सेट के साथ।

function loadImages (images) { 
 
    // each image will be loaded by this function. 
 
    // it returns a Promise that will resolve once 
 
    // the image has finished loading 
 
    let loader = function (src) { 
 
    return new Promise(function (resolve, reject) { 
 
     let img = new Image(); 
 
     img.onload = function() { 
 
     // resolve the promise with our url 
 
     resolve(src); 
 
     }; 
 
     img.onerror = function (err) { 
 
     reject(err); 
 
     }; 
 
     img.src = src; 
 
    }); 
 
    }; 
 

 
    // return an array of image-loading promises 
 
    return images.map(function (image) { 
 
    return loader(image); 
 
    }); 
 
} 
 

 

 
// the images we are going to display 
 
let myImages = [ 
 
    'http://www.gifpng.com/400x200', 
 
    'http://www.invalid-domain-name.foo/this-url-certainly-does-not-exist.jpg', 
 
    'http://www.gifpng.com/400x200/ffffff/000000', 
 
    'http://www.gifpng.com/400x200/000000/ffffff' 
 
]; 
 

 
// $(document).ready(fn) is deprecated, 
 
// use the $(fn) form instead 
 
$(function() { 
 

 
    // this receives an array of the promises for each image 
 
    function cycleImages ($target, images) { 
 
    let index = 0, 
 
     interval = 750; // how many ms to wait before attempting to switch images 
 

 
    function nextImage() { 
 
     // p is the promise for the current image 
 
     let p = images[index], 
 
     next = function (wait) { 
 
      // increment our counter and wait to display the next one 
 
      index = (index + 1) % images.length; 
 
      setTimeout(nextImage, wait); 
 
     }; 
 

 
     // wait for this image to load or fail to load 
 
     p.then(function (src) { 
 
     // it loaded, display it 
 
     $target.css('backgroundImage', 'url("' + src + '")'); 
 
     next(interval); 
 
     }).catch(function (err) { 
 
     // this one failed to load, skip it 
 
     next(0); 
 
     }); 
 

 
    } 
 

 
    // start cycling 
 
    nextImage(); 
 
    } 
 

 

 
    // load the images and start cycling through them as they are loaded 
 
    cycleImages($('#backgrounds'), loadImages(myImages)); 
 
});
#backgrounds { 
 
    height: 200px; 
 
    width: 400px; 
 
    border: 1px solid #000; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="backgrounds"></div>

के बजाय हार्ड-कोड छवियों परिवर्तन के बीच अंतराल तुम भी है कि पास कर सकता है एक पैरामीटर के रूप। उस बिंदु पर, मैं इसे सब कुछ पास करने के लिए कॉन्फ़िगरेशन ऑब्जेक्ट का उपयोग करने के लिए दोबारा प्रतिक्रिया दूंगा लेकिन छवि वादा सरणी: cycleImages(myImages, {target: $('#backgrounds'), interval: 1000});

+0

एक तरफ नोट, आप प्रत्येक 750ms के बजाय प्रत्येक कुछ सेकंड में अंतराल को बदलने के बारे में सोचना चाहेंगे। ज्यादातर लोग उस तेजी से चमकते हुए किसी चीज से नाराज हो जाएंगे। ध्यान घाटे के विकार वाले किसी व्यक्ति के रूप में, मैं आपको बता सकता हूं कि किसी पृष्ठ पर तेज़ चमकते हुए कुछ पेज पर कुछ भी पढ़ने पर ध्यान देना मुश्किल हो जाता है; यह बहुत विचलित है। एडीडी के बिना भी लोग व्याकुलता से प्रभावित हो सकते हैं। –

+0

महान जवाब! एक सुझाव: वर्तमान में, पहले चित्र दिखाए जाने से पहले सभी छवियों को लोड किया जाता है। यह आवश्यक होने पर केवल एक छवि लोड करने के लिए एक अच्छा वैकल्पिक समाधान हो सकता है और वादा को हल होने तक बस स्विच में देरी हो सकती है। इसका मतलब यह होगा कि पहले लूप के लिए, आप अभी तक अंतराल का उपयोग नहीं कर सकते हैं, लेकिन इसके बजाय यह सुनिश्चित करने की आवश्यकता है कि दोनों (ए) 750 एमएमएस (या जो भी आप सेट करते हैं) पास हो गए हैं और (बी) अगली छवि लोड हो गई है। वास्तव में यह भी वादे के साथ अच्छी तरह से किया जा सकता है। –

+0

ओह, और वर्तमान समाधान का एक और नुकसान यह है कि कोई पृष्ठभूमि छवि नहीं दिखायी जाएगी, भले ही केवल एक को एक्सेस नहीं किया जा सके। –

0

दिलचस्प विचार।

आप संभवतः इसलिए पृष्ठभूमि में उन्हें लोड किया जा सका की तरह:

<div class="hidden-images"> 
    <img src="img1.jpg" /> 
    <img src="img2.jpg" /> 
    <img src="img3.jpg" /> 
</div> 
फिर सीएसएस में

.hidden-images { 
    position: relative; 
    z-index: 1; 
} 

फिर जो कुछ भी आप मुख्य कंटेनर div की तरह, तमाचा है उस पर निम्नलिखित पर?

.main-container { 
    position: relative; 
    z-index: 2; // Or higher, whatever is needed 
} 
1

आप उन्हें जावास्क्रिप्ट में लोड कर सकते हैं। पसंद:

(new Image()).src = url1; 
(new Image()).src = url2; 
(new Image()).src = url3; 

अपनी छवि यूआरएल के साथ "url1", "url2", "url3" बदलें। ब्राउज़र छवि लोड करेगा लेकिन वे कहीं भी दिखाई नहीं देंगे।

0

आप इसे इस तरह के विभिन्न एचटीएमएल और सीएसएस संरचना के साथ भी कर सकते हैं।

एचटीएमएल

<div class="backgrounds"> 
    <div class="background freddy"></div> 
</div> 

सीएसएस

.backgrounds{ 
    background-color: transparent; 
    background-position: center bottom; 
    background-repeat: no-repeat; 
    background-size: 130%; 
    height: 250px; 
    width; 100%; 
} 

.backgrounds .freddy{ 
     height: 100%; 
     width: 100%; 
     background-image: url('http://adrianweb.net/includes/images/hero.jpg'); 
    } 

.backgrounds .irene{ 
     height: 100%; 
     width: 100%; 
     background-image: url('http://adrianweb.net/includes/images/projects-blur.png'); 
    } 

.backgrounds .joe{ 
     height: 100%; 
     width: 100%; 
     background-image: url('http://adrianweb.net/includes/images/contacts-blur.png'); 
    } 

जे एस

$(document).ready(function(){ 
setInterval(function() { 
    if ($('.background').hasClass('freddy')){ 
     $('.background').removeClass('freddy').addClass('irene'); 

    } else if ($('.background').hasClass('irene')){ 
     $('.background').removeClass('irene').addClass('joe'); 

    } else if ($('.background').hasClass('joe')){ 
     $('.background').removeClass('joe').addClass('freddy'); 

    } 
}, 750); 
}); 

हो सकता है कि आप इसे अंदर और बाहर फीका लग रही बनाने के लिए संक्रमण/एनीमेशन जोड़ सकते हैं।

नमूना नीचे codepen:

http://codepen.io/adrianrios/pen/yMEpEv

संबंधित मुद्दे