您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Play audio in KaniWani
- // ==UserScript==
- // @name KaniWani audio
- // @namespace http://tampermonkey.net/
- // @version 0.22 alpha
- // @description Play audio in KaniWani
- // @author CometZero
- // @match https://kaniwani.com/kw/review/
- // @match https://www.kaniwani.com/kw/review/
- // @grant GM_xmlhttpRequest
- // ==/UserScript==
- //https://kaniwani.com/kw/review/
- var buttonHtml =
- `<a id="playAudio" class="button -addsynonym" href="#">Play Audio</a>`;
- var colorDisabled = "hsl(0, 0%, 65%)";
- var loadingImageHtml = `<img src="http://img.etimg.com/photo/45627788.cms"
- alt="Loading ..." style="margin-left:5px;width:15px;height:15px;display:none;">`;
- var playSoundButton;
- var loadingImage;
- var audio = null;
- var isPendingPlay = false;
- var isLoadingAudio = false;
- var onAudioReady = function(){
- isLoading = false;
- loadingImage.style.display = "none"; // hide loading image
- playSoundButton.style.color = ""; // set default text color
- if(isPendingPlay){
- audio.play();
- isPendingPlay = false;
- }
- };
- var onAudioLoading = function(){
- loadingImage.style.display = "inline"; // show loading image
- playSoundButton.style.color = colorDisabled; // dimm play button
- isLoading = true;
- };
- (function() {
- 'use strict';
- // TODO test if my service is still working (wanikaniaudio.herokuapp.com)
- // and notify the user to motivate me to enable the service
- initElements();
- // loads audio for the first time
- loadAudio();
- onNewWordObserver(function(mutations, observer) {
- // loads audio everytime the word DOM changes
- loadAudio();
- });
- playSoundButton.onclick = function(){
- playAudio();
- };
- document.getElementById('submitAnswer').onclick = function(){
- playAudio();
- };
- })();
- // plays the audio
- // finds the word than loads the audo if needed and plays it
- function playAudio(){
- var word = getWord();
- if(word === null) {
- console.log("Cannot get word :(");
- return;
- }
- // if audio is available just play it
- if(audio){
- audio.play();
- return;
- }
- // audio is not available we need to load it
- // make sure audio is not already loading
- if(!isLoadingAudio){
- loadAudio(word);
- }
- // set pendingPlay true so when it loads it will play the audio
- isPendingPlay = true;
- }
- // accepts function that is triggered when new word is shown
- function onNewWordObserver(f){
- MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
- var observer = new MutationObserver(f);
- // configuration of the observer:
- var config = { attributes: true, childList: true, characterData: true };
- // select the target node
- var target = getWordDom();
- // pass in the target node, as well as the observer options
- observer.observe(target, config);
- }
- // accepts function that is triggered when user has answered correctly
- function onCorrectAnswerObserver(f){
- MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
- var observer = new MutationObserver(f);
- // configuration of the observer:
- var config = { attributes: true, childList: true, characterData: true };
- // TODO find target and change the config
- // select the target node
- var target = null;
- // pass in the target node, as well as the observer options
- observer.observe(target, config);
- }
- // adds all the buttons and loading images to the webpage
- function initElements(){
- // create "play audio button"
- playSoundButton = htmlToElement(buttonHtml);
- loadingImage = htmlToElement(loadingImageHtml);
- playSoundButton.appendChild(loadingImage);
- //buttonWraper.innerHTML = buttonHtml;
- // insert
- var answerPanel = document.getElementById('answerPanel');
- answerPanel.parentNode.insertBefore(playSoundButton, answerPanel.nextSibling);
- }
- // get the dom that is containg word that it has to play
- function getWordDom(){
- var detailKanjiDiv = document.getElementById("detailKanji");
- var kanjisDom = detailKanjiDiv.getElementsByClassName("text");
- if(kanjisDom && kanjisDom.length >= 1){
- return kanjisDom[0];
- }
- return null;
- }
- // finds the word that it has to play
- function getWord(){
- var kanjisDom = getWordDom();
- if(kanjisDom != null){
- // get just the first kanji
- var kanjis = kanjisDom.innerHTML;
- var splitKanjis = kanjis.split("<br>");
- return splitKanjis[0];;
- } else {
- return null;
- }
- }
- // get audio url for a word and play it
- function loadAudio(){
- vocubKanji = getWord();
- if(isEmpty(vocubKanji)) throw "vocubKanji cannot be empty!";
- audio = null;
- onAudioLoading();
- GM_xmlhttpRequest ( {
- method: 'GET',
- url: 'https://wanikaniaudio.herokuapp.com/url/' + vocubKanji,
- accept: 'text/xml',
- onreadystatechange: function (response) {
- console.log(response);
- if (response.readyState != 4)
- return;
- // get responseTxt
- var responseTxt = response.responseText;
- // check if responseTxt is valid
- if (!isEmpty(responseTxt) && !responseTxt.startsWith("Cannot")){
- audio = new Audio(responseTxt);
- onAudioReady(audio);
- } else {
- console.log("Invalid response " + responseTxt);
- }
- }
- } );
- }
- // check if string is empty
- function isEmpty(str) {
- return (!str || 0 === str.length);
- }
- /**
- * Creates dom element from string.
- * @param {String} HTML representing a single element
- * @return {Element}
- */
- function htmlToElement(html) {
- var template = document.createElement('template');
- template.innerHTML = html;
- return template.content.firstChild;
- }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址