内容简介:京东有电子书可以购买,可以多端阅读。比如PC客户端,移动端,以及本文提到的先换个镜头,读书要记笔记(电子版本), 方便以后查阅。镜头换回来,但是,我们为了方便肯定是想复制,下载啊,分享啊等,但是服务商一般是不允许你这么做的。
京东有电子书可以购买,可以多端阅读。比如PC客户端,移动端,以及本文提到的 PC网站端 。
先换个镜头,读书要记笔记(电子版本), 方便以后查阅。
镜头换回来,但是,我们为了方便肯定是想复制,下载啊,分享啊等,但是服务商一般是不允许你这么做的。
我了,在京东买了几本书,程序相关的,为了获取好的体验,在 PC网站端 阅读, 发现精彩之处,想去复制到笔记里面去。
结果,呵呵哒,结果连选中都不让。
更关键的是,这代码部分的显示是这样的。 辣眼睛啊。
所以,我打算hack一些,提升阅读体验。
- 允许选中
- 允许快捷复制, Control + C
- 允许右键复制
- 美化代码
经过网页的内容和节点分析,京东电子书PC网站端,是采用普通的div, p ,code等html标签,而不是pdf的插件或者canvas等。
那么我就有信心把你搞得面目全非,错了,服服帖帖。
1. 允许选中
原理
是通过在div上的style user-select: none
来实现的
<div ... >....</div>
方案
那么就好办了,音乐起。为了省去麻烦,来个暴力模式。
* { user-select: auto !important; }
之后,就是创建一个style的标签,写入样式,挂载到head或者body里面就ok拉。
2. 允许快捷复制
原理:
拦截keydown,让你的键盘事件失灵。
方案:
- F12手动删除注册keydown的事件
- 代码删除注册keydown的事件
这里采用2方案,问题来了,如何找到某个元素注册的事件。
chrome 控制台提供了一个 getEventListeners的方法,有那味了,战歌起:
// 删除监听事件 function cRemoveListener(el, option) { if (!el || !option) { return; } el.removeEventListener(option.type, option.listener, option.useCapture || false); } // 删除指定的监听事件 function cRemoveListeners(el, eventName) { var allListeners = getEventListeners(document); var listeners = allListeners[eventName]; if (listeners && listeners.length > 0) { for (let i = listeners.length - 1; i >= 0; i--) { const lsOption = listeners[i]; cRemoveListener(el, lsOption); } } } // 允许 ctl + c 复制 // document.body keydown 事件 cRemoveListeners(document, "keydown");
3. 允许右键复制
原理
邮件菜单一般都是通过contextmenu事件,所以同上
方案
同允许快捷复制
// 允许右键 // document.body contextmenu 事件 cRemoveListeners(document, "contextmenu");
4. 美化代码
原理
京东电子书,是对代码部分使用code标签来展示的。
方案
为了保持断行,只需要使用pre标签来包裹一下。
简单的包裹会产生两个问题
- 包裹一下后,代码占据的页面内容会变成,而京东电子书这块,限定了一个页面的高度为900px,超过部分隐藏。
所以,我们在使用pre包裹code节点的同事,还需要调整页面块这里的样式。 - 电子是采取的分页加载,在分页加载之后,我们需要对新生成的code标签进行包裹。
包裹code元素的思路
- 选择出所有带id的code节点(经过观察,code节点分两类,一类是有id标签,一类是没有,简单说就是对应markdown里面的 ``` 和 `)
- 找到每个code节点的父节点
- 创建pre节点
- 插入pre节点到code节点之前
- code节点 挂载到 pre下
- code添加code-hacked class,标签已经被hacked,避免重复被hacked
战歌起,上代码
// 创建节点 function createElement(tagName) { const el = document.createElement(tagName); return el; } // 包裹code节点 function adoptCodeNode(el) { if (!el || el.tagName !== "CODE") return; const parent = el.parentElement; // 节点前插入 const preElement = createElement("pre"); preElement.classList.add("pre-hacked"); parent.insertBefore(preElement, el); // 导入节点 preElement.appendChild(el); el.classList.add("code-hacked"); }; function adoptAllCodes() { const codesEls = Array.from(document.querySelectorAll("code[id]:not(.code-hacked)")); for (let i = codesEls.length - 1; i >= 0; i--) { adoptCodeNode(codesEls[i]); } } adoptAllCodes();
分页加载后的想到的方案
- 可以起个定时器,几秒处理一下
- 监听document.scrollingElement(document.body)的高度变化
- 监听document.scrollingElement(document.body)的scroll事件
- 采用MutationObserver监听子节点是否有变化
- 拦截分页数据的HTTP请求
- 拦截执行滚动加载的事件
第一种方式简单粗暴,其实我很喜欢。
第二种方式不太好实现,分页加载后,window本身没有触发resize事件,window外的节点本身没有监听resize的能力(IE除外),当然可以通过节点resize监听, 但是高度的变化依旧没法。
第三种方式,倒是可行,不过scroll事件触发频率很高,当然可以节流,也还不错。
第四种 ,可行性高,PC兼容性行也不错,性能也相对好一点。
第五种, 代码复杂度会高一些。
战歌起:
// 监听高度变化 // https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver function hackLoadmore() { const targetNode = document.scrollingElement; // 观察器的配置(需要观察什么变动) const config = { childList: true, subtree: true }; let preScrollHeight = targetNode.scrollHeight; // 当观察到变动时执行的回调函数 const callback = function (mutationsList, observer) { // Use traditional 'for loops' for IE 11 console.log("MutationObserver"); for (let mutation of mutationsList) { if (mutation.type !== 'childList') { return; } const scollHeight = targetNode.scrollHeight if (scollHeight == preScrollHeight) { return; } preScrollHeight = scollHeight; setTimeout(() => { adoptAllCodes(); }, 2000) } }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(callback); // 以上述配置开始观察目标节点 observer.observe(targetNode, config); }
基本的问题都解决了,上图。
上图可以看到
- 代码已经格式化
-
可以右键选择
当然ctrl + c这种效果用截图是表达不出来的,得视频,但是木有。
上图,可以看到,因为代码被格式化,页面边长,但是内容都已经能完整显示。
最后,感谢大家的阅读,也希望能帮助到大家。
哦,忘了,怎么使用,还是截图。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 《Flutter 实战》开源电子书
- 电子书 NoSQL精粹.pdf
- 开始一本开源电子书《Kubernetes指南》
- 开源电子书项目FBReader初探(一)
- 开源电子书项目FBReader初探(二)
- 开源电子书项目FBReader初探(三)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
轻量级Django
茱莉亚·埃尔曼 (Julia Elman)、马克·拉温 (Mark Lavin) / 侯荣涛、吴磊 / 中国电力出版社; 第1版 / 2016-11-1 / 35.6
自Django 创建以来,各种各样的开源社区已经构建了很多Web 框架,比如JavaScript 社区创建的Angular.js 、Ember.js 和Backbone.js 之类面向前端的Web 框架,它们是现代Web 开发中的先驱。Django 从哪里入手来适应这些框架呢?我们如何将客户端MVC 框架整合成为当前的Django 基础架构? 本书讲述如何利用Django 强大的“自支持”功......一起来看看 《轻量级Django》 这本书的介绍吧!