You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于随机时间间隔实现JavaScript通知错开显示并设置触发次数

实现FOMO社交证明通知的触发问题

我想要在页面上实现一种“FOMO/社交证明”效果,让通知滑入后再滑出。要求通知触发5次后停止,且每次触发间隔随机时长。

但目前用setTimeout实现时,所有通知无间隔连续触发,控制台显示时长值不同,但都是初始设置的,导致通知堆叠而非错开显示。

期望的流程:

  • 5秒后→通知滑入,等待7秒后滑出,间隔随机时长
  • 重复上述动作,总共触发5次后停止

原代码如下:

$(function() {

    var counterVal = 0;

    doFomoSequence(counterVal);

    function doFomoSequence(counterVal){
        var secVal = Math.floor(Math.random() * 10000);
        //secVal = 3000;
        setTimeout(doFomo(secVal), 5000);
        counterVal++;
        if(counterVal <= 5){
            doFomoSequence(counterVal);
        }


    }

    function doFomo(secVal){
        console.log(secVal);
        setTimeout( slideIn, secVal );
        setTimeout( slideOut, secVal + 7000 );
    }

    function slideIn(){
        $('#notification').animate({left: 20}, 'slow');
    }
    function slideOut(){
        $('#notification').animate({left: -400}, 'slow');
    }
});

问题分析与解决方案

核心问题

  1. setTimeout调用错误:setTimeout(doFomo(secVal), 5000)里直接执行了doFomo(secVal),而非传递函数引用,导致所有doFomo立即执行,通知直接堆叠。
  2. 递归时机错误:原代码一次性递归调用5次doFomoSequence,没有等待前一次通知的完整周期结束,导致所有通知的定时器同时启动。

修正后的代码

$(function() {
    var counterVal = 0;
    // 初始等待5秒后启动第一次通知
    setTimeout(startFomoSequence, 5000);

    function startFomoSequence() {
        if (counterVal >= 5) return; // 达到5次直接停止
        
        // 生成0-10秒的随机间隔时长
        var randomDelay = Math.floor(Math.random() * 10000);
        
        // 执行本次通知的滑入+滑出逻辑
        slideIn();
        setTimeout(slideOut, 7000); // 通知显示7秒后滑出
        
        // 等待滑出动画完成 + 随机间隔后,启动下一次通知
        setTimeout(function() {
            counterVal++;
            startFomoSequence();
        }, 7000 + randomDelay + 600); // +600是补偿slideOut的slow动画时长(默认600ms)
    }

    function slideIn(){
        $('#notification').animate({left: 20}, 'slow');
    }
    function slideOut(){
        $('#notification').animate({left: -400}, 'slow');
    }
});

关键改动说明

  • 改成链式调度逻辑:只有当前一次通知的滑出动画完全结束,再加上随机间隔后,才触发下一次通知,彻底避免堆叠。
  • 修正setTimeout调用方式:传递函数引用而非立即执行函数,保证定时器按预期延迟触发。
  • 增加动画时长补偿:给slideOut的动画留足执行时间,确保通知完全滑出后再开始下一轮流程。

内容的提问来源于stack exchange,提问作者hanji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:32:53