2013-08-29 46 views
2

問題是新的內容不會打印(更多的元素)。關於新增加的HTML的Javascript window.print()問題

當用戶點擊我的打印鏈接時,我會在window.print()被調用之前在文檔中添加更多html。

我使用ajax在打印之前爲書籍獲取更多章節。

代碼:

打印初始化:

var afterPrint = function() { 

    var timer = setInterval(function() { 

    afterContentPrint(); // Cleanup html (restore to initial state) 
    clearInterval(timer); 

    }, 900); 
} 
//window.onbeforeprint = beforePrint; 
window.onafterprint = afterPrint; 

事件打印點擊:

$("#print-test").click(function (e) { 

    e.preventDefault(); 

    beforeContentPrint(); // ajax call for additional content, finishing by calling window.print() 
}); 

在功能beforeContentPrint():

var jqxhr = $.ajax({ 

    type: "GET", 
    url: bookURL, 

    success: function(data) { 
    ..... 
    ..... 

    $(article).each(function() { 
     parent.append(article); 

    }); 
    }, 
    complete: function() { 
    var timer = setInterval(function() { 
     window.print(); 
    }, 900); 
    } 
} 

新的內容明顯增加到HTML文件,所以它應該工作。但是隻有最初的內容(在Ajax調用之前)纔會被打印出來。

此解決方案適用於IE和Firefox(onbeforeprint和onafterprint)。

使用window.matchMedia('print')似乎在Chrome中使用此邏輯可以正常工作。

+1

是否通過Ctrl + P打印預覽或打印輸出所有頁面? – user568109

回答

1

由於添加的元素沒有顯示,可能有點難以查明確切的問題,但通過追加/插入文檔添加元素並不總是適用於所有瀏覽器,最糟糕的情況下您需要通過代碼手動添加這些元素(document.createElement(),appendChild()等)。

在嘗試創建解決方法時,您可以嘗試使用MutationObservers來跟蹤您的文章元素的更改,這有助於您在正確更新DOM時觸發打印。在新的瀏覽器中支持相當不錯(你可能必須在某些地方使用前綴,f.ex. WebKitMutationObserver),而對於舊版本的瀏覽器,你可以提供一個後備 - 當然這隻會讓你滿意。

這將監視目標元素的變化並觸發回調。基於this article

通用示例:

var article = document.querySelector('#articleID'), 
    doPrint = false, // must be available in global/parent scope 
    o, 
    useFallback = (typeof MutationObserver !== 'undefined'); 


if (!useFallback) {  
    o = new MutationObserver(function(mutations) { 
     mutations.forEach(function(mutation) { 

      // you can do additional filtering here 
      // using the mutation object (.name, .type, ...) 

      if (doPrint) { 
       doPrint = false; 
       window.print(); 
      } 
     }); 
    }); 

    var cfg = { attributes: true, childList: true, characterData: true }; 

    o.observe(article, cfg); 
} 

現在觀察者正在運行,你可以在你的成功回調做修改:

var timer; // keep track of setTimeout so we can cancel it 

success: function(data) { 
    ... 
    ... 

$(article).each(function() { 

    parent.append(article); 

    }); 

    // after last element is added, add a "dummy" element 
    doPrint = true; 

    if (useFallback) { 
    // fallback to setTimeout or other solution 
    } 
    else { 
    parent.append('<br />'); 
    } 

} 

我做了online demo here其中規定了觀察員並添加了一些元素。打開控制檯查看操作。該演示可能太有限的數據方面來模擬您的情況,但可以用於查看過程。

這裏用於觸發打印對話框本身的機制可以討論如果是最好的 - 我只是爲了舉例而提供一個。

但是,您可以看到在向article添加內容時觸發了觀察者。這樣你就知道DOM已經更新了,應該可以打印了。只有添加的最後一個元素需要觸發打印,因此doPrint標誌。

如果你還沒有成功,你需要考慮手動添加元素的代碼方式,或者可能預先定義了一些你需要時注入的元素(如上所述,在不知道完整的場景的情況下,它必須與猜測) 。

0

它看起來像setInterval,clearInterval是什麼在搞砸你。更改爲setTimeout並擺脫afterprint函數中的clearInterval。我做了一個在FF和IE9中工作的小提琴。 Fiddle

complete: function() { 
     var timer = setTimeout(function() { 
     window.print(); 
     }, 900); 
    } 
+0

在調用print之前,我確實使用了'setTimeout'幾秒鐘,但它不起作用。我試圖通過使用'success:function(data){}'爲ajax和'complete:function(){}'來爲'window.print'分開這兩個過程,但它也沒有解決這個問題。嗯。 – gorn

1

我不知道爲什麼會發生這種情況,但有一個工作在mozilla文檔中;打印一個隱藏的iframe,然後你打開本書的更多章節,無需顯示。 下面的鏈接https://developer.mozilla.org/en-US/docs/Printing

下面的代碼:

<!doctype html> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<title>MDN Example</title> 
<script type="text/javascript"> 
function closePrint() { 
    document.body.removeChild(this.__container__); 
} 

function setPrint() { 
    this.contentWindow.__container__ = this; 
    this.contentWindow.onbeforeunload = closePrint; 
    this.contentWindow.onafterprint = closePrint; 
    this.contentWindow.print(); 
} 

function printPage (sURL) { 
    var oHiddFrame = document.createElement("iframe"); 
    oHiddFrame.onload = setPrint; 
    oHiddFrame.style.visibility = "hidden"; 
    oHiddFrame.style.position = "fixed"; 
    oHiddFrame.style.right = "0"; 
    oHiddFrame.style.bottom = "0"; 
    oHiddFrame.src = sURL; 
    document.body.appendChild(oHiddFrame); 
} 
</script> 
</head> 

<body> 
    <p><span onclick="printPage('externalPage.html');" style="cursor:pointer;text-decoration:underline;color:#0000ff;">Print external page!</span></p> 
</body> 
</html> 
1

1日嘗試:嘗試將ASYN:假在beforeContentPrint的AJAX請求,這樣的元素將首先加入,然後打印將被調用。

var jqxhr = $.ajax({ 

    type: "GET", 
    url: bookURL, 
    async:false, 
    success: function(data) { 
    ..... 
    ..... 

    $(article).each(function() { 
     parent.append(article); 

    }); 
    }, 
    complete: function() { 
    var timer = setInterval(function() { 
     window.print(); 
    }, 900); 
    } 
} 

2ndAttempt:看看Here如何陸續迫使一個函數的執行。 希望這有助於。

+0

OP在完成回調時有window.print,肯定會在成功後調用...顯然,異步不是問題 – j03w