目录

  • 一、 前言
  • 二、高质量代码的特征
  • 三、编程实践
  • 四、 实际代码
  • 五、 总结

你是否曾经为自己写的代码而感到懊恼?你是否想过如何才能写出高质量代码?那就不要错过这个话题!在这里,我们可以讨论什么是高质量代码,如何写出高质量代码等问题。无论你是初学者还是资深开发人员,都可以在这个话题下进行分享,汲取灵感和知识,共同提高自己的编程水平和工作效率。

一、 前言

低质量代码最可怕,
易生错,难维护。
BUG频发,影响大,
效率低,不规范。

二、高质量代码的特征

以下是一些高质量代码的特征:

  1. 可读性强:高质量代码应该易于阅读和理解,采用清晰的命名、注释和缩进,以及结构化的代码布局,可以使代码更加易于理解。

  2. 可维护性强:高质量代码应该易于修改和扩展,采用模块化的设计和代码重构,可以使代码更加易于维护。

  3. 可测试性强:高质量代码应该易于测试和调试,采用单元测试和集成测试等测试技术,可以使代码更加易于测试和调试。

  4. 安全性高:高质量代码应该具有良好的安全性,采用安全编码技术和安全测试技术,可以使代码更加安全可靠。

  5. 性能优良:高质量代码应该具有较好的性能,采用优化算法和数据结构,可以使代码更加高效。

  6. 代码规范:高质量代码应该符合代码规范,采用一致的代码风格和规范的编码习惯,可以使代码更加易于理解和维护。

  7. 可重用性高:高质量代码应该具有较好的可重用性,采用模块化设计和面向对象编程等技术,可以使代码更加易于重用。

三、编程实践

这是一个使用Tampermonkey(或Greasemonkey)脚本在网页中自动下载PDF文件的代码。具体来说,此脚本会监听 https://copyright.lib.*..**/pdfindex.jsp 页面。

代码中的注释已经很详细地解释了脚本中各个部分的功能和作用,这里简要介绍一下:

  • 脚本首先等待页面加载完毕,以便获得结题报告窗口的DOM元素。
  • 脚本在结题报告窗口下面插入一个按钮,用于启动PDF下载。
  • 当用户点击下载按钮时,脚本会自动遍历所有PDF页面并将其转换为一个单独的PDF文件。
  • PDF的每一页都是以图片的形式保存的,脚本会首先获取图片链接,然后使用jQuery的$.get()方法获取图片数据。这个数据在服务器端被压缩成了base64编码,并通过JSON格式返回给客户端。
  • 然后,脚本会将图片数据转换为Blob格式,并通过使用新的Image对象将其加载到页面中。这一步骤将确保jsPDF.addImage()方法只被调用一次,因为该方法需要从图片URL中获取图片数据。
  • 然后,脚本将Image对象添加到jsPDF中,以便在所有页面都添加完成后将它们保存为一个PDF文件。

总体来说,这个脚本使用了多种技术和工具,包括了异步函数、Promise、MutationObserver、jQuery和jsPDF。这使得脚本在处理多个页面和图片下载时非常有效和可靠。

四、 实际代码

// ==UserScript==
// @name         pdf_downloader
// @namespace    https://blog.rhilip.info/
// @version      1.0
// @description  下载pdf
// @author       DR-ZF-
// @match        https://copyright.lib.****.***.**/pdfindex.jsp*
// @require      https://unpkg.com/jspdf@2.3.0/dist/jspdf.umd.min.js
// @require      https://unpkg.com/jquery@3.6.0/dist/jquery.js
// ==/UserScript==/* globals $, jspdf */// 参考油猴NSFC_conclusion_downloader by Rhilip,进行改写
// Copy and edit from https://stackoverflow.com/a/61511955
function waitForElm(selector) {return new Promise(resolve => {if ($(selector).length > 0) {return resolve($(selector));}const observer = new MutationObserver(mutations => {if ($(selector).length > 0) {resolve($(selector));observer.disconnect();}});observer.observe(document.body, {childList: true,subtree: true});});
}(async function() {'use strict';// 等待页面加载const conclusionReportTab = await waitForElm('#tool_Zoom');// 准备交互按钮,并插入到页面中const downloadBtn = $('<button type="button" class="el-button el-button--default el-button--medium is-round">下载全文</button>');conclusionReportTab.after(downloadBtn);// 点击交互按钮时需要开始下载操作downloadBtn.click(async () => {downloadBtn.prop('disabled', true).addClass('is-disabled');if (!/无页面/.test(conclusionReportTab.text())) {// 获得项目信息const urlParams = new URLSearchParams(location.search);const dependUintID = urlParams.get('fid');// 准备需要的PDF文件,并删除初始页const doc = new jspdf.jsPDF();doc.deletePage(1);doc.setDocumentProperties({title: 'pdf_downloader',subject: location.href,creator: 'pdf_downloader'});// 核心下载方法const image = new Image();for (let i=1;;i++) {downloadBtn.text(`正在下载第 ${i} 页`);// 获得图片链接const response = await $.get('/jumpServlet?', { page: i, fid: dependUintID });console.log(response);if (!response){break; // 此处应该明确为false才break}const jsonResponse = JSON.parse(response);const { list } = jsonResponse;let firstSrc, firstIdif (Array.isArray(list) && list.length > 0) {const [firstItem] = list;if (firstItem.src && firstItem.id) {firstSrc = firstItem.src;firstId = firstItem.id;} else {console.error(`Unexpected response data. Missing 'src' or 'id' property. Response: ${JSON.stringify(response)}`);}} else {console.error(`Unexpected response data. 'list' property not found or empty array. Response: ${JSON.stringify(response)}`);}// 获得Blob形式的imageData,这样可以防止image.src和jsPDF.addImage会产生两次图片请求,浪费带宽// (实际变成了一次请求服务器和两次请求本地blob)try {const imageDataAsBlob = await $.ajax({url: firstSrc,method: 'GET',xhrFields: { responseType: 'blob'}});// 加载图片并获得图片的 width, height 属性image.src = URL.createObjectURL(imageDataAsBlob);await image.decode();// 将图片添加进PDF中doc.addPage([image.width, image.height], image.width < image.height ? 'p' : 'l');doc.addImage(image, "PNG", 0, 0, image.width, image.height);} catch (e) {break; // 如果中间有任何失败,则直接break}}// 我们并没法 await 保存过程,所以直接显示下载完成就好,浏览器处理好会自动显示下载文件doc.save(`PDF下载.pdf`);downloadBtn.text('下载完成');}});})();

五、 总结

这段代码的主要功能是从网页上下载 PDF 文件。以下是其中的优秀点:

  1. 使用了异步函数和 Promise:代码使用了 async 函数和 Promise 对象,使得在等待页面加载和图片下载等耗时操作时,代码可以继续执行其他任务,从而避免了页面阻塞或卡顿的情况。

  2. 使用了 MutationObserver:使用 MutationObserver 监听 DOM 树变化,当目标元素出现时再执行后续代码,可以提高页面加载速度和性能,同时避免了因页面加载慢而导致的代码执行错误。

  3. 代码可读性高:变量和函数名都具有语义化,注释清晰明了,代码结构清晰简洁,易于理解和维护。

  4. 使用了 jQuery 和 jspdf 库:代码使用了 jQuery 库简化了 DOM 操作,同时使用了 jspdf 库方便地生成 PDF 文件。

  5. 错误处理得当:代码对 HTTP 请求和其他异常情况进行了正确的处理,同时在出现异常时及时终止程序并给出相应的错误提示,防止代码出现严重的运行错误。

20230503 Javascript下载页面pdf的高质量代码相关推荐

  1. spark最新源码下载并导入到开发环境下助推高质量代码(Scala IDEA for Eclipse和IntelliJ IDEA皆适用)(以spark2.2.0源码包为例)(图文详解)...

    不多说,直接上干货! 前言   其实啊,无论你是初学者还是具备了有一定spark编程经验,都需要对spark源码足够重视起来. 本人,肺腑之己见,想要成为大数据的大牛和顶尖专家,多结合源码和操练编程. ...

  2. Github即将破百万的PDF:编写高质量代码改善JAVA程序的151个建议

    代码是我们前进的基石. 废话不多说直接把本书部分内容展示出来 目录 == 第1章Java开发中通用的方法和准则/1 建议1:不要在常量和变量中出现易混淆的字母/2 建议2:莫让常量蜕变成变量12 建议 ...

  3. 【备注】【C42】《编写高质量代码:改善Python程序的91个建议》PDF

    内容简介: 在通往"Python技术殿堂"的路上,本书将为你编写健壮.优雅.高质量的Python代码提供切实帮助!内容全部由Python编码的实践组成,从基本原则.惯用法.语法.库 ...

  4. 读书笔记:编写高质量代码--web前端开发修炼之道(二:5章)

    读书笔记:编写高质量代码--web前端开发修炼之道 这本书看得断断续续,不连贯,笔记也是有些马虎了,想了解这本书内容的童鞋可以借鉴我的这篇笔记,希望对大家有帮助. 笔记有点长,所以分为一,二两个部分: ...

  5. 荐书与免费送书:《编写高质量代码改善 Python 程序的 91 个建议》

    为了学习如何打理好微信公众号,Python猫我关注了好几个python技术公众号.然后发现这些同行们都在免费送资源,或者抽奖送书耶.于是,我也去参与抽奖,竟然侥幸抽中啦一本<Python数据科学 ...

  6. 《编写高质量代码:改善C#程序的157个建议》勘误表

    <编写高质量代码:改善C#程序的157个建议>中关于勘误的描述: 资源及勘误 通常情况下,一个问题的解决方案往往不止一种,你可能会不同意本书中的一些观点,甚至会强烈反对.没有关系,你可以通 ...

  7. [翻译Joel On Software]Joel测试:12步写出更高质量代码/The Joel Test: 12 Steps to Better Code

    Joel on Software The Joel Test: 12 Steps to Better Code Joel测试:12步写出更高质量代码 byJoel Spolsky Wednesday, ...

  8. 编写高质量代码改善java程序的151个建议——[110-117]异常及Web项目中异常处理

    编写高质量代码改善java程序的151个建议--[110-117]异常及Web项目中异常处理 原创地址:http://www.cnblogs.com/Alandre/(泥沙砖瓦浆木匠),需要转载的,保 ...

  9. python编写高质量代码_用 Python 编写干净、可测试、高质量的代码

    用 Python 编写干净.可测试.高质量的代码 Noah Gift 2010 年 12 月 20 日发布 简介 编写软件是人所承担的最复杂的任务之一.AWK 编程语言和 "K and R ...

最新文章

  1. python3 的encode 和 decode
  2. 温故而知新:MySQL 四种隔离级别,你还对答如流吗?
  3. 1.13 总结-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授
  4. 【Python】如何用Python来操作PDF文件,建议收藏
  5. Python基础(偏函数)
  6. Postman图片上传用法以及Required request part file is not present的解决方法
  7. 5年5亿美金,一年送出 1000 张训练卡,华为昇腾如何吸引AI开发者?
  8. CMatrix类 矩阵类 C++
  9. 超智能体,tensorflow
  10. IntelliJ IDEA导包快捷键以及创建方法
  11. 无线打印 airprint 服务器,怎么设置普通打印机也能airprint无线打印
  12. 卜若的代码笔记-机器学习基础-UCI数据库简介与Iris数据集分析
  13. 【Python爬虫系列】Python 爬取上海链家二手房数据
  14. 如何降低疾病监测的漏诊比率?一种新的分类学习算法
  15. 地对地导弹地对地导弹地对地导弹
  16. ruoyi-vue集成积木报表
  17. Cairo-基本概念
  18. PHP防红接口,域名防红php源代码
  19. 蚁群算法(ACO)求解路径规划
  20. 2021年西式面点师(高级)新版试题及涵盖考试最全题库免费练习

热门文章

  1. EasyExcel读写Excel
  2. 一篇文章教会你将nfc运用到极致
  3. 周易八卦——数字卦预测的程序实现
  4. Canvas drawImage在高清屏幕下变模糊,解决方案
  5. 仿个人税务 app html5_全城警惕!假个税APP正在抢你的钱!
  6. 【OpenGL】查看显卡对OpenGL的支持程度
  7. STM32学习笔记---TFT-LCD
  8. 树莓派基础之嵌入式开发概述
  9. nuxt框架Universal和Spa两种render mode的区别
  10. js将图片/文件等资源保存(下载)到本地