扇贝辅助

不用贝壳即可查看听力提示, 修改导航栏,方便炼句

  1. // ==UserScript==
  2. // @name 扇贝辅助
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description 不用贝壳即可查看听力提示, 修改导航栏,方便炼句
  6. // @author How
  7. // @match https://www.shanbay.com/*
  8. // @match https://web.shanbay.com/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // 一些变量
  17. window.shanbayLinks = {
  18. 'sentence-review': 'https://www.shanbay.com/sentence/review/',
  19. 'listen-link': 'https://www.shanbay.com/listen/',
  20. 'listen-with-hint': [ 'https://www.shanbay.com/listen/sentence',
  21. 'https://www.shanbay.com/listen/review'],
  22. };
  23.  
  24. window.shanbayConfig = {
  25. /* 修改“听力”链接,使其指向“精听”页面,而不是让我下载手机app */
  26. 'change-listen-nav': true,
  27. /* 在导航栏插入“炼句”的tab */
  28. 'insert-sentence-review-nav': true,
  29. /* 听听力的时候,免费查看提示 */
  30. 'free-listen-hint': true,
  31. }
  32. window.shanbayScript = {}
  33. window.shanbayScript.hint_input_dom = undefined;
  34. // Your code here...
  35.  
  36. // 修改导航栏
  37. changeNavBar();
  38.  
  39. // 修改听力页面,添加一个悬停在页面中的按钮
  40. let changedPage = false;
  41. if (window.shanbayConfig['free-listen-hint']) {
  42. for (let i = 0 ; i < window.shanbayLinks['listen-with-hint'].length ; i++) {
  43. console.log('trigger');
  44. if (!changedPage && window.location.href.startsWith(window.shanbayLinks['listen-with-hint'][i])) {
  45. changeListenPage();
  46. changedPage = true;
  47. }
  48. }
  49. }
  50.  
  51. /*
  52. if (window.location.href.startsWith('https://www.shanbay.com/listen/sentence')) {
  53. changeListenPage();
  54. }
  55. */
  56.  
  57. })();
  58.  
  59. // 找到所有空里面获得焦点的空,如果没有,就找第一个不正确的,不正确包括空白,返回这个DOM
  60. // 如果没找到,返回undefined
  61. function findFirstIncorrectBlank() {
  62. let inputs = document.getElementsByClassName('sentence-word-input');
  63. let res = undefined;// 如果没有光标所指的input,返回第一个非正确的
  64. for (let i = 0 ; i < inputs.length ; i++) {
  65. if (res == undefined && (inputs[i].value == '' || !inputs[i].classList.contains('correct-answer'))) {
  66. res = inputs[i];
  67. }
  68. // 如果有获得焦点的空,返回这个空的dom
  69. if (res != undefined && inputs[i] === document.activeElement) {
  70. return inputs[i];
  71. }
  72. }
  73.  
  74. return res;
  75. }
  76.  
  77. function displayListenHint() {
  78. let dom = findFirstIncorrectBlank();
  79. if (dom == undefined) {
  80. document.getElementById('hint-button').value = 'Not here';
  81. return;
  82. }
  83. window.shanbayScript.hint_input_dom = dom;
  84. document.getElementById('hint-button').value = dom.getAttribute('data');
  85. dom.placeholder = dom.getAttribute('data');
  86. }
  87.  
  88. function hideListenHint() {
  89. document.getElementById('hint-button').value = 'Hint';
  90. if (window.shanbayScript.hint_input_dom == undefined) {
  91. return;
  92. }
  93. window.shanbayScript.hint_input_dom.placeholder = '';
  94. }
  95.  
  96. // 设置element为可拖拽
  97. function dragElement(element) {
  98. var posX;// 原来鼠标的位置
  99. var posY;
  100. var posXX;// 拖拽之后鼠标的位置
  101. var posYY;
  102. function pressed(event) {
  103. event = event || window.event;
  104. event.preventDefault;
  105.  
  106. posX = event.clientX;
  107. posY = event.clientY;
  108. document.addEventListener('mousemove', drag);
  109. document.addEventListener('mouseup', released);
  110.  
  111. }
  112. function released(event) {
  113. document.removeEventListener('mousemove', drag);
  114. document.removeEventListener('mouseup', released);
  115. }
  116. function drag(event) {
  117. event = event || window.event;
  118. event.preventDefault;
  119. let deltaX = event.clientX - posX;
  120. let deltaY = event.clientY - posY;
  121. posX = event.clientX;
  122. posY = event.clientY; console.log(element.offsetTop);
  123. element.style.top = element.offsetTop + deltaY + 'px';
  124. element.style.left = element.offsetLeft + deltaX + 'px';
  125. }
  126. element.onmousedown = pressed;
  127. }
  128.  
  129. function changeListenPage() {
  130. let button = document.createElement('input');
  131. button.type='button';
  132. button.style.position = 'fixed';
  133. button.style['z-index'] = '10';
  134. button.style.top = '50%';
  135. button.style.left = '15%';
  136. button.id = 'hint-button';
  137. button.value = 'Hint';
  138. button.draggable = false;
  139. // 设置拖拽
  140. dragElement(button);
  141.  
  142. // 悬停事件
  143. button.addEventListener('mouseover', displayListenHint);
  144. button.addEventListener('mouseout', hideListenHint);
  145.  
  146. // todo 懒得美化
  147. document.body.appendChild(button);
  148. }
  149.  
  150. // 唉!扇贝的页面连导航栏的结构都不一样,要分页面来处理,真坑,[todo]
  151. function changeNavBar() {
  152. let navHandlerOfPage = {
  153. 'https://web.shanbay.com/wordsweb': changeNavBarOnWordPage,
  154. 'https://www.shanbay.com/news': changeNavBarOnSpeakAndReadPage,
  155. 'https://web.shanbay.com/reading': changeNavBarOnSpeakAndReadPage,
  156. 'https://www.shanbay.com/speak': changeNavBarOnSpeakAndReadPage,
  157. 'https://www.shanbay.com': changeNavBarOnNormalPage,
  158. };
  159.  
  160. for (let url in navHandlerOfPage) {
  161. if (window.location.href.startsWith(url)) {
  162. navHandlerOfPage[url](); break;
  163. }
  164. }
  165. }
  166.  
  167. // 一般性的页面,有统一的navbar结构
  168. function changeNavBarOnNormalPage() {
  169. let nav = document.getElementsByClassName('nav')[0];
  170. let navlinks = nav.getElementsByClassName('main-menu');
  171.  
  172. let tab = '<li class="dropdown main-nav ">'+
  173. '<a href="' + shanbayLinks['sentence-review'] + '" class="main-menu">' +
  174. '炼句' +
  175. '</a>'+
  176. ' </li>';
  177.  
  178. for (let i = 0 ; i < navlinks.length ; i++) {
  179. // 修改听力链接
  180. if (navlinks[i].innerText.trim() == '听力' && window.shanbayConfig['change-listen-nav']) {
  181. navlinks[i].href = window.shanbayLinks['listen-link'];
  182. }
  183. }
  184.  
  185. if (window.shanbayConfig['insert-sentence-review-nav']) {
  186. nav.innerHTML += tab;// 增加炼句导航
  187. }
  188. }
  189.  
  190. // 修改记单词界面的navbar
  191. function changeNavBarOnWordPage() {
  192. // todo: the class name might change
  193. let nav = document.getElementsByClassName('Nav_itemsWrapper__3FUxo')[0];
  194. if (nav === undefined)
  195. return;
  196. let navlinks = nav.getElementsByTagName('a');
  197.  
  198. let tab = '<a class="Nav_item__TffFb" href="' + shanbayLinks['sentence-review'] + '">炼句</a>';
  199.  
  200. for (let i = 0 ; i < navlinks.length ; i++) {
  201. // 修改听力链接
  202. if (navlinks[i].innerText.trim() == '听力' && window.shanbayConfig['change-listen-nav']) {
  203. navlinks[i].href = window.shanbayLinks['listen-link'];
  204. }
  205. }
  206.  
  207. if (window.shanbayConfig['insert-sentence-review-nav']) {
  208. nav.innerHTML += tab;// 增加炼句导航
  209. }
  210. }
  211.  
  212. // 口语和阅读的navbar结构一样
  213. function changeNavBarOnSpeakAndReadPage() {
  214. let nav = document.getElementsByClassName('nav-top-left')[0];
  215. let navlinks = nav.getElementsByClassName('secondary');
  216.  
  217. let tab = '<li>'+
  218. '<a class="secondary" href="' + shanbayLinks['sentence-review'] + '" class="main-menu">' +
  219. '炼句' +
  220. '</a>'+
  221. ' </li>';
  222.  
  223. for (let i = 0 ; i < navlinks.length ; i++) {
  224. // 修改听力链接
  225. if (navlinks[i].innerText.trim() == '听力' && window.shanbayConfig['change-listen-nav']) {
  226. navlinks[i].href = window.shanbayLinks['listen-link'];
  227. }
  228. }
  229.  
  230. if (window.shanbayConfig['insert-sentence-review-nav']) {
  231. nav.getElementsByTagName('ul')[0].innerHTML += tab;// 增加炼句导航
  232. }
  233. }

QingJ © 2025

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