首先来首歌曲来放松一下吧!
一、准备工作
根据所学JS知识以及又拍云小哥直播的讲解实战开发的一个小脚本!
所有链接:
- 又拍云上直播地址:点击这里!
- 又拍云油猴脚本开发:点击这里!
- 我的油猴知乎实战脚本,点击这里!
二、实现功能
- 隐藏回答界面的右边侧栏,提升阅读舒适性!
- 加宽回答的可视区域,让您看的更加舒服!
- 增加一个一键转载按钮(一键复制),禁止转载的给出提示信息!
实现效果如下:
三、完整代码
脚本地址,点击这里!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
GM_addStyle('.Question-sideColumn {display: none !important}');
GM_addStyle('.Question-mainColumn {width: 1000px !important}');
(function() { 'use strict'; function createElement(eleName, text, attrs){ let ele = document.createElement(eleName); ele.innerText = text; for(let k in attrs){ ele.setAttribute(k, attrs[k]); } return ele; } function addToClipboard(text){ navigator.clipboard.writeText(text).then(function() { alert('succeed copy'); }, function(err) { console.info('failed copy', err); alert('faild copy') }); } let added = []; let btnStyle = 'background-color: #0084ff; margin-top: 15px; margin-bottom: 15px; margin-left:-5px; cursor:pointer; color: #fff; border-radius: 3px; border: 1px solid; padding: 3px 6px'; function addFirstBtn(){ let first = document.querySelector("#root > div > main > div > div.Question-main > div.ListShortcut > div > div.Card.AnswerCard"); let meta = first.querySelector('div[class="ContentItem-meta"]'); let who = meta.querySelector('meta[itemprop="url"]').getAttribute('content').split('/').pop(); if(added.indexOf(who) === -1){ added.push(who); let btn = createElement('button', '转载按钮', {style: btnStyle}); let text = first.querySelector('div[class="RichContent-inner"]').innerText; btn.addEventListener('click', ()=>{addToClipboard(text)}); meta.append(btn); } } function addBtn(){ let all = document.querySelectorAll('div[class="List-item"]'); for(let item of all){ let meta = item.querySelector('div[class="ContentItem-meta"]'); let who = meta.querySelector('meta[itemprop="url"]').getAttribute('content').split('/').pop(); if(added.indexOf(who) !== -1){ continue; } added.push(who); let btn = createElement('button', '转载按钮', {style: btnStyle}); let text = item.querySelector('div[class="RichContent-inner"]').innerText; btn.addEventListener('click', ()=>{addToClipboard(text)}); meta.append(btn); } } window.addEventListener('load', addBtn); window.addEventListener('load', addFirstBtn); window.addEventListener('scroll', addBtn); })();
|
四、代码实现介绍
模仿又拍云小哥demo实现,由于小哥原版的有一些bug,我做了简单修复,具体内容如下:
- 修复回答界面点击查看全部回答后第一个回答无法加载按钮的bug
- 修复点进回答界面第一个回答按钮无法加载需要触发滚动事件的bug
- 修复来修复去,又多了一个bug,点进查看全部回答界面似乎又不进行加载脚本了,我心累了!原脚本也有这个bug。
1、油猴脚本头部
1 2 3 4 5 6 7 8 9
| // ==UserScript== // @name 知乎一键转载 // @namespace http://tampermonkey.net/ // @version 0.5 // @description 模仿又拍云 demo 实现并修改的知乎一件转载,可以一键复制到剪贴板!隐藏知乎右边侧栏,加宽回答可视区域,使您阅读的更加舒服!欢迎食用! // @author NXD // @match https://www.zhihu.com/question/* // @grant GM_addStyle // ==/UserScript==
|
- name:脚本名称
- version:版本
- description:脚本描述
- author:作者
- match:匹配生效的网址
- grant:导入油猴官方的API
- namespace:是命名空间,可以用你的网站名称
其他关键词及API请访问油猴文档!
2、相关函数介绍
2.1 GM_addStyle
油猴官方实现的接口用于写更方便的写CSS!
怎么写CSS就怎么使用该方法。
1
| GM_addStyle('.Question-mainColumn {width: 1000px !important}');
|
2.2 createElement
创建元素函数!
createElement(eleName, text, attrs)
:元素名,元素内的文本信息,以及属性接收一个对象(即{}参数)
2.3 addToClipboard
复制到剪贴板函数!
传入text参数,为复制的文本信息。
2.4 addFirstBtn
由于不点击查看全部回答第一个回答和后续回答不一样,要格外设置一个函数去处理第一个回答!
第一个回答的 class:Card AnswerCard
点击查看全部回答后的 class:Card MoreAnswers
2.5 addBtn
同样:处理没点击查看全部回答的后续回答(除了第一个不一样的)以及点击查看全部回答的所有回答。
3、加载事件设置
window.addEventListener('load', addFirstBtn)
:处理第一个不一样的回答
window.addEventListener('load', addBtn)
:主要用于处理点击查看全部回答后的回答,加载完调用。
window.addEventListener('scroll', addBtn)
:同时处理点击或每点击后续流式加载出现的回答,随滚动条加载。
防止出现重复添加按钮,使用added
数组来判断:added.indexOf(who) !== -1
1 2 3 4 5 6 7 8
|
window.addEventListener('load', addBtn);
window.addEventListener('load', addFirstBtn);
window.addEventListener('scroll', addBtn);
|
五、总结
- 一个脚本的编写需要去网页找到对应的元素class,获取到位置再进行操作
- 需要修复好多的bug,泪目啊!
- 需要有HTML CSS JS知识,最好有强硬的JS能力。
- 这一次脚本编写也是极大的锻炼了我的JS实战能力,掌握了一些用法。虽然本脚本实现的功能较为简单与简陋,甚至有好多bug,但是我会在后续不断改进,完善的!
很开心的一次实战!