it-swarm.com.de

So laden Sie Bilder faul und stellen sie zum Drucken bereit

Einige Websites haben viele Bilder, daher scheint Lazyloading angemessen zu sein, um Ladezeiten und Datenverbrauch zu reduzieren. Aber was ist, wenn Sie für diese Website auch printing unterstützen müssen?

Ich meine, Sie können versuchen, das Druckereignis zu erkennen und dann die Bilder mit so etwas wie dem folgenden zu laden:

HTML

<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">

Hinweis: Dies ist ein Dummy-Bild mit einer Pixelanzahl.

JavaScript

window.addEventListener('DOMContentLoaded', () => {
  img = document.querySelector('img');
  var isPrinting = window.matchMedia('print');
  isPrinting.addListener((media) => {
    if (media.matches) {
      img.src = 'http://unsplash.it/500/300/?image=705';
    }
  })
});

Hinweis: Wenn Sie dies in einem Code-Spielfeld versuchen, entfernen Sie das Ereignis DOMContentLoaded (oder geben Sie einfach Folgendes ein: JSFiddle | Codepen ).

Anmerkung: Ich habe mich aus offensichtlichen Gründen nicht um die onbeforeprint und onafterprint gekümmert.

Dies funktioniert gut, wenn das Bild zwischengespeichert wird, aber genau das ist nicht der Punkt. Die Bilder sollten alle geladen und dann auf dem Druckbildschirm angezeigt werden.

Hast du eine Idee? Hat jemand erfolgreich ein druckfertiges Lazyloading-Plugin implementiert?

Aktualisieren

Ich habe versucht, umzuleiten den Benutzer nach dem Erkennen des Druckdialogs zu einer gekennzeichneten Version der Website a.k.a website.com?print=true, auf der das Lazyloading deaktiviert ist und alle Bilder normal geladen werden.

Diese Methode wird verbessert, indem die window.print() -Methode in dieser markierten druckfertigen Version der Seite angewendet wird, ein neuer Druckdialog geöffnet wird, sobald alle Bilder geladen sind, und in der Zwischenzeit eine "warte darauf" -Meldung angezeigt wird oben auf der Seite.

Wichtiger Hinweis: Diese Methode wurde in Chrome getestet. Sie funktioniert weder in Firefox noch in Edge (daher ist dies keine Antwort, sondern ein Zeugnis).

Es funktioniert in Chrome, da der Druckdialog geschlossen wird, wenn Sie auf eine andere Website umleiten (in diesem Fall dieselbe URL, aber markiert). In Edge und Firefox ist das Druckdialogfeld ein tatsächliches Fenster und wird nicht geschlossen, wodurch es ziemlich unbrauchbar wird.

23
undefined

Aufgrund Ihrer gewünschten Funktionalität bin ich nicht ganz sicher, was Sie tun möchten. Als Entwickler haben wir nicht wirklich die Kontrolle über den Browser eines Benutzers. Hier sind meine Gedanken, warum dies nicht vollständig möglich ist.

  1. Durch das Anhängen des Ereignisses und das Laden Ihrer fehlenden Bilder können Sie nicht garantieren, dass Bilder vom Server auf Ihre Seite gelangen. Genauer gesagt, das für Ihre Druckvorschau generierte PDF wird generiert, bevor das Laden Ihrer Bilder abgeschlossen ist, der img.src = "..." ist asynchron. Mit onbeforeprint stoßen Sie leider auch auf ähnliche Probleme. Manchmal funktioniert es, manchmal nicht (z. B. hat Ihre Geige beim Testen in Safari funktioniert, aber nicht in Chrome)

  2. Sie können nicht stoppen oder stoppen den Druckaufruf - Sie können den Browser nicht dazu zwingen, zu warten, bis das Bild im Lazy-Loading-Kontext vollständig geladen ist. (Ich habe einmal etwas über die Verwendung von Warnmeldungen gelesen, um dies zu erreichen, aber es schien mir wirklich hackig zu sein, war eher eine Abschreckung für das Drucken als das Abwürgen).

  3. Sie können img.src nicht zwingen, diese Daten synchron in einem Lazy-Load-Kontext abzurufen. Es gibt einige Methoden, dies zu tun, aber sie sind clevere Hacks - werden als reines Übel bezeichnet und funktionieren möglicherweise nicht immer. Ich habe einen anderen Link mit einem ähnlichen Ansatz gefunden

Wir haben also ein Problem: Wenn die Bilder nicht bis zum Zeitpunkt des Druckereignisses geladen werden, können wir den Browser nicht dazu zwingen, zu warten, bis sie abgeschlossen sind. Sicher, wir können diese Bilder abdrucken und loslegen, aber wie oben erwähnt, können wir nicht warten, bis diese Ressourcen geladen sind, bevor die Druckvorschau angezeigt wird.

Mögliche Lösung (inspiriert durch Links in Punkt drei sowie diesen Link )

Sie könnten fast mit einem synchronen XMLHttpRequest davonkommen. Syncrhonous XMLHTTPRequests lässt Sie den ResponseType nicht ändern, es handelt sich immer um Zeichenfolgen. Sie können den String-Wert jedoch in einen ArrayBuffer-Code konvertieren, der ihn in einen Base-64-codierten String codiert, und src auf eine dataURL setzen (siehe den Link, auf den clevere Hacks verwiesen werden). Als ich dies jedoch versucht habe, habe ich einen Fehler erhalten das jsfiddle - so wäre es möglich, wenn die Dinge richtig konfiguriert wären, theoretisch. Ich zögere, ja zu sagen, dass Sie es können, da ich nicht in der Lage war, die Geige mit den folgenden Elementen zum Laufen zu bringen (aber es ist eine Route, die Sie erkunden könnten!).

var xhr = new XMLHttpRequest();
xhr.open("GET","http://unsplash.it/500/300/?image=705",false);
xhr.send(null);
if (request.status === 200) {
    //we cannot change the resposne type in synchronous XMLHTTPRequests
    //we can convert the string into a dataURL though
    var arr = new Uint8Array(this.response);
    // Convert the int array to a binary string
    // We have to use apply() as we are converting an *array*
    // and String.fromCharCode() takes one or more single values, not
    // an array.
    var raw = String.fromCharCode.apply(null,arr);

    // This is supported in modern browsers
    var b64=btoa(raw);
    var dataURL="data:image/jpeg;base64,"+b64;
    img.src = dataURL;
}

Umgehen, um die Benutzererfahrung zu verbessern

Etwas, das Sie tun können, ist Text, der nur in der Druckversion Ihrer Seite angezeigt wird (über @print css media) und die Meldung "Bilder werden noch geladen, Druckauftrag abbrechen und erneut versuchen" und wenn die Bilder vollständig geladen sind, entfernen Sie diesen "Wartet noch auf Ressourcen, wiederholen Sie die Nachricht" vom DOM. Darüber hinaus könnten Sie Ihren Hauptinhalt in ein Element einbetten, das die Anzeige umwandelt, wenn der Inhalt nicht geladen ist. Sie sehen also nur diese Meldung im Dialogfeld für die Druckvorschau.

Wenn Sie den Code, den Sie gepostet haben, verlassen, könnte dies in etwa wie folgt aussehen (siehe aktualisierte jsfiddle ):

CSS

.printing-not-ready-message{
  display:none;
}
@media print{
  .printing-not-ready-message{
    display:block;
  }
  .do-not-print-content{
    display:none;
  }
}

HTML

<div class="printing-not-ready-message">
Images are still loading please cancel your preview and try again shortly.
</div>
<div class="do-not-print-content">
    <h1>Welcome to my Lazy Page</h1>
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
    <p>Insert some comment about picture</p>
</div>

JavaScript

window.addEventListener('DOMContentLoaded', () => {
  img = document.querySelector('img');
  var isPrinting = window.matchMedia('print');
  isPrinting.addListener((media) => {
    if (media.matches) {
      img.src = 'http://unsplash.it/500/300/?image=705';
      //depending on how the lazy loading is done, the following might
      //exist in some other call, should happen after all images are loaded.
      //There is only 1 image in this example so this code can be called here.
      img.onload = ()=>{
          document.querySelector(".printing-not-ready-message").remove();
          document.querySelector(".do-not-print-content").className=""
      }
    }
  })
});
13
Arthur Weborg

Ich habe ein Lazy-Loading-JQuery-Plugin geschrieben, das das Anzeigen von Bildern beim Drucken mithilfe von window.onbeforeprint-Ereignissen und mediaQueryListeners unterstützt. https://github.com/msigley/Unveil-EX/

1
Chaoix

Ich bin der Autor des Skripts Vanilla-lazyload und habe kürzlich eine Funktion entwickelt, die das Drucken aller Bilder ermöglicht! 

Getesteter Cross-Browser mit diesem Repo-Code der Live hier .

Schauen Sie sich das an und lassen Sie mich wissen, was Sie denken! Ich bin natürlich offen für Anfragen zu GitHub.

1
verlok