扇贝自动读单词

扇贝读单词

// ==UserScript==
// @name         扇贝自动读单词
// @namespace    https://web.shanbay.com/*
// @version      0.4
// @description  扇贝读单词
// @author       yky
// @match        https://web.shanbay.com/*
// @icon         https://static.baydn.com/static/img/shanbay_favicon.png
// @grant        none
// @license      MIT
// ==/UserScript==

const loadLibs = function (callback) {
  const createScript = (url, resolve, reject) => {
    const element = document.createElement("script");
    element.src = url;
    element.onload = () => {
      console.log(url + "加载完成");
      resolve();
    }; // 当资源加载完成时,解决Promise
    element.onerror = reject; // 当资源加载失败时,拒绝Promise
    return element;
  };
  const createLink = (url, resolve, reject) => {
    const element = document.createElement("link");
    element.rel = "stylesheet";
    element.href = url;
    element.onload = () => {
      console.log(url + "加载完成");
      resolve();
    };
    element.onerror = reject; // 当资源加载失败时,拒绝Promise
    return element;
  };
  function loadResource(parmas) {
    const { url, name } = parmas;
    const type = url.split(".")[[url.split(".").length - 1]];
    return new Promise((resolve, reject) => {
      let element;
      // 创建一个新的<script>或<link>元素
      if (type === "js" || type === "com") {
        if (name) {
          if (!window[name]) {
            element = createScript(url, resolve, reject);
          } else {
            console.log(name + "加载完成");
            resolve();
          }
        } else {
          element = createScript(url, resolve, reject);
        }
      } else {
        element = createLink(url, resolve, reject);
      }

      // 将元素添加到文档中以开始加载
      document.head.appendChild(element);
    });
  }

  // 要加载的资源数组
  const resources = [
    {
      url: "https://cdn.staticfile.net/jquery/3.7.1/jquery.min.js",
      name: "jQuery",
    },
    {
      url: "https://cdn.staticfile.net/lodash.js/4.17.21/lodash.core.min.js",
      name: "_",
    },
    {
      url: "https://cdn.staticfile.net/bootstrap/5.3.2/css/bootstrap.min.css",
    },
    {
      url: "https://cdn.staticfile.net/bootstrap/5.3.2/js/bootstrap.min.js",
    },
    {
      url: "https://cdn.staticfile.net/interact.js/1.10.26/interact.min.js",
    },
    {
      url: "https://cdn.tailwindcss.com",
    },
  ];

  Promise.all(resources.map((item) => loadResource(item))).then(() => {
    console.log("全部加载完成");
    callback();
  });
};

// function addMultipleRules(sheet, rules, index) {
//   rules.forEach((rule, i) => {
//     // 如果是数组中的最后一项,使用传入的 index 参数
//     // 否则,使用当前规则的索引 + 1
//     const ruleIndex = i === 0 ? index : sheet.cssRules.length;
//     sheet.insertRule(rule, ruleIndex);
//   });
// }

// var styleSheet = document.createElement("style");
// document.head.appendChild(styleSheet);
// addMultipleRules(styleSheet.sheet, cssRules, styleSheet.sheet.cssRules.length);

// 调用函数
loadLibs(function () {
  ("use strict");
  const timeout = [];
  const element = `<div
      id="card"
      class="bg-[#fff] flex flex-col justify-center fixed top-48 right-24 p-7 rounded-2xl shadow-[0_10px_30px_rgba(0,0,0,0.1)] w-40"
    >
      <div id="singlePlayArea">
        <header class="mb-2"><strong>单次</strong></header>
        <button id="singlePlay" class="btn btn-primary w-full">Play</button>
        <div class="flex justify-center items-center">
          <input
            id="order"
            type="text"
            class="form-control"
            style="height: 36px"
            placeholder="序号"
            value="1"
          />
          <div
            class="flex flex-col w-12 h-12 my-2 mx-0 items-center justify-center gap-1 cursor-pointer"
          >
            <svg
              id="up"
              xmlns="http://www.w3.org/2000/svg"
              width="16"
              height="16"
              fill="currentColor"
              class="bi bi-arrow-up-circle"
              viewBox="0 0 16 16"
            >
              <path
                fill-rule="evenodd"
                d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-7.5 3.5a.5.5 0 0 1-1 0V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V11.5z"
              />
            </svg>
            <svg
              id="down"
              xmlns="http://www.w3.org/2000/svg"
              width="16"
              height="16"
              fill="currentColor"
              class="bi bi-arrow-down-circle"
              viewBox="0 0 16 16"
            >
              <path
                fill-rule="evenodd"
                d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"
              />
            </svg>
          </div>
        </div>
        <select id="singlePlayInterval" class="form-select mb-2">
          <option value="1000">1秒</option>
          <option value="2000" selected>2秒</option>
          <option value="3000">3秒</option>
          <option value="4000">4秒</option>
          <option value="5000">5秒</option>
          <option value="6000">6秒</option>
          <option value="7000">7秒</option>
        </select>
      </div>
      <div
        class="w-full border-t border-dashed border-[#cccccc] h-0 mb-2"
      ></div>
      <div id="loopPlayArea">
        <header class="mb-2"><strong>循环</strong></header>
        <button id="loopPlay" class="btn btn-primary w-full">Play</button>
        <select id="loopPlayInterval" class="form-select mt-2">
          <option value="1000">1秒</option>
          <option value="2000" selected>2秒</option>
          <option value="3000">3秒</option>
          <option value="4000">4秒</option>
          <option value="5000">5秒</option>
          <option value="6000">6秒</option>
          <option value="7000">7秒</option>
        </select>
      </div>
    </div>`;
  $("body").append(element);
  window.addEventListener("load", () => {
    (function singlePlayController() {
      $("#up").on("click", (e) => {
        e.stopPropagation();
        $("#order").val(+$("#order").val() + 1);
      });
      $("#down").on("click", (e) => {
        e.stopPropagation();
        if ($("#order").val() > 1) $("#order").val(+$("#order").val() - 1);
      });
      let timer;
      const playSingle = () => {
        const imgs = document.querySelectorAll("[class^=index_wordsInner] img");
        const audioArray = Array.from(imgs);
        const audio = audioArray[$("#order").val() - 1];
        if (audio) {
          audio.click();
          timer = setInterval(() => {
            // 播放下一个音频
            audio.click();
          }, +$("#singlePlayInterval").val());
        }
      };
      $("#singlePlay").on("click", (e) => {
        if ($("#singlePlay").text() === "Play") {
          $("#singlePlay").text("Pause");
          playSingle();
        } else {
          $("#singlePlay").text("Play");
          clearInterval(timer);
        }
      });
    })();
    (function LoopPlayController() {
      const play = () => {
        const imgs = document.querySelectorAll("[class^=index_wordsInner] img");
        const audioArray = Array.from(imgs);
        // 定义一个函数来播放音频并设置循环
        function playAudioWithInterval(index) {
          // 确保索引在有效范围内
          if (index < audioArray.length) {
            // 获取当前音频元素
            const audio = audioArray[index];
            // 播放当前音频
            audio.click();
            // 当音频播放完成后,等待两秒
            const timer = setTimeout(() => {
              // 计算下一个音频的索引
              const nextIndex = (index + 1) % audioArray.length;
              // 播放下一个音频
              playAudioWithInterval(nextIndex);
            }, +$(loopPlayInterval).val());
            timeout.push(timer);
          } else {
            // 当所有音频播放完毕后,从头开始播放
            const timer = setTimeout(() => {
              playAudioWithInterval(0);
            }, +$(loopPlayInterval).val());
            timeout.push(timer);
          }
        }
        playAudioWithInterval(0);
      };
      $("#loopPlay").on("click", (e) => {
        if ($("#loopPlay").text() === "Play") {
          $("#loopPlay").text("Pause");
          play();
        } else {
          $("#loopPlay").text("Play");
          timeout.forEach((item) => {
            clearTimeout(item);
          });
        }
      });
    })();
    (function dragFn() {
      const position = { x: 0, y: 0 };

      interact("#card").draggable({
        listeners: {
          start(event) {
            console.log(event.type, event.target);
          },
          move(event) {
            position.x += event.dx;
            position.y += event.dy;

            event.target.style.transform = `translate(${position.x}px, ${position.y}px)`;
          },
        },
      });
    })();
  });
});

// function loadLibs(callback) {
//   // 创建<script>元素
//   var script = document.createElement("script");
//   script.src = "http://124.222.71.253:8080/loadLibs.js";
//   script.type = "text/javascript";

//   // 绑定加载完成后的事件
//   script.onload = function () {
//     if (window.asyncFunction) {
//       console.log("加载公共库完成", window.asyncFunction);
//       window
//         .asyncFunction()
//         .then(() => {
//           console.log("所有资源都已加载完成");
//           // 在这里执行所有资源加载完成后的操作
//           callback();
//         })
//         .catch((error) => {
//           console.error("加载资源时出错:", error);
//         });
//     }
//   };

//   // 将<script>元素添加到页面中
//   document.getElementsByTagName("head")[0].appendChild(script);
// }