Keyboard navigator

Keyboard navigation

目前为 2019-06-10 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Keyboard navigator
  3. // @version 1.2
  4. // @description Keyboard navigation
  5. // @author badook
  6. // @include http*://*
  7. // @grant GM_openInTab
  8. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js
  9. // @namespace https://greasyfork.org/users/240988
  10. // ==/UserScript==
  11.  
  12. 'use strict';
  13.  
  14. var jq = $.noConflict();
  15.  
  16. var bgcolor = "#EBF2FF";
  17.  
  18. var util = {
  19. q: function(query, context) {
  20. return (context || document).querySelector(query);
  21. },
  22. qq: function(query, context) {
  23. return [].slice.call((context || document).querySelectorAll(query));
  24. }
  25. };
  26.  
  27. var i = 0;
  28.  
  29.  
  30. var isGoogleSearch = /^(http|https):\/\/(www.)?google.(com|co.uk|it)\/search\?/.test(location.href);
  31. var isPageScrollEnabled = true;
  32.  
  33.  
  34. if ( isGoogleSearch ) {
  35. var searchBox = jq('input[name="q"]').first();
  36. //var searchBox = document.getElementById("lst-ib");
  37. var prevPage = document.getElementById("pnprev");
  38. var nextPage = document.getElementById("pnnext");
  39. var results = util.qq('div.r', document.body);
  40.  
  41. results[i].style.backgroundColor = bgcolor;
  42.  
  43. jq(results).click(function() {
  44. results[i].style.backgroundColor = "transparent";
  45. i = results.indexOf(jq(this).get(0));
  46. jq(this).get(0).style.backgroundColor = bgcolor;
  47. });
  48. }
  49.  
  50.  
  51. document.onkeypress = function(e) {
  52. console.log(e.keyCode);
  53.  
  54. if ( !shouldScroll(e) ) {
  55. return;
  56. }
  57.  
  58. switch(e.keyCode) {
  59. case 97: // a
  60. setTimeout(function(){ // Dont put current letter in input
  61. searchBox.focus();
  62. searchBox.value = searchBox.value; // Cursor to end
  63. }, 0);
  64. return;
  65. case 13: // enter
  66. case 100: // d
  67. var url = jq('a',jq(results[i])).attr('href');
  68. console.log(url);
  69. GM_openInTab(url, true);
  70. return;
  71. case 68: // D
  72. GM_openInTab(util.q('a', results[i]).href, false);
  73. return;
  74. case 113: // q
  75. prevPage.click();
  76. return;
  77. case 101: // e
  78. nextPage.click();
  79. return;
  80. case 87: // W
  81. // if (isPageScrollEnabled)
  82. window.scrollBy(0, -100);
  83. return;
  84. case 83: // S
  85. // if (isPageScrollEnabled)
  86. console.log("scroll")
  87. window.scrollBy(0, 100);
  88. return;
  89. case 119: // w
  90. if(i > 0)
  91. results[i--].style.backgroundColor = "transparent";
  92. break;
  93. case 115: // s
  94. if(i < results.length - 1)
  95. results[i++].style.backgroundColor = "transparent";
  96. break;
  97. default:
  98. return;
  99. }
  100. results[i].style.backgroundColor = bgcolor;
  101. scrollToElement(results[i]);
  102. };
  103.  
  104.  
  105. function scrollToElement(el) {
  106. var elOffset = jq(el).offset().top;
  107. var elHeight = jq(el).height();
  108. var windowHeight = jq(window).height();
  109. var offset;
  110. if (elHeight < windowHeight)
  111. offset = elOffset - ((windowHeight / 2) - (elHeight / 2));
  112. else
  113. offset = elOffset;
  114. jq('html, body').animate({scrollTop:offset}, 0);
  115. }
  116.  
  117.  
  118. function shouldScroll(event, direction) {
  119. if (event.target.isContentEditable) {
  120. return false;
  121. }
  122. if (event.target.type === 'application/x-shockwave-flash') {
  123. return false;
  124. }
  125. if (event.defaultPrevented) {
  126. return false;
  127. }
  128. if (/button|input|textarea|select|embed|object/i.test(event.target.nodeName)) {
  129. return false;
  130. }
  131. if (event.metaKey === true) {
  132. return false;
  133. }
  134. if (!document.hasFocus()) {
  135. return false;
  136. }
  137. if (document.domain === 'mail.google.com') {
  138. if (window.location.hash.indexOf('/') === -1) {
  139. return false;
  140. } else if (!(event.keyCode in keyMaps.arrows)) {
  141. return false;
  142. }
  143. }
  144. /*
  145. if (!window.scrollTargetY) {
  146. findScrollTargets(event, 'y');
  147. if (!window.scrollTargetY) {
  148. return false;
  149. }
  150. }
  151. */
  152. if (!scrollable(window.scrollTargetY, 'y')) {
  153. return false;
  154. }
  155. return true;
  156. };
  157.  
  158.  
  159. findScrollTargets = function(event, axis) {
  160. var scrollableParentX, scrollableParentY, target;
  161. if (event == null) {
  162. event = null;
  163. }
  164. if (axis == null) {
  165. axis = 'both';
  166. }
  167. if (!event || document.activeElement === !document.body) {
  168. target = document.activeElement;
  169. } else {
  170. target = event.target || event.srcElement;
  171. target = target.nodeType === 1 ? target : target.parentNode;
  172. }
  173. if (axis === 'y' || axis === 'both') {
  174. scrollableParentY = findScrollableParent(target, 'y');
  175. if (scrollableParentY) {
  176. window.scrollTargetY = scrollableParentY;
  177. }
  178. }
  179. if (axis === 'x' || axis === 'both') {
  180. scrollableParentX = findScrollableParent(target, 'x');
  181. if (scrollableParentX) {
  182. return window.scrollTargetX = scrollableParentX;
  183. }
  184. }
  185. };
  186.  
  187.  
  188. findScrollableParent = function(element, axis) {
  189. while (true) {
  190. if (scrollable(element, axis)) {
  191. return element;
  192. } else {
  193. element = element.parentElement;
  194. }
  195. }
  196. };
  197.  
  198.  
  199. scrollable = function(element, axis) {
  200. var initialPosition, scrollAxis, scrollVariation;
  201. scrollAxis = axis === 'y' ? 'scrollTop' : 'scrollLeft';
  202. if (!element) {
  203. return true;
  204. } else if (/button|input|textarea|select|embed|object/i.test(element.nodeName)) {
  205. return false;
  206. } else if (element[scrollAxis] > 10) {
  207. return true;
  208. } else {
  209. initialPosition = element[scrollAxis];
  210. element[scrollAxis] = 10;
  211. scrollVariation = element[scrollAxis];
  212. element[scrollAxis] = initialPosition;
  213. if (scrollVariation >= 10) {
  214. return true;
  215. }
  216. }
  217. return false;
  218. };