2016-12-28 19 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); 
 
    } 
 
    }

我需要帮助。请。在JS

回答

1

印刷检测是可能的,在IE 5+,火狐6+,铬9+和Safari 5.1+。我猜你的失败尝试从Detecting Print Requests with JavaScript

你应该实现组合法。从查看您的代码:您可以收听仅适用于Chrome和Safari的window.matchMedia

您必须在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; 

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

感谢弧。当我在Chrome浏览器和Firefox浏览器上进行打印/打印预览时,他们会根据预期请求所有图像并提取_(在各个浏览器开发工具 - 网络中检查)_。但**浏览器的打印预览实用程序会在所有_these images_下载**之前渲染页面的其余部分。很明显,当我取消打印并重新点击打印时,所有图像都会按预期显示,因为图像已被抓取并存储在浏览器缓存中。我们不能假设用户第二次尝试。有什么方法可以解决吗?谢谢。 – nzkks

+0

@nzkks我会研究它 – arcs

+0

@nzkks它看起来不像你的问题的解决方案。现在,如果你需要这个功能,我看到的唯一方法是用'document.location.href =“”'在'beforePrint()'中重新加载页面。然后,您可以添加一个URL参数(例如'?print = true'),并在您的方法中,当存在该参数时,禁用延迟加载。 – arcs