2017-03-29 6 views
5

J'utilise la technique suivante aux images pré-charge qui sont appliqués sous forme d'images d'arrière-plan CSS lorsque les boutons en vol stationnaire:image techniques préchargement (pour une utilisation en tant qu'Etat vol stationnaire images de fond CSS) ne semblent pas travailler sur Chrome

#preload_area { 
    background-image: 
    url(../images/image1.svg), 
    url(../images/image2.svg); 
    width: 0px; 
    height: 0px; 
    display: inline; 
} 

a également essayé d'effectuer une pré-charge d'une seule image, de cette façon:

#preload_area { 
    background: url(../images/image1.svg) -9999px -9999px no-repeat; 
} 

Rien de tout cela fonctionne: après rafraîchissement dur, en vol stationnaire mon bouton la première fois, je vois encore un clin d'oeil (ce qui correspond à une charge l'image du vol stationnaire). Évidemment, après cette première fois, il n'y a plus de clignement d'yeux.

Pourquoi ne fonctionne pas sur Chrome? (Il ne fonctionne sur Firefox)

+0

Il n'y a aucune raison pour que le premier exemple de code ne fonctionnerait pas. Le second devrait juste avoir 'background' au lieu de' background-image' - voir https: //developer.mozilla.org/fr-fr/docs/Web/CSS/Shorthand_properties # Background_Properties – helb

+0

Eh bien, ce n'est pas le cas. J'utilise Chrome 57.0.2987.110 (64 bits) sur Windows 10. Merci pour le commentaire, j'ai rectifié (ne fonctionne toujours pas sur Chrome). Fonctionne bien sur Firefox. – drake035

+1

@ drake035 Je pense que Chrome implémente une sorte de virtualisation DOM, où seuls les éléments visibles sont rendus, donc je ne suis pas sûr si vous seriez capable de contourner ce problème, sauf si vous mettez l'image dans la zone visible pendant le préchargement. bien sûr, est indésirable. –

Répondre

0

Live Demo: http://blackmiaool.com/soa/43093224/

Personne ne promesse que les images invisibles seront chargées. Les navigateurs ont le droit de ne pas précharger vos images invisibles, de sorte que l'approche css dans votre question peut ne pas fonctionner dans certains navigateurs. La démo ci-dessus est écrite par moi-même. Il restitue réellement l'image sur l'écran pour garantir que l'image est chargée.

HTML:

<!DOCTYPE html> 
<html> 

<head> 
    <meta charset="utf-8" /> 
    <title>test</title> 

</head> 

<body> 
    <h1 style="color:white;text-align:center;">Try to hover</h1> 
    <div class="show-area"></div> 
    <link rel="stylesheet" href="style.css"> 

    <script src="../js/jquery.min.js"></script> 
    <script> 
     function preloadImage(src, cb) { 
      //create a image 
      const $dom = $("<img />", { 
       src: src 
      }); 

      //check whether the image is already loaded 
      if ($dom[0].naturalWidth) { 
       cb && cb(); 
       return; 
      } 

      //Put the image at the left bottom of the screen, and set its opacity to 0.01 to keep it from people eyes. 
      //Since it's actually rendered on the screen, the browser must load the image 
      $dom.css({ 
       opacity: 0.01, 
       position: 'fixed', 
       bottom: 0, 
       left: 0, 
       height: 1, 
       width: 1, 
       'z-index': 10000, 
       'pointer-events': 'none', 
      }); 

      $(document.body).append($dom); 

      //listen its `load` event to remove it and invoke callback 
      $dom.on("load", function() { 
       $dom.remove(); 
       cb && cb(); 
      }); 
     } 

     //try to get the urls in the css file, and preload them 
     $("link").each(function() { 
      const href = $(this).attr("href"); 
      $.get(href, function(style) { 
       const urls = []; 
       let match = style.match(/url\([\s\S]+?\)/g); 

       match.forEach(function(str) { 
        str = str.replace(/\s/g, "") 
         .replace(/^url\(/, "") 
         .replace(/\)$/, ""); 
        let url = str.match(/^["']?([\S]+?)["']?$/); 
        if (!url || !url[1]) { 
         console.warn("Can't find url of " + str); 
        } else { 
         url = url[1]; 
         preloadImage(url); 
        } 
       }); 
      }); 
     }); 
    </script> 

</body> 

</html> 

css:

body{ 
    margin: 0; 
    background-color: black; 
} 
.show-area {  
    height: 100px; 
    width: 300px; 
    margin: auto; 
    margin-top: 100px; 
    background: url(./1.jpg) no-repeat center; 
    background-size: contain; 
} 

.show-area:hover { 
    background-image: url("./2.jpg "); 
} 
+0

Je ne sais pas comprendre ce code ou comment l'utiliser, donc je ne peux pas accepter la réponse ... – drake035

+0

@ drake035 J'ai mis à jour la réponse pour ajouter quelques commentaires pour vous. – blackmiaool

+0

@ drake035 J'ai mis à jour la réponse pour la rendre compatible avec l'extrait de votre question. – blackmiaool

0

Pourquoi est-il ne fonctionne pas sur Chrome? Parce que tous les vendeurs de navigateurs veulent le navigateur le plus rapide. Ils ne chargeront pas les actifs non contrôlés.

Vous souhaitez un préchargement? Utilisez un sprite, comme [CBroe] suggéré. Cette solution a été autour depuis des siècles et est solide comme le roc. Tout autre truc, rendant l'image invisible, peut fonctionner aujourd'hui mais être brisé demain.

0

préchargement en CSS ne signifie pas vraiment que le fichier est chargé avant tout le reste, cela signifie juste que c'est la première ressource à la file d'attente pour le téléchargement à partir de votre fichier CSS.

Cela signifie que votre HTML a déjà été récupéré à partir du serveur et a probablement déjà mis en attente ou téléchargé d'autres ressources avant que le CSS. Il n'est pas rare que les images préchargées CSS se chargent après tout le contenu HTML.

Maintenant, alors que l'image sera plus tôt dans la file d'attente que d'autres ressources référencées dans le CSS cela ne signifie pas qu'il retourne avant les autres ressources. Si la taille du fichier est supérieure à celle des autres fichiers mis en file d'attente, le téléchargement peut prendre plus de temps que les autres fichiers téléchargés en même temps.

Une façon de voir ce qui se passe avec Chrome est d'aller à votre page Web et accédez à l'onglet « Réseau » dans les Devtools Chrome puis rafraîchir la page. Il vous montrera les détails du moment où chaque élément est chargé et combien de temps cet élément doit être reçu du serveur. Selon l'image que vous chargez et votre cas d'utilisation, il existe plusieurs autres options.

1) Si la taille du fichier est grande et que le téléchargement est trop long, déterminez comment réduire la taille du fichier.

2) Si vous avez le contrôle de la page que l'utilisateur navigue à partir, vous pouvez précharger l'image pour le cache de la page précédente.

3) Vous pouvez également essayer d'utiliser le préchargement HTML en plus du CSS. Je pense que le préchargement HTML est uniquement pris en charge par Chrome pour le moment, il est donc peut-être parfait pour ce scénario. Ajoutez ce qui suit à la tête de votre code HTML.

<link rel="preload" as="image" href="image1.svg"> 
<link rel="preload" as="image" href="image2.svg"> 
+0

Merci. Dans DevTools, peu importe combien de temps j'attends, l'image de survol est chargée à la fin de la liste uniquement lorsque j'effleure mon lien. La précharge ne fonctionne tout simplement pas. – drake035

0

Fait un test avec du chrome, il semble que l'image est chargée. Le clignotement est dû à placer l'image je pense. Pour mieux comprendre, jetez un oeil à ce test.

A test with a very big image

div#preload_area::before { 
content: " "; 
background: url(http://gfsnt.no/oen/foto/Haegefjell_Jan_2013_Large.jpg) no-repeat; 
} 

div#preload_area { 
    width: 50%; 
    height:100vh; 
} 

div#preload_area:hover { 
    background: url(http://gfsnt.no/oen/foto/Haegefjell_Jan_2013_Large.jpg); 
    background-repeat:no-repeat; 
    background-size:100% auto; 
} 
0

à mon humble avis, ce n'est pas préchargement. C'est juste le chargement, et vous utilisez un truc pour afficher la bonne image lorsque vous passez le bouton.

Si vous voulez vraiment précharger, ou, si je comprends votre besoin, « vous voulez que l'image déjà là, lorsque vous essayez de planer sur le bouton », alors vous avez différentes options:

  • prélecture:

<link rel="prefetch" href="image1.svg"> <link rel="prefetch" href="image2.svg">

Une bonne chose à ajouter est que « il n'y a aucune restriction de même origine pour le préchargement des liens ».

    pré-charge
  • :

<link rel="preload" href="image1.svg"> <link rel="preload" href="image2.svg">

Avec "pré-charge", les ressources doivent être téléchargées, alors que ce n'est pas toujours le cas avec prefetch.

Preload est pris en charge par Chrome, Opera, navigateur Android et un peu plus, mais pas Firefox & autres. Plus de détails here

Ces techniques sont décrites de façon plus approfondie sur css-tricks.com

espoir que cela vous aide.

0

Si vous ne voulez pas d'espace de chargement, vous pouvez utiliser une image-image, ou vous pouvez définir l'image d'arrière-plan comme image codée en base64. Dans ce cas, les images sont toujours chargées lorsque le fichier css est chargé.

.myImg { 
    background-image: url(data:image/svg+xml;base64,PD9...); 
} 

Ici, vous pouvez convertir vos images svg à base64: http://b64.io

0

J'utilise récemment ceci pour "back to top" bouton dans mon blog http://anggit.com. Cela va-t-il marcher pour vous?

CSS:

<style> 
#to_top { 
    display: block; 
    width: 48px; 
    height: 48px; 
    overflow: hidden; 
} 
#to_top img { /* in case the actual image size is over 48px */ 
    width: 48px; 
    height: 48px; 
} 
#to_top:hover #image-1 { /* hover will remove the 1st image, the 2nd image will appear */ 
    display: none; 
} 
</style> 

HTML:

<a id="to_top" href="#"> 
    <img id="image-1" src="image48x48.png" alt="Top" /> 
    <img id="image-2" src="image48x48-hover.png" alt="Top" /> 
</a>