Tải trước hình ảnh CSS


118

Tôi có một biểu mẫu liên hệ ẩn được triển khai khi nhấp vào một nút. Các trường của nó được đặt làm hình nền CSS và chúng luôn xuất hiện muộn hơn một chút so với div đã được chuyển đổi.

Tôi đã sử dụng đoạn mã này trong <head>phần, nhưng không may mắn (sau khi tôi xóa bộ nhớ cache):

<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>

Tôi đang sử dụng jQuery làm thư viện của mình và sẽ rất tuyệt nếu tôi cũng có thể sử dụng nó để sắp xếp vấn đề này.

Cảm ơn vì mặc dù của bạn.


Vui lòng hiển thị mã của bạn. Làm thế nào để bạn chuyển đổi biểu mẫu này?
n1313

1
n1313, tôi sử dụng cách đơn giản nhất có thể: $ ('# toggle'). click (function () {$ ('# contact'). slideToggle ();});
Peanuts 03/09/09

Câu trả lời:


257

Chỉ tải trước hình ảnh bằng CSS

Trong đoạn mã dưới đây, tôi đang chọn ngẫu nhiên bodyphần tử, vì nó là một trong những phần tử duy nhất được đảm bảo tồn tại trên trang.

Để "thủ thuật" hoạt động, chúng tôi sẽ sử dụng thuộc contenttính cho phép tải nhiều URL một cách thoải mái , nhưng như được hiển thị, ::afterphần tử giả được giữ ẩn để hình ảnh sẽ không được hiển thị:

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
}

Bản giới thiệu


tốt hơn là sử dụng hình ảnh sprite để giảm yêu cầu http ... (nếu có nhiều hình ảnh có kích thước tương đối nhỏ) và đảm bảo hình ảnh được lưu trữ ở nơi HTTP2 được sử dụng.


27
Điều này thật tuyệt!
Hengjie

4
Kỹ thuật tốt nhất cho đến nay vì sự đơn giản và cách tiếp cận CSS thuần túy! Hạn chế duy nhất thực sự là những hình ảnh này được tải cùng lúc với nội dung hiển thị ngay lập tức và không bị trì hoãn cho đến khi nội dung chính được tải, điều này sẽ yêu cầu Javascript. Nhưng trừ khi bạn tải trước hàng tá hình ảnh, điều này không phải là một công cụ phá vỡ thỏa thuận.
Benjamin

2
đây là tuyệt vời cho gia tải tài sản di chuột cho nút CSS và như vậy - cách mà bạn không nhận được bất kỳ nhấp nháy khi bạn qua qua nút bấm của bạn trong khi tài sản tải
Robert Petz

16
Giải pháp tốt. Tuy nhiên, tôi khuyên bạn không nên áp dụng điều này bodyvì những hình ảnh này sẽ được tải lên mọi trang tham chiếu đến biểu định kiểu. Thay vào đó, bạn nên sử dụng .contact_form:after {...}hoặc một số lớp khác ít toàn cầu hơn. Tất nhiên, trừ khi, biểu mẫu liên hệ của bạn có trên mọi trang;)
CloudMagick

3
@vsync, điều đó có ý nghĩa, đặc biệt là đối với ảnh gif và các tệp nhỏ có thể tái sử dụng. Tình huống tôi gặp gần đây là đối với hình ảnh bg lớn cho băng chuyền phong phú về nội dung và tôi chắc chắn không muốn những tệp lớn đó được tải ở khắp mọi nơi :)
CloudMagick

30

Tôi có thể xác nhận rằng mã gốc của tôi dường như hoạt động. Tôi đã tình cờ dính vào một hình ảnh với một con đường sai lầm.

Đây là bài kiểm tra: 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>

Sau một vài thử nghiệm với CSS-ONLY và giải pháp này, cụ thể là trong trường hợp của tôi, đây là giải pháp tốt nhất.
zequinha-bsb 13/11/11

Cảm ơn nó là Điều dễ dàng nhất của tất cả :)
BetaCoder

4
URL trong câu trả lời không còn hợp lệ.
Brandon Buck,

Xin chào, tôi đã tải lên lại nội dung trên URL đó ( paragraphe.org/slidetoggletest/test.html ), xin lỗi vì đã bỏ lỡ điều này. Chúc mừng,
Peanuts

25

Tải trước hình ảnh bằng Thẻ <link> HTML

Tôi tin rằng hầu hết những người truy cập câu hỏi này đang tìm kiếm câu trả lời của "Làm cách nào để tải trước một hình ảnh trước khi kết xuất của trang bắt đầu?" và giải pháp tốt nhất cho vấn đề này là sử dụng <link>thẻ vì <link>thẻ có khả năng chặn hiển thị thêm trang. Xem trước

Hai tùy chọn giá trị này của thuộc tính rel( mối quan hệ giữa tài liệu hiện tại và tài liệu được liên kết ) phù hợp nhất với vấn đề:

  • tìm nạp trước : tải tài nguyên đã cho trong khi hiển thị trang
  • tải trước : tải tài nguyên đã cho trước khi bắt đầu hiển thị trang

Vì vậy, nếu bạn muốn tải tài nguyên ( trong trường hợp này là hình ảnh ) trước khi quá trình hiển thị <body>thẻ bắt đầu, hãy sử dụng:

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

và nếu bạn muốn tải một tài nguyên trong khi <body>đang hiển thị nhưng bạn định sử dụng động sau này và không muốn làm phiền người dùng về thời gian tải, hãy sử dụng:

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

Cần lưu ý rằng công cụ trình duyệt Mozilla sẽ chỉ tải prefetchkhi trình duyệt không hoạt động, điều này được xác định bởi nsIWebProgressListenerAPI. Xem cái này để biết thêm thông tin.
Matthew Beckman

1
Tôi không nghĩ rằng điều này thực sự chặn hiển thị: w3c.github.io/preload "Ví dụ: ứng dụng có thể sử dụng từ khóa tải trước để bắt đầu tìm nạp sớm, ưu tiên cao và không chặn hiển thị của tài nguyên CSS mà sau đó có thể được áp dụng bởi các ứng dụng tại thời điểm thích hợp"
Michael Crenshaw

1
@MichaelCrenshaw là đúng, <link rel="preload">không không chặn vẽ, tôi tin rằng tác giả hiểu lầm định nghĩa. Từ MDN Tải trước nội dung có rel = "preload" , "... mà bạn muốn bắt đầu tải sớm trong vòng đời của trang, trước khi bộ máy kết xuất chính của trình duyệt hoạt động." Ý tưởng là các tài nguyên được tìm nạp càng sớm càng tốt, làm cho nhiều khả năng tài nguyên đó sẵn có khi cần, chẳng hạn như khi một <img>phần tử đang hiển thị.
MDMower

14

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

Kỹ thuật số 1

Tải hình ảnh về trạng thái bình thường của phần tử, chỉ dịch chuyển nó ra xa với vị trí nền. Sau đó, di chuyển vị trí nền để hiển thị nó khi di chuột.

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

Kỹ thuật số 2

Nếu phần tử được đề cập đã áp dụng hình nền và bạn cần thay đổi hình ảnh đó, thì phần trên sẽ không hoạt động. Thông thường, bạn sẽ tìm một sprite ở đây (một hình nền kết hợp) và chỉ cần thay đổi vị trí nền. Nhưng nếu không thể, hãy thử cách này. Áp dụng hình nền cho một phần tử trang khác đã được sử dụng, nhưng không có hình nền.

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

4
Luôn cung cấp nội dung của các liên kết bên ngoài. Nếu không câu trả lời của bạn là vô giá trị nếu liên kết bị phá vỡ!
sra

@Fatih +1 cho liên kết rất tốt. Phiên bản hiện tại của nhiều bài viết liên kết với 3 cách khác nhau là ở đây perishablepress.com/3-ways-preload-images-css-javascript-ajax
xmojmr

@xmojmr Không có giải pháp chỉ CSS nào trong liên kết của bạn.
Tối đa

10

thử với cái này:

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

Với mã này, bạn tải trước hình nền và hiển thị biểu mẫu khi nó được tải


mck89, cảm ơn cái này trông khá ổn. Nhưng, tôi nên sử dụng mã này bên trong 'head' hay nội tuyến? Ý tôi là, tôi phải điền nó bằng html?
Peanuts 03/09/09

Bạn phải sử dụng nó trong đầu. Tôi nghĩ rằng bạn có thể sử dụng nó bên trong $ (document) .ready
mck89

6

Để tải trước hình ảnh nền được đặt bằng CSS, câu trả lời hiệu quả nhất mà tôi nghĩ ra là phiên bản sửa đổi của một số mã mà tôi thấy không hoạt động:

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

Lợi ích to lớn của việc này là bạn không cần phải cập nhật nó khi bạn đưa ảnh nền mới vào trong tương lai, nó sẽ tìm những ảnh mới và tải trước chúng!


Tôi có hiểu chính xác rằng bạn thêm một phần tử ẩn cho mỗi hình ảnh không? Nó không phải là nó có thể quét tệp CSS của bạn để tìm hình ảnh đúng không? :)
bvdb

5

Nếu bạn đang sử dụng lại những hình ảnh bg này ở bất kỳ nơi nào khác trên trang web của mình để nhập biểu mẫu, bạn có thể muốn sử dụng một mô hình hình ảnh. Bằng cách đó, bạn có thể quản lý tập trung hình ảnh của mình (thay vì có pic1, pic2, pic3, v.v.).

Sprites thường nhanh hơn đối với máy khách, vì họ chỉ yêu cầu một tệp (mặc dù lớn hơn một chút) từ máy chủ thay vì nhiều tệp. Xem bài viết SO để biết thêm lợi ích:

Hình ảnh CSS

Sau đó, một lần nữa, điều này có thể không hữu ích chút nào nếu bạn chỉ sử dụng chúng cho một biểu mẫu và bạn thực sự chỉ muốn tải chúng nếu người dùng yêu cầu biểu mẫu liên hệ ... mặc dù có thể có ý nghĩa.

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


Có, CSS Sprites là cách để đi. Chỉ cần đảm bảo rằng một trong các hình ảnh trong sprite đó xuất hiện trước khi khởi chạy biểu mẫu ẩn (như khi tải trang).
Steve

1

làm thế nào về việc tải hình nền đó ở một nơi ẩn. Bằng cách đó, nó sẽ được tải khi trang được mở và sẽ không mất bất kỳ thời gian nào khi biểu mẫu được tạo bằng ajax:

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

1

Bạn có thể sử dụng plugin jQuery này là waitForImage hoặc bạn có thể đặt hình ảnh của mình vào một div ẩn hoặc (chiều rộng: 0 và chiều cao: 0) và sử dụng sự kiện tải trên hình ảnh.

Nếu bạn chỉ có 2-3 hình ảnh, bạn có thể liên kết các sự kiện và kích hoạt chúng trong một chuỗi để sau mỗi hình ảnh, bạn có thể thực hiện một số mã.


1

Cách duy nhất là Base64 mã hóa hình ảnh và đặt nó bên trong mã HTML để nó không cần phải liên hệ với máy chủ để tải xuống hình ảnh.

Thao tác này sẽ mã hóa hình ảnh từ url để bạn có thể sao chép mã tệp hình ảnh và chèn nó vào trang của mình như vậy ...

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

2
nếu bạn muốn sử dụng lại cùng một hình ảnh trong CSS của mình ... nó sẽ không được lưu vào bộ nhớ cache và bạn sẽ phải tải lại.
vsync

1

Khi không có cách nào để sửa đổi mã CSS và tải trước hình ảnh với các quy tắc CSS :beforehoặc :aftercác phần tử giả thì có thể sử dụng một cách tiếp cận khác với mã JavaScript duyệt qua các quy tắc CSS của bảng định kiểu đã tải. Để làm cho nó hoạt động, các tập lệnh nên được đưa vào sau các biểu định kiểu trong HTML, ví dụ, trước bodythẻ đóng hoặc ngay sau biểu định kiểu.

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

Nếu các phần tử trang và hình nền của chúng đã có trong DOM (tức là bạn không tạo / thay đổi chúng động), thì hình nền của chúng sẽ được tải. Tại thời điểm đó, bạn có thể muốn xem xét các phương pháp nén :)


mmmm ... cpharmston điểm tốt, và điều này giải thích tại sao sự cố vẫn tiếp diễn ngay cả với các hình ảnh được lưu vào bộ nhớ đệm. Vì vậy, điều đó có nghĩa là không có công việc?
Peanuts 03/09/09

Tạo hình ảnh nhỏ hơn! JPEG được nén dễ dàng, có các công cụ dòng lệnh để giảm kích thước của PNG ( pmt.sourceforge.net/pngcrush ) và bạn có thể giảm số lượng màu trong ảnh để giảm kích thước của GIF. Tất nhiên, bạn cũng có thể sử dụng dịch vụ internet nhanh hơn;)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.