jQuery.print

jQuery.print库,网页打印库

目前為 2018-02-28 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/38955/254772/jQueryprint.js

  1. /* @license
  2. * jQuery.print, version 1.5.1
  3. * (c) Sathvik Ponangi, Doers' Guild
  4. * Licence: CC-By (http://creativecommons.org/licenses/by/3.0/)
  5. *--------------------------------------------------------------------------*/
  6. (function ($) {
  7. "use strict";
  8. // A nice closure for our definitions
  9. function getjQueryObject(string) {
  10. // Make string a vaild jQuery thing
  11. var jqObj = $("");
  12. try {
  13. jqObj = $(string)
  14. .clone();
  15. } catch (e) {
  16. jqObj = $("<span />")
  17. .html(string);
  18. }
  19. return jqObj;
  20. }
  21.  
  22. function printFrame(frameWindow, content, options) {
  23. // Print the selected window/iframe
  24. var def = $.Deferred();
  25. try {
  26. frameWindow = frameWindow.contentWindow || frameWindow.contentDocument || frameWindow;
  27. var wdoc = frameWindow.document || frameWindow.contentDocument || frameWindow;
  28. if(options.doctype) {
  29. wdoc.write(options.doctype);
  30. }
  31. wdoc.write(content);
  32. wdoc.close();
  33. var printed = false;
  34. var callPrint = function () {
  35. if(printed) {
  36. return;
  37. }
  38. // Fix for IE : Allow it to render the iframe
  39. frameWindow.focus();
  40. try {
  41. // Fix for IE11 - printng the whole page instead of the iframe content
  42. if (!frameWindow.document.execCommand('print', false, null)) {
  43. // document.execCommand returns false if it failed -http://stackoverflow.com/a/21336448/937891
  44. frameWindow.print();
  45. }
  46. // focus body as it is losing focus in iPad and content not getting printed
  47. $('body').focus();
  48. } catch (e) {
  49. frameWindow.print();
  50. }
  51. frameWindow.close();
  52. printed = true;
  53. def.resolve();
  54. }
  55. // Print once the frame window loads - seems to work for the new-window option but unreliable for the iframe
  56. $(frameWindow).on("load", callPrint);
  57. // Fallback to printing directly if the frame doesn't fire the load event for whatever reason
  58. setTimeout(callPrint, options.timeout);
  59. } catch (err) {
  60. def.reject(err);
  61. }
  62. return def;
  63. }
  64.  
  65. function printContentInIFrame(content, options) {
  66. var $iframe = $(options.iframe + "");
  67. var iframeCount = $iframe.length;
  68. if (iframeCount === 0) {
  69. // Create a new iFrame if none is given
  70. $iframe = $('<iframe height="0" width="0" border="0" wmode="Opaque"/>')
  71. .prependTo('body')
  72. .css({
  73. "position": "absolute",
  74. "top": -999,
  75. "left": -999
  76. });
  77. }
  78. var frameWindow = $iframe.get(0);
  79. return printFrame(frameWindow, content, options)
  80. .done(function () {
  81. // Success
  82. setTimeout(function () {
  83. // Wait for IE
  84. if (iframeCount === 0) {
  85. // Destroy the iframe if created here
  86. $iframe.remove();
  87. }
  88. }, 1000);
  89. })
  90. .fail(function (err) {
  91. // Use the pop-up method if iframe fails for some reason
  92. console.error("Failed to print from iframe", err);
  93. printContentInNewWindow(content, options);
  94. })
  95. .always(function () {
  96. try {
  97. options.deferred.resolve();
  98. } catch (err) {
  99. console.warn('Error notifying deferred', err);
  100. }
  101. });
  102. }
  103.  
  104. function printContentInNewWindow(content, options) {
  105. // Open a new window and print selected content
  106. var frameWindow = window.open();
  107. return printFrame(frameWindow, content, options)
  108. .always(function () {
  109. try {
  110. options.deferred.resolve();
  111. } catch (err) {
  112. console.warn('Error notifying deferred', err);
  113. }
  114. });
  115. }
  116.  
  117. function isNode(o) {
  118. /* http://stackoverflow.com/a/384380/937891 */
  119. return !!(typeof Node === "object" ? o instanceof Node : o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string");
  120. }
  121. $.print = $.fn.print = function () {
  122. // Print a given set of elements
  123. var options, $this, self = this;
  124. // console.log("Printing", this, arguments);
  125. if (self instanceof $) {
  126. // Get the node if it is a jQuery object
  127. self = self.get(0);
  128. }
  129. if (isNode(self)) {
  130. // If `this` is a HTML element, i.e. for
  131. // $(selector).print()
  132. $this = $(self);
  133. if (arguments.length > 0) {
  134. options = arguments[0];
  135. }
  136. } else {
  137. if (arguments.length > 0) {
  138. // $.print(selector,options)
  139. $this = $(arguments[0]);
  140. if (isNode($this[0])) {
  141. if (arguments.length > 1) {
  142. options = arguments[1];
  143. }
  144. } else {
  145. // $.print(options)
  146. options = arguments[0];
  147. $this = $("html");
  148. }
  149. } else {
  150. // $.print()
  151. $this = $("html");
  152. }
  153. }
  154. // Default options
  155. var defaults = {
  156. globalStyles: true,
  157. mediaPrint: false,
  158. stylesheet: null,
  159. noPrintSelector: ".no-print",
  160. iframe: true,
  161. append: null,
  162. prepend: null,
  163. manuallyCopyFormValues: true,
  164. deferred: $.Deferred(),
  165. timeout: 750,
  166. title: null,
  167. doctype: '<!doctype html>'
  168. };
  169. // Merge with user-options
  170. options = $.extend({}, defaults, (options || {}));
  171. var $styles = $("");
  172. if (options.globalStyles) {
  173. // Apply the stlyes from the current sheet to the printed page
  174. $styles = $("style, link, meta, base, title");
  175. } else if (options.mediaPrint) {
  176. // Apply the media-print stylesheet
  177. $styles = $("link[media=print]");
  178. }
  179. if (options.stylesheet) {
  180. // Add a custom stylesheet if given
  181. $styles = $.merge($styles, $('<link rel="stylesheet" href="' + options.stylesheet + '">'));
  182. }
  183. // Create a copy of the element to print
  184. var copy = $this.clone();
  185. // Wrap it in a span to get the HTML markup string
  186. copy = $("<span/>")
  187. .append(copy);
  188. // Remove unwanted elements
  189. copy.find(options.noPrintSelector)
  190. .remove();
  191. // Add in the styles
  192. copy.append($styles.clone());
  193. // Update title
  194. if (options.title) {
  195. var title = $("title", copy);
  196. if (title.length === 0) {
  197. title = $("<title />");
  198. copy.append(title);
  199. }
  200. title.text(options.title);
  201. }
  202. // Appedned content
  203. copy.append(getjQueryObject(options.append));
  204. // Prepended content
  205. copy.prepend(getjQueryObject(options.prepend));
  206. if (options.manuallyCopyFormValues) {
  207. // Manually copy form values into the HTML for printing user-modified input fields
  208. // http://stackoverflow.com/a/26707753
  209. copy.find("input")
  210. .each(function () {
  211. var $field = $(this);
  212. if ($field.is("[type='radio']") || $field.is("[type='checkbox']")) {
  213. if ($field.prop("checked")) {
  214. $field.attr("checked", "checked");
  215. }
  216. } else {
  217. $field.attr("value", $field.val());
  218. }
  219. });
  220. copy.find("select").each(function () {
  221. var $field = $(this);
  222. $field.find(":selected").attr("selected", "selected");
  223. });
  224. copy.find("textarea").each(function () {
  225. // Fix for https://github.com/DoersGuild/jQuery.print/issues/18#issuecomment-96451589
  226. var $field = $(this);
  227. $field.text($field.val());
  228. });
  229. }
  230. // Get the HTML markup string
  231. var content = copy.html();
  232. // Notify with generated markup & cloned elements - useful for logging, etc
  233. try {
  234. options.deferred.notify('generated_markup', content, copy);
  235. } catch (err) {
  236. console.warn('Error notifying deferred', err);
  237. }
  238. // Destroy the copy
  239. copy.remove();
  240. if (options.iframe) {
  241. // Use an iframe for printing
  242. try {
  243. printContentInIFrame(content, options);
  244. } catch (e) {
  245. // Use the pop-up method if iframe fails for some reason
  246. console.error("Failed to print from iframe", e.stack, e.message);
  247. printContentInNewWindow(content, options);
  248. }
  249. } else {
  250. // Use a new window for printing
  251. printContentInNewWindow(content, options);
  252. }
  253. return this;
  254. };
  255. })(jQuery);