Попередня завантаження CSS-зображень


118

У мене є прихована контактна форма, яка розгорнута, натиснувши кнопку. Його поля задаються у вигляді фонових зображень CSS, і вони завжди з’являються трохи пізніше, ніж div, який було перемкнено.

Я використовував цей фрагмент у <head>розділі, але не пощастило (після того, як я очистив кеш):

<script>
$(document).ready(function() {
        pic = new Image();
        pic2 = new Image();
        pic3 = new Image();
        pic.src="<?php bloginfo('template_directory'); ?>/images/inputs/input1.png";
        pic2.src="<?php bloginfo('template_directory'); ?>/images/inputs/input2.png";
        pic3.src="<?php bloginfo('template_directory'); ?>/images/inputs/input3.png";
});
</script>

Я використовую jQuery як свою бібліотеку, і було б здорово, якби я міг використовувати її також для організації цієї проблеми.

Дякую за те, що ви хочете.


Покажіть, будь ласка, свій код. Як ви перемикаєте цю форму?
n1313

1
n1313, я використовую найпростіший можливий спосіб: $ ('# toggle'). click (function () {$ ('# contact'). slideToggle ();});
Арахіс

Відповіді:


257

Попередня завантаження зображень лише за допомогою CSS

У наведеному нижче коді я випадковим чином вибираю body елемент, оскільки це один з гарантованих елементів на сторінці.

Для того, щоб "фокус" працював, ми будемо використовувати contentвластивість, яка комфортно дозволяє встановлювати кілька URL-адрес, але як показано, ::afterпсевдоелемент зберігається прихованим, щоб зображення не відображалися:

body::after{
   position:absolute; width:0; height:0; overflow:hidden; z-index:-1; // hide images
   content:url(img1.png) url(img2.png) url(img3.gif) url(img4.jpg);   // load images
}

Демо


краще використовувати спрайт-образ для зменшення http-запитів ... (якщо є багато зображень порівняно невеликого розміру) і переконайтеся, що зображення розміщуються там, де використовується HTTP2 .


27
Це круто!
Hengjie

4
Найкраща техніка дотепер для простоти та чистого CSS підходу! Єдиний недолік насправді полягає в тому, що ці зображення завантажуються одночасно з безпосередньо видимим контентом, а не відкладаються до того моменту, поки не завантажиться основний контент, який потребував би Javascript. Але якщо ви не завантажуєте десятки зображень, це не повинно бути розбивачем.
Бенджамін

2
це фантастично для попереднього завантаження курсорних елементів для кнопок CSS і так - таким чином у вас не виникає мерехтіння, коли ви перейдете на кнопку, поки активація завантажується
Роберт Петц,

16
Гарне рішення. Я б рекомендував не застосовувати це body, оскільки ці зображення завантажуються на кожну сторінку, на яку посилається таблиця стилів. Натомість ви повинні використовувати .contact_form:after {...}або якийсь інший клас, який є менш глобальним. Якщо, звичайно, ваша контактна форма є на кожній сторінці;)
CloudMagick

3
@vsync, що має сенс, особливо для GIF і невеликих повторних використання. Ситуація, з якою я стикався нещодавно, стосувалася великих зображень у форматі bg для каруселі з насиченим вмістом, і я, звичайно, не хотів, щоб ті великі файли завантажувались всюди :)
CloudMagick

30

Я можу підтвердити, що мій оригінальний код, здається, працює. Я випадково прилипав до зображення неправильним шляхом.

Ось тест: http://paragraphe.org/slidetoggletest/test.html

<script>
    var pic = new Image();
    var pic2 = new Image();
    var pic3 = new Image();
    pic.src="images/inputs/input1.png";
    pic2.src="images/inputs/input2.png";
    pic3.src="images/inputs/input3.png";
</script>

Після декількох тестів з CSS-ТОЛЬКО і це рішення, в моєму випадку конкретно, це найкраще.
zequinha-bsb

Дякуємо за найпростіший з усіх :)
BetaCoder

4
URL-адреса у відповіді більше не є дійсною.
Брендон Бак

Привіт, я повторно завантажив вміст на цю URL-адресу ( paragraphe.org/slidetoggletest/test.html ), вибачте, що пропустив це. Ура,
Арахіс

25

Попередня завантаження зображень за допомогою HTML <link> Тег

Я вважаю, що більшість відвідувачів цього питання шукають відповіді "Як я можу попередньо завантажити зображення до початку візуалізації сторінки?" а найкраще рішення цієї проблеми - використання <link>тегу, оскільки <link>тег здатний блокувати подальше відображення сторінки. Див. Перевагу

Ці два параметри значення rel( взаємозв'язок між поточним документом та пов'язаним документом ) атрибуту найбільш релевантні:

  • prefetch : завантажте даний ресурс під час візуалізації сторінки
  • попереднє завантаження : завантажте даний ресурс перед початком візуалізації сторінки

Тож якщо ви хочете завантажити ресурс ( у даному випадку це зображення ) перед початком процесу візуалізації <body>тегу, використовуйте:

<link rel="preload" as="image" href="IMAGE_URL">

і якщо ви хочете завантажити ресурс під час <body>візуалізації, але ви плануєте використовувати його в подальшому динамічно і не хочете заважати користувачеві часом завантаження, використовуйте:

<link rel="prefetch" href="RESOURCE_URL">

Варто зазначити, що двигун браузера Mozilla завантажуватиметься лише prefetchтоді, коли браузер не працює, що визначається nsIWebProgressListenerAPI. Дивіться це для отримання додаткової інформації.
Метью Бекман

1
Я не думаю, що це насправді блокує візуалізацію: w3c.github.io/preload "Наприклад, програма може використовувати ключове слово попереднього завантаження для ініціювання раннього, високоприоритетного та неблокуючого блокування ресурсу CSS, який може потім застосовуватись заявкою у відповідний час "
Майкл Креншо

1
@MichaelCrenshaw правильно, <link rel="preload">це НЕ блок рендеринга, я вважаю , що автор неправильно визначення. З MDN Попередній завантаження вмісту з rel = "preload" , "... який ви хочете почати завантажувати на початку життєвого циклу сторінки, перш ніж починається основна техніка візуалізації браузерів." Ідея полягає в тому, що ресурси отримують якнайшвидше, що робить більш імовірним, що ресурс буде доступний при необхідності, наприклад, коли <img>елемент передається.
MDMower

14

http://css-tricks.com/snippets/css/css-only-image-preloading/

Техніка №1

Завантажте зображення у звичайний стан елемента, лише відсуньте його від фонового положення. Потім перемістіть положення фону, щоб відобразити його на наведення курсора.

#grass { background: url(images/grass.png) no-repeat -9999px -9999px; }
#grass:hover { background-position: bottom left; }

Техніка №2

Якщо до відповідного елемента вже застосовано фонове зображення, і вам потрібно змінити це зображення, вищезазначене не буде працювати. Зазвичай ви б тут справили спрайт (комбінований фоновий образ) і просто змістили фонове положення. Але якщо це неможливо, спробуйте це. Застосувати фонове зображення до іншого елемента сторінки, який вже використовується, але не має фонового зображення.

#random-unsuspecting-element { background: url(images/grass.png) no-repeat -9999px -9999px; }
#grass:hover { background: url(images/grass.png) no-repeat; }

4
Завжди надайте вміст зовнішніх посилань. Інакше ваша відповідь марна, якщо посилання розривається!
sra

@Fatih +1 за дуже гарне посилання. Більш поточна версія пов'язаної статті з 3 - ма різними способами тут perishablepress.com/3-ways-preload-images-css-javascript-ajax
xmojmr

@xmojmr У вашому посиланні немає лише CSS-рішень.
Макс

10

спробуйте з цим:

var c=new Image("Path to the background image");
c.onload=function(){
   //render the form
}

За допомогою цього коду ви попередньо завантажуєте фонове зображення та надаєте форму при завантаженні


mck89, спасибі це виглядає досить добре. Але чи повинен я використовувати цей код всередині "голови" чи "вбудованого"? Я маю на увазі, чи повинен я заповнити його html?
Арахіс

Ви повинні використовувати його в голові. Я думаю, що ви можете використовувати його всередині $ (document) .ready
mck89

6

Для попереднього завантаження фонових зображень, встановлених CSS, найефективнішою відповіддю, яку я придумав, була модифікована версія якогось коду, який я виявив, що він не працював:

$(':hidden').each(function() {
  var backgroundImage = $(this).css("background-image");
  if (backgroundImage != 'none') {
    tempImage = new Image();
    tempImage.src = backgroundImage;
  }
});

Величезна перевага цього полягає в тому, що вам не потрібно оновлювати його, коли в майбутньому ви вносите нові фонові зображення, вони знайдуть нові та попередньо завантажать їх!


Чи правильно я розумію, що ви додаєте прихований елемент для кожного зображення? Це не те, що він може сканувати ваш файл CSS на зображення, чи не так? :)
bvdb

5

Якщо ви використовуєте ці bg-образи де-небудь ще на вашому сайті для введення форми, ви, ймовірно, хочете використовувати спрайт зображень. Таким чином ви можете централізовано керувати своїми зображеннями (замість pic1, pic2, pic3 тощо).

Прайти, як правило, швидше для клієнта, оскільки вони вимагають лише один (хоч трохи більший) файл із сервера замість кількох файлів. Дивіться статтю про додаткові переваги:

CSS-спрайти зображень

Знову ж таки, це може бути зовсім не корисним, якщо ви просто використовуєте їх для однієї форми, і ви дійсно хочете їх завантажувати лише у випадку, коли користувач запитує контактну форму ... Хоча це може мати сенс.

http://www.alistapart.com/articles/sprites


Так, CSS спрайти - це шлях. Просто переконайтеся, що одне із зображень у спрайті з’являється перед запуском прихованої форми (наприклад, при завантаженні сторінки).
Стів

1

як щодо завантаження цього фонового зображення десь приховано. Таким чином він буде завантажений, коли сторінка відкрита, і не буде потрібен будь-коли, коли форма буде створена за допомогою ajax:

body {
background: #ffffff url('img_tree.png') no-repeat -100px -100px;
}

1

Ви можете використовувати цей плагін jQuery waitForImage або ви можете помістити зображення в прихований div або (ширина: 0 і висота: 0) та використовувати події завантаження на зображеннях.

Якщо у вас є лише 2-3 зображення, ви можете зв'язати події і запустити їх ланцюжком, тому після кожного зображення ви можете зробити якийсь код.


1

Єдиний спосіб - Base64 кодувати зображення і розмістити його всередині HTML-коду, щоб не потрібно було звертатися до сервера для завантаження зображення.

Це буде кодувати зображення з URL, щоб ви могли скопіювати код файлу зображення та вставити його на свою сторінку так ...

body {
  background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...);
}

2
якщо ви хочете знову використовувати те саме зображення у своєму CSS ... воно не буде кешоване, і вам доведеться завантажити його знову.
vsync

1

Коли немає можливості змінювати CSS-код і попередньо завантажувати зображення з правилами CSS для :beforeабо :afterпсевдоелементів, може бути використаний інший підхід із кодом JavaScript, який проходить правила CSS для завантажених таблиць стилів. Для того, щоб зробити його робочими сценаріями слід включити після таблиць стилів в HTML, наприклад, перед закриттям bodyтегу або відразу після таблиць стилів.

getUrls() {
    const urlRegExp = /url\(('|")?([^'"()]+)('|")\)?/;

    let urls = [];
    for (let i = 0; i < document.styleSheets.length; i++) {
        let cssRules = document.styleSheets[i].cssRules;
        for (let j = 0; j < cssRules.length; j++) {
            let cssRule = cssRules[j];
            if (!cssRule.selectorText) {
                continue;
            }

            for (let k = 0; k < cssRule.style.length; k++) {
                let property = cssRule.style[k],
                    urlMatch = cssRule.style[property].match(urlRegExp);
                if (urlMatch !== null) {
                    urls.push(urlMatch[2]);
                }
            }
        }
    }
    return urls;
}

preloadImages() {
    return new Promise(resolve => {
        let urls = getUrls(),
            loadedCount = 0;

        const onImageLoad = () => {
            loadedCount++;
            if (urls.length === loadedCount) {
                resolve();
            }
        };

        for (var i = 0; i < urls.length; i++) {
            let image = new Image();
            image.src = urls[i];
            image.onload = onImageLoad;
        }
    });
}

document.addEventListener('DOMContentLoaded', () => {
    preloadImages().then(() => {
        // CSS images are loaded here
    });
});

0

Якщо елементи сторінки та їх фонові зображення вже є у DOM (тобто ви не створюєте / змінюєте їх динамічно), то їх фонові зображення вже завантажуватимуться. У цей момент ви можете подивитися методи стиснення :)


мммм ... хороший момент cpharmston, і це пояснює, чому проблема зберігається навіть із кешованими зображеннями. Отже, це означає, що немає ніякого пошкодження?
Арахіс

Створюйте менші зображення! JPEG легко стискаються, є інструменти командного рядка для зменшення розміру PNG ( pmt.sourceforge.net/pngcrush ), і ви можете зменшити кількість кольорів на зображенні, щоб зменшити розмір GIF. Звичайно, ви також можете скористатися швидшим службою Інтернету;)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.