Open in Goodreads

Adds a button to Amazon book pages to redirect to Goodreads page based on ASIN/ISBN

  1. // ==UserScript==
  2. // @name Open in Goodreads
  3. // @namespace open-in-goodreads
  4. // @version 2.4
  5. // @description Adds a button to Amazon book pages to redirect to Goodreads page based on ASIN/ISBN
  6. // @match https://*.amazon.com/*
  7. // @match https://*.amazon.co.uk/*
  8. // @match https://*.amazon.com.au/*
  9. // @match https://*.amazon.com.be/*
  10. // @match https://*.amazon.com.br/*
  11. // @match https://*.amazon.ca/*
  12. // @match https://*.amazon.cn/*
  13. // @match https://*.amazon.eg/*
  14. // @match https://*.amazon.fr/*
  15. // @match https://*.amazon.de/*
  16. // @match https://*.amazon.in/*
  17. // @match https://*.amazon.it/*
  18. // @match https://*.amazon.co.jp/*
  19. // @match https://*.amazon.com.mx/*
  20. // @match https://*.amazon.nl/*
  21. // @match https://*.amazon.pl/*
  22. // @match https://*.amazon.sa/*
  23. // @match https://*.amazon.sg/*
  24. // @match https://*.amazon.es/*
  25. // @match https://*.amazon.se/*
  26. // @match https://*.amazon.com.tr/*
  27. // @match https://*.amazon.ae/*
  28. // @grant none
  29. // @license MIT
  30. // ==/UserScript==
  31.  
  32. (function () {
  33. 'use strict';
  34.  
  35. function redirectToGoodreads() {
  36. var asinElements = document.getElementsByName('ASIN');
  37. if (asinElements.length === 0) asinElements = document.getElementsByName('ASIN.0');
  38.  
  39. if (asinElements.length > 0) {
  40. const asin = asinElements[0].value;
  41. const goodreadsUrl = asin.match(/\D/) === null
  42. ? `http://www.goodreads.com/review/isbn/${asin}`
  43. : `https://www.goodreads.com/book/isbn?isbn=${asin}`;
  44. window.open(goodreadsUrl, '_blank');
  45. } else {
  46. alert("No ASIN or ISBN Found.");
  47. }
  48. }
  49.  
  50. function addButton() {
  51. const imageBlockNew = document.getElementById('imageBlockNew_feature_div');
  52. const imageBlock = document.getElementById('imageBlock_feature_div');
  53. const booksImageBlock = document.getElementById('booksImageBlock_feature_div');
  54.  
  55. // Only add button if one of the target image blocks is present
  56. if (imageBlockNew || booksImageBlock || imageBlock) {
  57. // Check for Publication date in the carousel section
  58. const carousel = document.querySelector('.a-carousel');
  59. const publicationDateExists = carousel && carousel.innerText.includes('Publication date');
  60.  
  61. if (publicationDateExists) {
  62. const button = document.createElement('button');
  63. button.innerText = 'Open in Goodreads';
  64. button.style.cssText = `
  65. margin: 10px auto;
  66. display: block;
  67. color: #ffffff;
  68. background-color: #377458;
  69. border: none;
  70. border-radius: 4px;
  71. padding: 8px 12px;
  72. font-family: Arial, sans-serif;
  73. font-size: 14px;
  74. font-weight: bold;
  75. cursor: pointer;
  76. `;
  77. button.onclick = redirectToGoodreads;
  78.  
  79. const centerDiv = document.createElement('div');
  80. centerDiv.style.textAlign = 'center';
  81. centerDiv.appendChild(button);
  82.  
  83. // Insert the button after the image block
  84. if (imageBlockNew) imageBlockNew.parentNode.insertBefore(centerDiv, imageBlockNew.nextSibling);
  85. else if (booksImageBlock) booksImageBlock.parentNode.insertBefore(centerDiv, booksImageBlock.nextSibling);
  86. else if (imageBlock) imageBlock.parentNode.insertBefore(centerDiv, imageBlock.nextSibling);
  87. }
  88. }
  89. }
  90.  
  91. // Observer to detect when the target elements are available
  92. const observer = new MutationObserver(() => {
  93. const imageBlockNew = document.getElementById('imageBlockNew_feature_div');
  94. const imageBlock = document.getElementById('imageBlock_feature_div');
  95. const booksImageBlock = document.getElementById('booksImageBlock_feature_div');
  96.  
  97. if (imageBlockNew || booksImageBlock || imageBlock) {
  98. addButton();
  99. observer.disconnect(); // Stop observing once the button is added
  100. }
  101. });
  102.  
  103. // Start observing for changes in the DOM
  104. observer.observe(document.body, { childList: true, subtree: true });
  105. })();

QingJ © 2025

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