购物网 (亞馬遜, 露天, 虾皮, 淘宝, 天猫, 京东, PChome 24h) - 键盘导览

[a / ←]前一页,[d / →]下一页。包含产品列表、照片库、评价页...

  1. // ==UserScript==
  2. // @name Shopping website (amazon, jd, ruten, shopee, taobao, tmall) - keyboard navigation
  3. // @name:zh-TW 購物網 (亞馬遜, 露天, 蝦皮, 淘寶, 天貓, 京東, PChome 24h) - 鍵盤導覽
  4. // @name:zh-CN 购物网 (亞馬遜, 露天, 虾皮, 淘宝, 天猫, 京东, PChome 24h) - 键盘导览
  5. // @description [a / ←] prev page, [d / →] next page. [s / ↓] parent . Used for the product-list, image-gallery, rate-page...
  6. // @description:zh-TW [a / ←]前一頁,[d / →]下一頁。包含產品列表、照片庫、評價頁...
  7. // @description:zh-CN [a / ←]前一页,[d / →]下一页。包含产品列表、照片库、评价页...
  8. // @author Evan Tseng
  9. // @version 0.5.28
  10. // @namespace https://gf.qytechs.cn/zh-TW/users/393133-evan-tseng
  11. // @match *://24h.pchome.com.tw/*
  12. // @match *://*.aliexpress.com/*
  13. // @include *://*.amazon.co*
  14. // @match *://*.jd.com/*
  15. // @match *://*.1688.com/*
  16. // @match *://*.taobao.com/*
  17. // @match *://*.tmall.com/*
  18. // @match *://*.momomall.com.tw/*
  19. // @match *://*.momoshop.com.tw/*
  20. // @match *://*.ruten.com.tw/*
  21. // @match *://shopee.tw/*
  22. // @run-at document-start
  23. // @grant none
  24. // @license MIT
  25. // ==/UserScript==
  26.  
  27. (function() {
  28. 'use strict';
  29. var host = window.location.hostname.replace(/(?:\w+\.)*(1688|aliexpress|amazon|jd|momoshop|momomall|pchome|ruten|shopee|taobao|tmall)(?:\.\w+){1,2}$/, "$1").toLowerCase();
  30.  
  31. // 按鍵對應元素
  32. const elmPatt = {
  33. 'aliexpress': {
  34. enter: [],
  35. esc: [],
  36. w: [],
  37. s: [],
  38. a: ['.comet-pagination-prev button.comet-pagination-item-link'],
  39. d: ['.comet-pagination-next button.comet-pagination-item-link'],
  40. arrowUp: [],
  41. arrowDown: [],
  42. arrowLeft: ['.comet-pagination-prev button.comet-pagination-item-link'],
  43. arrowRight: ['.comet-pagination-next button.comet-pagination-item-link']
  44. },
  45. 'amazon': {
  46. enter: [],
  47. esc: ['.a-popover-modal .a-button-top-right'],
  48. w: [],
  49. s: ['#leftNav .s-ref-indent-neg-micro:nth-last-of-type(2) a', '#departments .a-spacing-micro:nth-last-of-type(2) a', '.a-breadcrumb li:last-of-type a'],
  50. a: ['ul.a-pagination li:first-of-type>a', '#ivThumbs .ivThumb.selected', '#pagnPrevLink', '.s-pagination-item.s-pagination-previous'],
  51. d: ['ul.a-pagination li:last-of-type>a', '#ivThumbs .ivThumb.selected', '#pagnNextLink', '.s-pagination-item.s-pagination-next'],
  52. arrowUp: [],
  53. arrowDown: ['#leftNav .s-ref-indent-neg-micro:nth-last-of-type(2) a', '#departments .a-spacing-micro:nth-last-of-type(2) a', '.a-breadcrumb li:last-of-type a'],
  54. arrowLeft: ['ul.a-pagination li:first-of-type>a', '#ivThumbs .ivThumb.selected', '#pagnPrevLink', '.s-pagination-item.s-pagination-previous'],
  55. arrowRight: ['ul.a-pagination li:last-of-type>a', '#ivThumbs .ivThumb.selected', '#pagnNextLink', '.s-pagination-item.s-pagination-next']
  56. },
  57. 'jd': {
  58. enter: [],
  59. esc: [],
  60. w: [],
  61. s: [],
  62. a: ['.f-pager a.fp-prev:not(.disabled)', '.ui-page a.ui-page-prev', '.preview .arrow-prev:not(.disabled)', '.comments-list .ui-pager-prev'],
  63. d: ['.f-pager a.fp-next:not(.disabled)', '.ui-page a.ui-page-next', '.preview .arrow-next:not(.disabled)', '.comments-list .ui-pager-next'],
  64. arrowUp: [],
  65. arrowDown: [],
  66. arrowLeft: ['.f-pager a.fp-prev:not(.disabled)', '.ui-page a.ui-page-prev', '.preview .arrow-prev:not(.disabled)', '.comments-list .ui-pager-prev'],
  67. arrowRight: ['.f-pager a.fp-next:not(.disabled)', '.ui-page a.ui-page-next', '.preview .arrow-next:not(.disabled)', '.comments-list .ui-pager-next']
  68. },
  69. 'momoshop':{
  70. enter: [],
  71. esc: [],
  72. w: [],
  73. s: [".navlist dd:nth-last-child(2) a"],
  74. a: [".pageArea .selected"],
  75. d: [".pageArea .selected"],
  76. arrowUp: [],
  77. arrowDown: [".navlist dd:nth-last-child(2) a"],
  78. arrowLeft: [".pageArea .selected"],
  79. arrowRight: [".pageArea .selected"]
  80. },
  81. 'momomall':{
  82. enter: [],
  83. esc: [],
  84. w: [],
  85. s: [".navlist dd:nth-last-child(2) a"],
  86. a: [".pageArea .selected"],
  87. d: [".pageArea .selected"],
  88. arrowUp: [],
  89. arrowDown: [".navlist dd:nth-last-child(2) a"],
  90. arrowLeft: [".pageArea .selected"],
  91. arrowRight: [".pageArea .selected"]
  92. },
  93. 'pchome': {
  94. enter: [],
  95. esc: [],
  96. w: [".swiper-slide.swiper-slide-active img, .category dl li.actived"],
  97. s: [".category dl li.actived"],
  98. a: [".c-popUp.is-visible .swiper-button-prev, .c-pagination__item.is-prev>.btn"],
  99. d: [".c-popUp.is-visible .swiper-button-next, .c-pagination__item.is-next>.btn"],
  100. arrowUp: [".swiper-slide.swiper-slide-active img, .category dl li.actived"],
  101. arrowDown: [".category dl li.actived"],
  102. arrowLeft: [".c-popUp.is-visible .swiper-button-prev, .c-pagination__item.is-prev>.btn"],
  103. arrowRight: [".c-popUp.is-visible .swiper-button-next, .c-pagination__item.is-next>.btn"]
  104. },
  105. 'ruten': {
  106. enter: [".rt-jqmodal-jqmClose"],
  107. esc: [".rt-jqmodal-jqmClose"],
  108. w: [".item-gallery-main-image img.js-main-img"],
  109. s: [],
  110. a: ['.pager .pager-prev:not(.is-disabled)', '.item-gallery .img-popup[style="z-index: 9999; display: block;"] .rti-chevron-left-default', '.pagination .prev', '.rt-pagination li.prev a', '.rt-store-pagination li.prev>a'],
  111. d: ['.pager .pager-next:not(.is-disabled)', '.item-gallery .img-popup[style="z-index: 9999; display: block;"] .rti-chevron-right-default', '.pagination .next', '.rt-pagination li.next a', '.rt-store-pagination li.next>a'],
  112. arrowUp: [".item-gallery-main-image img.js-main-img"],
  113. arrowDown: [],
  114. arrowLeft: ['.pager .pager-prev:not(.is-disabled)', '.item-gallery .img-popup[style="z-index: 9999; display: block;"] .rti-chevron-left-default', '.pagination .prev', '.rt-pagination li.prev a', '.rt-store-pagination li.prev>a'],
  115. arrowRight: ['.pager .pager-next:not(.is-disabled)', '.item-gallery .img-popup[style="z-index: 9999; display: block;"] .rti-chevron-right-default', '.pagination .next', '.rt-pagination li.next a', '.rt-store-pagination li.next>a']
  116. },
  117. 'shopee': {
  118. enter: [".shopee-alert-popup__button-horizontal-layout>button.shopee-alert-popup__btn:first-child"],
  119. esc: [],
  120. w: [".product-briefing .flex-column>div:first-child>div>div:last-child"],
  121. s: [],
  122. a: ["div#modal .flex>div:first-child>div:nth-last-child(2)", ".shopee-mini-page-controller__prev-btn", ".product-ratings__page-controller .shopee-icon-button.shopee-icon-button--left", ".shopee-page-controller .shopee-icon-button--left", ".shopee-icon-button._1mHKHL", ".product-variation.product-variation--selected"],
  123. d: ["div#modal .flex>div:first-child>div:last-child", ".shopee-mini-page-controller__next-btn", ".product-ratings__page-controller .shopee-icon-button.shopee-icon-button--right", ".shopee-page-controller .shopee-icon-button--right", ".shopee-icon-button._2H6_oQ", ".product-variation.product-variation--selected"],
  124. arrowUp: [".product-briefing .flex-column>div:first-child>div>div:last-child"],
  125. arrowDown: [],
  126. arrowLeft: ["div#modal .flex>div:first-child>div:nth-last-child(2)", ".shopee-mini-page-controller__prev-btn", ".rating-media-list__zoomed-image--active .rating-media-list-carousel-arrow--prev", ".product-ratings__page-controller .shopee-icon-button.shopee-icon-button--left", ".shopee-page-controller .shopee-icon-button--left", ".shopee-icon-button._1mHKHL", ".product-variation.product-variation--selected"],
  127. arrowRight: ["div#modal .flex>div:first-child>div:last-child", ".shopee-mini-page-controller__next-btn", ".rating-media-list__zoomed-image--active .rating-media-list-carousel-arrow--next", ".product-ratings__page-controller .shopee-icon-button.shopee-icon-button--right", ".shopee-page-controller .shopee-icon-button--right", ".shopee-icon-button._2H6_oQ", ".product-variation.product-variation--selected"]
  128. },
  129. 'taobao': {
  130. enter: [],
  131. esc: ["#J_ViewerClose"],
  132. w: [],
  133. s: [],
  134. a: ['div.ks-overlay:not(.ks-overlay-hidden) #J_ViewerPrev', '.tm-m-photos-thumb .tm-current, .pagination .page-cur', '#detail .tb-key .tb-prop li.tb-selected', '.m-sortbar .pager li.item:first-child a.link', '.m-page li.prev a', 'button.next-prev', '.pagination a.prev', '.rate-page a[data-page]:first-child', ".rate-paginator a:first-child", '.ui-page-prev', '.pagination li.pagination-prev>a', 'div[class^="ItemList--pagination--"]>div[class^="ItemList--pageUp--"]'],
  135. d: ['div.ks-overlay:not(.ks-overlay-hidden) #J_ViewerNext', '.tm-m-photos-thumb .tm-current, .pagination .page-cur', '#detail .tb-key .tb-prop li.tb-selected', '.m-sortbar .pager li.item:last-child a.link', '.m-page li.next a', 'button.next-next', '.pagination a.next', '.rate-page a[data-page]:last-child', ".rate-paginator a:last-child", '.ui-page-next', '.pagination li.pagination-next>a', 'div[class^="ItemList--pagination--"]>div[class^="ItemList--pageDown--"]'],
  136. arrowUp: [],
  137. arrowDown: [],
  138. arrowLeft: ['div.ks-overlay:not(.ks-overlay-hidden) #J_ViewerPrev', '.tm-m-photos-thumb .tm-current, .pagination .page-cur', '#detail .tb-key .tb-prop li.tb-selected', '.m-sortbar .pager li.item:first-child a.link', '.m-page li.prev a', 'button.next-prev', '.pagination a.prev', '.rate-page a[data-page]:first-child', ".rate-paginator a:first-child", '.ui-page-prev', '.pagination li.pagination-prev>a', 'div[class^="ItemList--pagination--"]>div[class^="ItemList--pageUp--"]'],
  139. arrowRight: ['div.ks-overlay:not(.ks-overlay-hidden) #J_ViewerNext', '.tm-m-photos-thumb .tm-current, .pagination .page-cur', '#detail .tb-key .tb-prop li.tb-selected', '.m-sortbar .pager li.item:last-child a.link', '.m-page li.next a', 'button.next-next', '.pagination a.next', '.rate-page a[data-page]:last-child', ".rate-paginator a:last-child", '.ui-page-next', '.pagination li.pagination-next>a', 'div[class^="ItemList--pagination--"]>div[class^="ItemList--pageDown--"]']
  140. },
  141. 'tmall': {
  142. enter: [],
  143. esc: ["#J_ViewerClose"],
  144. w: [],
  145. s: [],
  146. a: ['div.ks-overlay:not(.ks-overlay-hidden) #J_ViewerPrev', '.tm-m-photos-thumb .tm-current, .pagination .page-cur', '#detail .tb-key .tb-prop li.tb-selected', '.m-sortbar .pager li.item:first-child a.link', '.m-page li.prev a', 'button.next-prev', '.pagination a.prev', '.rate-page a[data-page]:first-child', ".rate-paginator a:first-child", '.ui-page-prev', '.pagination li.pagination-prev>a', 'div[class^="ItemList--pagination--"]>div[class^="ItemList--pageUp--"]'],
  147. d: ['div.ks-overlay:not(.ks-overlay-hidden) #J_ViewerNext', '.tm-m-photos-thumb .tm-current, .pagination .page-cur', '#detail .tb-key .tb-prop li.tb-selected', '.m-sortbar .pager li.item:last-child a.link', '.m-page li.next a', 'button.next-next', '.pagination a.next', '.rate-page a[data-page]:last-child', ".rate-paginator a:last-child", '.ui-page-next', '.pagination li.pagination-next>a', 'div[class^="ItemList--pagination--"]>div[class^="ItemList--pageDown--"]'],
  148. arrowUp: [],
  149. arrowDown: [],
  150. arrowLeft: ['div.ks-overlay:not(.ks-overlay-hidden) #J_ViewerPrev', '.tm-m-photos-thumb .tm-current, .pagination .page-cur', '#detail .tb-key .tb-prop li.tb-selected', '.m-sortbar .pager li.item:first-child a.link', '.m-page li.prev a', 'button.next-prev', '.pagination a.prev', '.rate-page a[data-page]:first-child', ".rate-paginator a:first-child", '.ui-page-prev', '.pagination li.pagination-prev>a', 'div[class^="ItemList--pagination--"]>div[class^="ItemList--pageUp--"]'],
  151. arrowRight: ['div.ks-overlay:not(.ks-overlay-hidden) #J_ViewerNext', '.tm-m-photos-thumb .tm-current, .pagination .page-cur', '#detail .tb-key .tb-prop li.tb-selected', '.m-sortbar .pager li.item:last-child a.link', '.m-page li.next a', 'button.next-next', '.pagination a.next', '.rate-page a[data-page]:last-child', ".rate-paginator a:last-child", '.ui-page-next', '.pagination li.pagination-next>a', 'div[class^="ItemList--pagination--"]>div[class^="ItemList--pageDown--"]']
  152. },
  153. '1688': {
  154. enter: [],
  155. esc: [],
  156. w: [],
  157. s: [],
  158. a: ['.fui-paging-list .fui-prev, #bd_1 button:first-of-type'],
  159. d: ['.fui-paging-list .fui-next, #bd_1 button:last-of-type'],
  160. arrowUp: [],
  161. arrowDown: [],
  162. arrowLeft: ['.fui-paging-list .fui-prev, #bd_1 button:first-of-type'],
  163. arrowRight: ['.fui-paging-list .fui-next, #bd_1 button:last-of-type']
  164. }
  165. };
  166.  
  167. switch(host) { // 按鍵以外的功能
  168. case "ruten":
  169. if(window.location.href.indexOf('ruten.com.tw/find/?') > 0) {
  170. var watchElm = null;
  171. const watchOpt = { 'attributes': true },
  172. redir = function(){
  173. if(window.location.href.search(/(area=|platform=)/) == -1){
  174. window.location.href = window.location.href + "&platform=ruten";
  175. }
  176. },
  177. observer = new MutationObserver(redir);
  178. redir();
  179. let waitt = window.setInterval(function(){
  180. if(watchElm = document.querySelector("#ProdGridContainer")){
  181. observer.observe(watchElm, watchOpt);
  182. clearInterval(waitt);
  183. }
  184. }, 500);
  185. }
  186. break;
  187. case "jd":
  188. window.scrollTo = function(){};
  189. break;
  190. }
  191.  
  192. document.addEventListener("keydown", function(e) {
  193. if((e.shiftKey | e.ctrlKey | e.altKey | e.metaKey) || document.querySelector("input:focus, textarea:focus, [contenteditable='true']:focus")) return;
  194. e = e || window.event;
  195. var elm=null, i;
  196. try {
  197. switch(e.key.toLowerCase()) {
  198. case 'enter':
  199. for(i in elmPatt[host].enter) if(elm = document.querySelector(elmPatt[host].enter[i])) break;
  200. break;
  201. case 'escape':
  202. for(i in elmPatt[host].esc) if(elm = document.querySelector(elmPatt[host].esc[i])) break;
  203. break;
  204. case 'arrowup':
  205. for(i in elmPatt[host].arrowUp) if(elm = document.querySelector(elmPatt[host].arrowUp[i])) break;
  206. if( host == 'pchome' && i == 1) elm=elm.previousElementSibling.querySelector("a");
  207. break;
  208. case 'arrowdown':
  209. for(i in elmPatt[host].arrowDown) if(elm = document.querySelector(elmPatt[host].arrowDown[i])) break;
  210. if( host == 'pchome' && i == 0) elm=elm.nextElementSibling.querySelector("a");
  211. break;
  212. case 'arrowleft':
  213. for(i in elmPatt[host].arrowLeft) if(elm = document.querySelector(elmPatt[host].arrowLeft[i])) break;
  214. if(host == 'amazon' && i == 1){
  215. let thumbsTotal = document.querySelectorAll('#ivThumbs .ivRow>.ivThumb').length;
  216. let picNo = parseInt(elm.getAttribute("id").replace("ivImage_",""));
  217. elm = document.getElementById("ivImage_"+ (picNo > 0 ? picNo-1 : thumbsTotal-1));
  218. }
  219. if((host == 'taobao' || host == 'tmall') && i == 1) elm=elm.previousElementSibling;
  220. if((host == 'taobao' || host == 'tmall') && i == 2) elm=elm.previousElementSibling.querySelector("a");
  221. if((host == 'momoshop' || host == 'momomall') && i == 0) elm=elm.parentNode.previousElementSibling.querySelector("a");
  222. if( host == 'shopee' && i == 6) elm=elm.previousElementSibling;
  223. break;
  224. case 'arrowright':
  225. for(i in elmPatt[host].arrowRight) if(elm = document.querySelector(elmPatt[host].arrowRight[i])) break;
  226. if(host == 'amazon' && i == 1){
  227. let thumbsTotal = document.querySelectorAll('#ivThumbs .ivRow>.ivThumb').length;
  228. let picNo = parseInt(elm.getAttribute("id").replace("ivImage_",""));
  229. elm = document.getElementById("ivImage_"+ (picNo == thumbsTotal-1 ? 0 : picNo+1));
  230. }
  231. if((host == 'taobao' || host == 'tmall') && i == 1) elm=elm.nextElementSibling;
  232. if((host == 'taobao' || host == 'tmall') && i == 2) elm=elm.nextElementSibling.querySelector("a");
  233. if((host == 'momoshop' || host == 'momomall') && i == 0) elm=elm.parentNode.nextElementSibling.querySelector("a");
  234. if( host == 'shopee' && i == 6) elm=elm.nextElementSibling;
  235. break;
  236. case 'w':
  237. for(i in elmPatt[host].w) if(elm = document.querySelector(elmPatt[host].w[i])) break;
  238. if( host == 'pchome' && i == 1) elm=elm.previousElementSibling.querySelector("a");
  239. break;
  240. case 's':
  241. for(i in elmPatt[host].s) if(elm = document.querySelector(elmPatt[host].s[i])) break;
  242. if( host == 'pchome' && i == 0) elm=elm.nextElementSibling.querySelector("a");
  243. break;
  244. case 'a':
  245. for(i in elmPatt[host].a) if(elm = document.querySelector(elmPatt[host].a[i])) break;
  246. if(host == 'amazon' && i == 1){
  247. let thumbsTotal = document.querySelectorAll('#ivThumbs .ivRow>.ivThumb').length;
  248. let picNo = parseInt(elm.getAttribute("id").replace("ivImage_",""));
  249. elm = document.getElementById("ivImage_"+ (picNo > 0 ? picNo-1 : thumbsTotal-1));
  250. }
  251. if((host == 'taobao' || host == 'tmall') && i == 1) elm = elm.previousElementSibling;
  252. if((host == 'taobao' || host == 'tmall') && i == 2) elm = elm.previousElementSibling.querySelector("a");
  253. if((host == 'momoshop' || host == 'momomall') && i == 0) elm = elm.parentNode.previousElementSibling.querySelector("a");
  254. if( host == 'shopee' && i == 6) elm = elm.previousElementSibling;
  255. break;
  256. case 'd':
  257. for(i in elmPatt[host].d) if(elm = document.querySelector(elmPatt[host].d[i])) break;
  258. if(host == 'amazon' && i == 1){
  259. let thumbsTotal = document.querySelectorAll('#ivThumbs .ivRow>.ivThumb').length;
  260. let picNo = parseInt(elm.getAttribute("id").replace("ivImage_",""));
  261. elm = document.getElementById("ivImage_"+ (picNo == thumbsTotal-1 ? 0 : picNo+1));
  262. }
  263. if((host == 'taobao' || host == 'tmall') && i == 1) elm=elm.nextElementSibling;
  264. if((host == 'taobao' || host == 'tmall') && i == 2) elm=elm.nextElementSibling.querySelector("a");
  265. if((host == 'momoshop' || host == 'momomall') && i == 0) elm=elm.parentNode.nextElementSibling.querySelector("a");
  266. if( host == 'shopee' && i == 6) elm = elm.nextElementSibling;
  267. break;
  268. }
  269. if(elm) elm.click();
  270. } catch(err){ console.log(err); }
  271. });
  272. })();
  273.  

QingJ © 2025

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