京东有电子书可以购买,可以多端阅读。比如PC客户端,移动端,以及本文提到的PC网站端

先换个镜头,读书要记笔记(电子版本), 方便以后查阅。

镜头换回来,但是,我们为了方便肯定是想复制,下载啊,分享啊等,但是服务商一般是不允许你这么做的。

我了,在京东买了几本书,程序相关的,为了获取好的体验,在PC网站端阅读, 发现精彩之处,想去复制到笔记里面去。

结果,呵呵哒,结果连选中都不让。

更关键的是,这代码部分的显示是这样的。 辣眼睛啊。

所以,我打算hack一些,提升阅读体验。

  1. 允许选中
  2. 允许快捷复制, Control + C
  3. 允许右键复制
  4. 美化代码

经过网页的内容和节点分析,京东电子书PC网站端,是采用普通的div, p ,code等html标签,而不是pdf的插件或者canvas等。

那么我就有信心把你搞得面目全非,错了,服服帖帖。

1. 允许选中

原理

是通过在div上的style user-select: none 来实现的

<div class="JD_page" style="width: 675px;overflow: hidden;height: 100%;float: left;background-color: rgb(240, 240, 240);margin-top: 5px;font-size: 16px;/* user-select: none; */z-index: 0;" ... >....</div>

方案

那么就好办了,音乐起。为了省去麻烦,来个暴力模式。

* {
user-select: auto !important;
}

之后,就是创建一个style的标签,写入样式,挂载到head或者body里面就ok拉。

2. 允许快捷复制

原理:

拦截keydown,让你的键盘事件失灵。

方案:

  1. F12手动删除注册keydown的事件
  2. 代码删除注册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标签来包裹一下。

简单的包裹会产生两个问题

  1. 包裹一下后,代码占据的页面内容会变成,而京东电子书这块,限定了一个页面的高度为900px,超过部分隐藏。

    所以,我们在使用pre包裹code节点的同事,还需要调整页面块这里的样式。
  2. 电子是采取的分页加载,在分页加载之后,我们需要对新生成的code标签进行包裹。

包裹code元素的思路

  1. 选择出所有带id的code节点(经过观察,code节点分两类,一类是有id标签,一类是没有,简单说就是对应markdown里面的 ``` 和 `)
  2. 找到每个code节点的父节点
  3. 创建pre节点
  4. 插入pre节点到code节点之前
  5. code节点 挂载到 pre下
  6. 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();

分页加载后的想到的方案

  1. 可以起个定时器,几秒处理一下
  2. 监听document.scrollingElement(document.body)的高度变化
  3. 监听document.scrollingElement(document.body)的scroll事件
  4. 采用MutationObserver监听子节点是否有变化
  5. 拦截分页数据的HTTP请求
  6. 拦截执行滚动加载的事件

第一种方式简单粗暴,其实我很喜欢。

第二种方式不太好实现,分页加载后,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这种效果用截图是表达不出来的,得视频,但是木有。

上图,可以看到,因为代码被格式化,页面边长,但是内容都已经能完整显示。

最后,感谢大家的阅读,也希望能帮助到大家。

哦,忘了,怎么使用,还是截图。

京东阅读(web)体验优化的更多相关文章

  1. Web前端优化最佳实践及工具集锦

    Web前端优化最佳实践及工具集锦 发表于2013-09-23 19:47| 21315次阅读| 来源Googe & Yahoo| 118 条评论| 作者王果 编译 Web优化Google雅虎P ...

  2. Web 性能优化:21 种优化 CSS 和加快网站速度的方法

    这是 Web 性能优化的第 4 篇,上一篇在下面看点击查看: Web 性能优化:使用 Webpack 分离数据的正确方法 Web 性能优化:图片优化让网站大小减少 62% Web 性能优化:缓存 Re ...

  3. Web 性能优化: 图片优化让网站大小减少 62%

    摘要: 压缩各种格式的图片. 原文:Web 性能优化: 图片优化让网站大小减少 62% 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这是 Web 性能优化的第二篇,上一篇在下面看点 ...

  4. Web 性能优化: 使用 Webpack 分离数据的正确方法

    摘要: Webpack骚操作. 原文:Web 性能优化: 使用 Webpack 分离数据的正确方法 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 制定向用户提供文件的最佳方式可能是一 ...

  5. Linux实战教学笔记38:企业级Nginx Web服务优化实战(下)

    四,Nginx站点目录及文件URL访问控制 4.1 根据扩展名限制程序和文件访问 Web2.0时代,绝大多数网站都是以用户为中心多的,例如:bbs,blog,sns产品,这几个产品都有一个共同特点,就 ...

  6. 常见 Web 性能优化方式

    这篇文章是我阅读 Web Performance 101 之后的进行的粗糙的翻译作为笔记,英语还行的童鞋可以直接看原文. 这篇文章主要介绍了现代 web 加载性能(注意不涉及代码算法等),学习为什么加 ...

  7. Kindle阅读产品体验报告-随时随地畅享阅读

    产品入门-第一份产品体验报告Kindle阅读-随时随地畅享阅读时间:2018/11/18-11/22   Kindle阅读 一.产品概括 (1)体验环境 机型:荣耀8 系统:EMUI 8.0(Andr ...

  8. Web性能优化:图片优化

    程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...

  9. 关于大型网站技术演进的思考(十九)--网站静态化处理—web前端优化—上(11)

    网站静态化处理这个系列马上就要结束了,今天我要讲讲本系列最后一个重要的主题web前端优化.在开始谈论本主题之前,我想问大家一个问题,网站静态化处理技术到底是应该归属于web服务端的技术范畴还是应该归属 ...

  10. 关于WEB 性能优化 (摘抄)

    压缩源代码和图片 JavaScript文件源代码可以采用混淆压缩的方式,CSS文件源代码进行普通压缩,JPG图片可以根据具体质量来压缩为50%到70%,PNG可以使用一些开源压缩软件来压缩,比如24色 ...

随机推荐

  1. Python3-Django-1.开发环境搭建

    官网 https://www.djangoproject.com/ 安装 http://www.runoob.com/django/django-install.html 创建项目 方式一(命令行): ...

  2. 入门大数据---SparkSQL联结操作

    一. 数据准备 本文主要介绍 Spark SQL 的多表连接,需要预先准备测试数据.分别创建员工和部门的 Datafame,并注册为临时视图,代码如下: val spark = SparkSessio ...

  3. 入门大数据---Flume 简介及基本使用

    一.Flume简介 Apache Flume 是一个分布式,高可用的数据收集系统.它可以从不同的数据源收集数据,经过聚合后发送到存储系统中,通常用于日志数据的收集.Flume 分为 NG 和 OG ( ...

  4. shell基本正则表达式

    基本正则表达式 星号* 匹配它前面的字符串或正则表达式任意次(包括0次).比如,“1122*” 将匹配11+1个或多个2,其可能匹配的字符串将是112.1122.112222.11223343等 句点 ...

  5. python unittest自动测试框架

    编写函数或者类时进行测试,确保代码正常工作 python  unittest 模块提供了代码测试工具.按照定义测试包括两部分:管理测试依赖库的代码(称为‘固件’)和测试本身. 单元测试用于核实函数的某 ...

  6. 树形dp——三色二叉树

    题目描述 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": 0 该树没有子节点 1S1 该树有一个子节点,S1为其二叉树序列 1S1S2 ...

  7. JS断点调试,必备的javaScript的debug调试技巧

    1.断点调试是啥?难不难? 断点调试其实并不是多么复杂的一件事,简单的理解无外呼就是打开浏览器,打开sources找到js文件,在行号上点一下罢了.操作起来似乎很简单,其实很多人纠结的是,是在哪里打断 ...

  8. CF819B Mister B and PR Shifts 思维题

    分析 这道题\(n\leq10^{6}\),显然\(n^{2}\)的暴力是无法解决问题的 那么我们可以考虑数列的某一种性质 因为最终的答案是\(\sum{n \atop i=1} |p_i - i|\ ...

  9. 洛谷 P4408 [NOI2003]逃学的小孩

    题目传送门 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚, ...

  10. 解决idea中“系统找不到指定路径”的问题

    有时在其他工具中运行正确的项目,在idea中运行会报路径找不到的错误. 该路径是相对路径的情况下,很有可能是因为idea中的工作空间没有选择正确而导致的.设置工作空间: 该目录没有配置到你运行的模块, ...