demo open talk

课件. 又拍云 open talk 公开课 油猴脚本 —— 只为更好的交互体验

安装此脚本?
作者推荐脚本

您可能也喜欢知乎浏览助手

安装此脚本
  1. // ==UserScript==
  2. // 脚本名称
  3. // @name demo open talk
  4. // @namespace http://tampermonkey.net/
  5. // @version 0.2
  6. // @description 课件. 又拍云 open talk 公开课 油猴脚本 —— 只为更好的交互体验
  7. // @author You
  8. // 在哪些页面生效, 支持通配符
  9. // @match https://www.zhihu.com/question/*
  10. // GM_addStyle 油猴内置的 api, `@grant GM_addStyle` 的作用相当于 import, 这样就可以在当前页面调用 GM_addStyle 这个接口了. GM_addStyle 这个可以用来添加样式.
  11. // @grant GM_addStyle
  12. // ==/UserScript==
  13.  
  14. // 隐藏右边栏. display: none 是要隐藏选中的节点
  15. // 因为 CSS 中可能会存在多个样式渲染到同一个节点上, 为了达到我们想要的效果, 这些样式有一个优先级,
  16. // 使用 `!important` 就表明我们当前的样式优先级比较高
  17. GM_addStyle('.Question-sideColumn {display: none !important}');
  18. // 加宽内容栏
  19. // with 表示盒子的宽度,
  20. GM_addStyle('.Question-mainColumn {width: 1000px !important}');
  21.  
  22. (function() {
  23. 'use strict';
  24.  
  25. // Your code here...
  26. // 创建元素
  27. function createEle(eleName, text, attrs){
  28. let ele = document.createElement(eleName);
  29. // innerText 也就是 <p>text会被添加到这里</p>
  30. ele.innerText = text;
  31. // attrs 的类型是一个 map
  32. for (let k in attrs) {
  33. // 遍历 attrs, 给节点 ele 添加我们想要的属性
  34. ele.setAttribute(k, attrs[k]);
  35. }
  36. // 返回节点
  37. return ele;
  38. }
  39.  
  40. // 复制到剪贴板
  41. function updateClipboard(newClip) {
  42. // 把内容复制到剪贴板. then 是代表回调的意思
  43. navigator.clipboard.writeText(newClip).then(function() {
  44. // 一切都没问题的话会执行 alert 操作
  45. alert('succeed copy');
  46. }, function(err) {
  47. // 失败时执行的函数
  48. /* clipboard write failed */
  49. console.info('failed copy', err);
  50. alert('faild copy')
  51. });
  52. }
  53.  
  54. const added = [];
  55. // btnStyle 是一个我事先写好的样式.
  56. // 因为写样式调试的时间比较久,我就不一一向大家演示了.
  57. const 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';
  58.  
  59.  
  60. // 加转载按钮
  61. function addBtn() {
  62. // 获取回答列表
  63. // querySelectorAll 这个 api 可以获取一组 api 节点
  64. const all = document.querySelectorAll('div[class="List-item"]');
  65. for (let item of all) {
  66. // 定位到每个节点的 meta 节点
  67. const meta = item.querySelector('div[class="ContentItem-meta"]');
  68. // 因为知乎规则, 每个人只允许回答一次, 所以我们可以使用 who 作为每个答案的 id;
  69. // todo: 这个地方是有 bug 的, 因为知乎规则中是允许匿名回答的, 匿名的时候会导致当前节点的节点为空, 导致重复添加
  70. // 解决办法是, 多从 meta 中获取几个属性, 拼接成一个独一无二的 id, 这里为了演示, 简单起见, 暂不考虑这种情况.
  71. const who = meta.querySelector('meta[itemprop="url"]').getAttribute('content').split('/').pop();
  72. // added 是一个全局变量, 用来保存已经添加过按钮的节点.
  73. // 这步的作用是, 已经添加按钮节点不重复添加
  74. if (added.indexOf(who) > -1) {
  75. continue;
  76. }
  77. // createEle 是我封住的一个工具函数, 可以生成一个节点.
  78. const btn = createEle('button', '转载按钮', {style: btnStyle});
  79. // text 是我们选中的文本.
  80. const text = item.querySelector('div[class="RichContent-inner"]').innerText;
  81. // 给 btn 节点添加一个鼠标点击事件
  82. // 当 btn 节点接听到鼠标事件后, 会触发后面的方法
  83. // ()=>{}, 这种是箭头函数, 是 ES6 的语法.
  84. btn.addEventListener('click', ()=>{updateClipboard(text)});
  85. // 把创建好的 btn 节点添加到 meta 后面.
  86. meta.append(btn);
  87. // 添加了 btn后的推到 added 列表, 不再重复添加.
  88. added.push(who);
  89. }
  90. }
  91.  
  92. // 给 window 对象添加一个滚动事件, 当滚动时触发就执行对应的操作.
  93. window.addEventListener('scroll', addBtn);
  94.  
  95. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址