2016-12-28 4 views
2

Я использую ленивый груз функция для изображений в разделе моей веб-страницы. (В основном отображаются изображения, отображаемые в окне . Остальные не загружаются с сервера.) Следующий JavaScript работает.Что не так с этой логикой функций lazyload для поддержки печатных носителей?

Пример использования: img class="lazy" src="/images/pixel.gif" data-src="/images/actual-image.jpg" alt="alt text"

стороны информация: Чуть ниже выше тег изображения Я также имею не-скрипт тега ниже тег изображений для поддержки не-JavaScript ситуации.

Для краткости я не прибавило CSS или HTML в фрагменте. Сожалею.

Рабочая JavaScript:

var lazy = []; 
 
    registerListener('load', setLazy); 
 
    registerListener('load', lazyLoad); 
 
    registerListener('scroll', lazyLoad); 
 
    registerListener('resize', lazyLoad); 
 
    function setLazy(){ 
 
    lazy = document.getElementsByClassName('lazy'); 
 
    } 
 
    function lazyLoad(){ 
 
    for(var i=0; i<lazy.length; i++){ 
 
     if(isInViewport(lazy[i])){ 
 
     if (lazy[i].getAttribute('data-src')){ 
 
      lazy[i].src = lazy[i].getAttribute('data-src'); 
 
      lazy[i].removeAttribute('data-src'); 
 
     } 
 
     } 
 
    } 
 
    cleanLazy(); 
 
    } 
 
    function cleanLazy(){ 
 
    lazy = Array.prototype.filter.call(lazy, function(l){ return l.getAttribute('data-src');}); 
 
    } 
 
    function isInViewport(el){ 
 
    var rect = el.getBoundingClientRect(); 
 
    return (
 
     rect.bottom >= 0 && 
 
     rect.right >= 0 && 
 
     rect.top <= (window.innerHeight || document.documentElement.clientHeight) && 
 
     rect.left <= (window.innerWidth || document.documentElement.clientWidth) 
 
    ); 
 
    } 
 
    function registerListener(event, func) { 
 
    if (window.addEventListener) { 
 
     window.addEventListener(event, func); 
 
    } else { 
 
     window.attachEvent('on' + event, func); 
 
    } 
 
    }

Технически скрипт ленивый нагрузки принимает URL изображения в атрибуте данных-Src и заменить его в атрибут Src для изображений, показанных в рамках окно видового окна.

Потребность/Требование:

при печати веб-страницы, я хотел бы, чтобы увидеть все изображения в печати (или PDF/физический печатный лист).

Выпуск:

Если свитки пользователя через весь набор изображений, не будут пустыми или черными заполнители (на основе различных браузеров).

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

Это мой неработающий скрипт. Сценарий нуждается в исправлении.

var lazy = []; 
 
    registerListener('load', setLazy); 
 
    registerListener('load', checkPrintMedia); 
 
    registerListener('scroll', lazyLoad); 
 
    registerListener('resize', lazyLoad); 
 
    function setLazy(){ 
 
    lazy = document.getElementsByClassName('lazy'); 
 
    } 
 
    function checkPrintMedia(){ 
 
    if (window.matchMedia) { 
 
     var mediaQueryList1 = window.matchMedia('print'); 
 
     mediaQueryList1.addListener(function(mql) { 
 
     if (mql.matches) { 
 
      for(var i=0; i<lazy.length; i++){ 
 
      if (lazy[i].getAttribute('data-src')){ 
 
       lazy[i].src = lazy[i].getAttribute('data-src'); 
 
       lazy[i].removeAttribute('data-src'); 
 
      } 
 
      } 
 
      cleanLazy(); 
 
     } 
 
     else{ 
 
      lazyLoad(); 
 
     } 
 
     }); 
 
    } 
 
    } 
 
    function lazyLoad(){ 
 
    for(var i=0; i<lazy.length; i++){ 
 
     if(isInViewport(lazy[i])){ 
 
     if (lazy[i].getAttribute('data-src')){ 
 
      lazy[i].src = lazy[i].getAttribute('data-src'); 
 
      lazy[i].removeAttribute('data-src'); 
 
     } 
 
     } 
 
    } 
 
    cleanLazy(); 
 
    } 
 
    function cleanLazy(){ 
 
    lazy = Array.prototype.filter.call(lazy, function(l){ return l.getAttribute('data-src');}); 
 
    } 
 
    function isInViewport(el){ 
 
    var rect = el.getBoundingClientRect(); 
 
    return (
 
     rect.bottom >= 0 && 
 
     rect.right >= 0 && 
 
     rect.top <= (window.innerHeight || document.documentElement.clientHeight) && 
 
     rect.left <= (window.innerWidth || document.documentElement.clientWidth) 
 
    ); 
 
    } 
 
    function registerListener(event, func) { 
 
    if (window.addEventListener) { 
 
     window.addEventListener(event, func); 
 
    } else { 
 
     window.attachEvent('on' + event, func); 
 
    } 
 
    }

мне нужна помощь. Пожалуйста.

ответ

1

Обнаружение печати в JS возможно в IE 5+, Firefox 6+, Chrome 9+ и Safari 5.1+. Я думаю, ваша неудачная попытка - от Detecting Print Requests with JavaScript

Вы должны реализовать Комбинированный подход. От взгляда на ваш код: вы слушаете на window.matchMedia, который работает только в Chrome и Safari.

Необходимо также прослушать window.onbeforeprint. Что-то вроде этого.

var beforePrint = function() { 
    for(var i=0; i<lazy.length; i++){ 
     if (lazy[i].getAttribute('data-src')){ 
      lazy[i].src = lazy[i].getAttribute('data-src'); 
      lazy[i].removeAttribute('data-src'); 
     } 
    } 
    cleanLazy(); 
} 

if (window.matchMedia) { 
    var mediaQueryList = window.matchMedia('print'); 
    mediaQueryList.addListener(function(mql) { 
     if (mql.matches) beforePrint(); 
    }) 
} 

window.onbeforeprint = beforePrint; 

Update 2

Как оказалось, проблема в том, что печать не будет ждать изображения для загрузки, даже во время ожидания внутри beforePrint.

Способ, которым я решаю это решить, - перезагрузить страницу в beforePrint и добавить параметр. Это будет в головке .

var reloadForPrint = function() { 
    if(location.search.indexOf('print') === -1) { 
     var url = window.location.href; 
     if (url.indexOf('?') > -1) window.location.href = url += '&print' 
     else window.location.href = url += '?print' 
    } 
} 
window.matchMedia && window.matchMedia('print').addListener(function(mql) {if (mql.matches) reloadForPrint()}) 
window.onbeforeprint = reloadForPrint 

Теперь при загрузке страницы снова проверить для этого параметра, отключить LazyLoad и выполнить метод window.print(). Это было бы в теге скрипта после</body>. (убедитесь, что остальная часть вашего сценария загружена до этого, это должен быть последний блок)

if(location.search.indexOf('print') > -1) { 
    for(var i=0; i<lazy.length; i++){ 
     if (lazy[i].getAttribute('data-src')){ 
      lazy[i].src = lazy[i].getAttribute('data-src'); 
      lazy[i].removeAttribute('data-src'); 
     } 
    } 
    cleanLazy(); 
    window.print() 
} 

Что это будет делать?

В принципе, когда кто-то хочет распечатать, он перезагрузит страницу и добавит параметр ?print к URL-адресу. Когда этот параметр присутствует, все изображения будут загружены, и команда печати будет выполнена программно. Однако на этот раз он будет ожидать загрузки всех изображений.

+0

Спасибо дуги. Когда я делаю Print/Print Preview в браузерах Chrome и Firefox, они делают запросы для всех изображений, как ожидалось, и выбирает _ (проверяется в соответствующих инструментах разработчика браузера - Network) _. Но ** Утилита предварительного просмотра броузера браузера отображает остальную часть страницы, прежде чем все _these images_ будут загружены **. Очевидно, что когда я отменю печать и повторно нажимаю на печать, все изображения отображаются так, как ожидалось, потому что изображения уже получены и сохранены в кеше браузера. Мы не можем повторить попытку пользователя во второй раз. Есть ли способ исправить? Благодарю. – nzkks

+0

@nzkks Я рассмотрю его – arcs

+0

@nzkks не похоже, что есть решение вашей проблемы. Теперь, если вам нужна эта функция, единственный способ, который я вижу, - перезагрузить страницу в 'beforePrint()' с помощью 'document.location.href =" "'. Затем вы можете добавить параметр URL (например, '? Print = true'), и в вашем методе, когда он присутствует, отключите ленивую загрузку. – arcs