Tampermonkey 脚本仅在第一个新节点上工作

Tampermonkey script working only on the first new node

我只是在尝试使用 Tampermonkey 中的代码,当聊天中出现某种消息时它会发出声音。

问题是这个脚本只对第一条消息起作用,我想让它每次都起作用。

我一直在网上寻找,我发现这可能是因为一个叫做 'iFrames' 的东西??

脚本:

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Sound when chat message
// @author       You
// @include      *
// @grant        none
// ==/UserScript==

var exist = false;
var notified = false;
mCoinSound = new Audio("https://dl.dropbox.com/u/7079101/coin.mp3");

setInterval(getRain, 2000);

function getRain() {
    var rain = document.getElementsByClassName('rain-message');
    exist = rain.length === 0 ? false : true;
    notified = (exist && notified);

    if (exist && !notified) {
        mCoinSound.play();
        notified = true;
    }
}

由于您想为每个新的 rain-message 节点播放一次声音,因此像 notified 这样的全局状态布尔值将不起作用。

您需要单独标记每个节点。有多种方法可以做到这一点,但我将展示如何使用 waitForKeyElements() 来实现——因为您还需要等待 AJAX 个节点,而 waitForKeyElements 会自动标记节点。

接下来要避免每秒多次播放声音。为此,我将使用 "debounce" 函数。

最后,不要使用@include *

综上所述,这个脚本应该可以在 Tampermonkey 上运行:

// ==UserScript==
// @name     _Play Sound on new chat message
// @match    *://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
//- The @grant directive is needed to restore the proper sandbox.

let mCoinSound = new soundObj ('https://dl.dropbox.com/u/7079101/coin.mp3');

waitForKeyElements (".rain-message", playSound);

function playSound (jNode) {
    mCoinSound.playDbnc ();
}

function soundObj (audioURL) {
    let dbncTimer   = null;
    let audioObj    = new Audio(audioURL);

    this.playDbnc = function () { // "Debounce" function
        if (dbncTimer)  return;

        dbncTimer = setTimeout (resetTimer, 1111);
        audioObj.play ();
    };

    function resetTimer () {
        clearTimeout (dbncTimer);
        dbncTimer = null;
    }
}




Firefox 在没有用户交互的情况下播放声音有问题,需要 "primed" 手动点击。