- // ==UserScript==
- // @name b站统计真实评分
- // @namespace http://tampermonkey.net/
- // @version 0.2.2
- // @description b站统计真实评分,使用后在番剧介绍页和游戏介绍页会多一个“计算真实评分”的按钮,点击将会收集**所有能进行访问的评论**进行统计,得出真实评分。
- // @author thunder-sword【b站up主:月雨洛然】
- // @match https://www.bilibili.com/bangumi/media/md*
- // @match https://www.biligame.com/detail/?id=*
- // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com
- // @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js
- // @license MIT
- // @grant none
- // ==/UserScript==
-
- //常量作用:全局设置
- const settings = {
- "game_float_button": 1, //游戏区页面是否启用悬浮窗按钮,启用后会在页面右下角多一个“计算真实评分”的悬浮按钮,因为页面元素不同缘故,有些游戏不能不好插入页面按钮,所以可以点击悬浮窗运行代码
- "reTryGapTime": 500, //失败时重试等待时间
- }
-
- //作用:检验页面作用域,并执行对应函数
- function mainFunction(){
- let id = 0;
- if(location.href.match(/media\/md(\d+)/)){
- console.log("当前位于视频页面");
- id = location.href.match(/media\/md(\d+)/)[1];
- statMedia(id);
- } else if(location.href.match(/biligame.com\/detail\/\?id=(\d+)/)) {
- console.log("当前位于游戏页面");
- id = location.href.match(/biligame.com\/detail\/\?id=(\d+)/)[1];
- statGame(id);
- } else{
- alert("未知的页面,无法运行脚本");
- throw new Error("未知的页面,无法运行脚本");
- }
- }
-
- //作用:运行时的进度条渲染
- function beforeRender(type) {
- const dialog = document.createElement('div');
- document.body.appendChild(dialog);
- dialog.style.position = 'fixed';
- dialog.style.width = '100%';
- dialog.style.height = '100%';
- dialog.style.background = 'rgba(0,0,0,.8)';
- dialog.style.top = '0';
- dialog.style.left = '0';
- dialog.style.zIndex = '999';
- dialog.style.display = 'flex';
- dialog.style.alignItems = 'center';
- dialog.style.justifyContent = 'center';
-
-
- const dialogContent = document.createElement('div');
- dialog.appendChild(dialogContent);
-
- dialogContent.style.width = '455px';
- dialogContent.style.height = '200px';
- dialogContent.style.background = '#fff';
- dialogContent.style.borderRadius = '6px';
- dialogContent.style.padding = '51px 0';
-
- var render = undefined;
-
- if("media"==type){
- const shortWrap = document.createElement('div');
- dialogContent.appendChild(shortWrap);
- const longWrap = document.createElement('div');
- dialogContent.appendChild(longWrap);
-
- shortWrap.style.width = longWrap.style.width = '455px';
- shortWrap.style.height = longWrap.style.height = '100px';
- shortWrap.style.display = longWrap.style.display = 'flex';
- shortWrap.style.alignItems = longWrap.style.alignItems = 'center';
- shortWrap.style.justifyContent = longWrap.style.justifyContent = 'center';
-
- // --------------
- const shortw1 = document.createElement('div');
- const longw1 = document.createElement('div');
- shortWrap.appendChild(shortw1);
- longWrap.appendChild(longw1);
- shortw1.innerText = '短评:';
- longw1.innerText = '长评:';
- longw1.style.fontSize = shortw1.style.fontSize = '14px';
- longw1.style.color = shortw1.style.color = '#333';
- longw1.style.marginRight = shortw1.style.marginRight = '16px';
-
-
- const shortw2 = document.createElement('div');
- const longw2 = document.createElement('div');
- shortWrap.appendChild(shortw2);
- longWrap.appendChild(longw2);
- longw2.style.width = shortw2.style.width = '300px';
- longw2.style.height = shortw2.style.height = '32px';
- longw2.style.background = shortw2.style.background = '#eee';
- longw2.style.position = shortw2.style.position = 'relative';
-
-
- const shortPrg = document.createElement('div');
- const longPrg = document.createElement('div');
- shortw2.appendChild(shortPrg);
- longw2.appendChild(longPrg);
-
- longPrg.style.position = shortPrg.style.position = 'absolute';
- longPrg.style.left = shortPrg.style.left = '0';
- longPrg.style.top = shortPrg.style.top = '0';
- longPrg.style.width = shortPrg.style.width = '0%';
- longPrg.style.height = shortPrg.style.height = '100%';
- longPrg.style.background = shortPrg.style.background = '#ff85ad';
-
-
- render = function (type, percent) {
- const dom = type == 'long' ? longPrg : shortPrg;
- let width = percent + '%';
- dom.style.width = width;
- }
- } else if("game"==type){
- const nomalWrap = document.createElement('div');
- dialogContent.appendChild(nomalWrap);
-
- nomalWrap.style.width = '455px';
- nomalWrap.style.height = '100px';
- nomalWrap.style.display = 'flex';
- nomalWrap.style.alignItems = 'center';
- nomalWrap.style.justifyContent = 'center';
-
- // --------------
- const nomalw1 = document.createElement('div');
- nomalWrap.appendChild(nomalw1);
- nomalw1.innerText = '评价:';
- nomalw1.style.fontSize = '14px';
- nomalw1.style.color = '#333';
- nomalw1.style.marginRight = '16px';
-
- const nomalw2 = document.createElement('div');
- nomalWrap.appendChild(nomalw2);
- nomalw2.style.width = '300px';
- nomalw2.style.height = '32px';
- nomalw2.style.background = '#eee';
- nomalw2.style.position = 'relative';
-
-
- const nomalPrg = document.createElement('div');
- nomalw2.appendChild(nomalPrg);
-
- nomalPrg.style.position = 'absolute';
- nomalPrg.style.left = '0';
- nomalPrg.style.top = '0';
- nomalPrg.style.width = '0%';
- nomalPrg.style.height = '100%';
- nomalPrg.style.background = '#ff85ad';
-
-
- render = function (percent) {
- const dom = nomalPrg;
- let width = percent + '%';
- dom.style.width = width;
- }
- } else{
- alert(`未知的参数值${type}`);
- throw new Error(`未知的参数值${type}`);
- }
-
- var rmDialog = function () {
- document.body.removeChild(dialog);
- }
-
- return {"render": render, "rmDialog": rmDialog}
- }
-
- async function delay(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
-
- //作用:单次请求视频评论
- //参数说明:
- /*
- *next:单次查询光标位置
- *type:选择长评或短评
- */
- async function mediaGetScore(mid, next, type) {
- while(true){
- let url = `https://api.bilibili.com/pgc/review/${type}/list?media_id=${mid}&ps=12575&sort=0`;
- if (next) {
- url += `&cursor=${next}`;
- }
- const res = await fetch(url, { "method": "GET" });
- const { data } = await res.json();
- if(data!==undefined) return data;
- await delay(settings.reTryGapTime);
- }
- }
- //作用:根据长评或短评统计视频评论主函数,统计的同时调用render进行进度条渲染,返回当前总分数和总人数
- async function mediaGetAllScores(mid, type, render) {
- let score=0, //目前总分数
- count=0; //目前总人数
- let { list, next, total } = await mediaGetScore(mid, undefined, type);
- count+=list.length;
- for (let i = 0; i < list.length; i++) {
- score += list[i].score;
- }
- render(type, count * 100 / total);
-
- while (true) {
- const data = await mediaGetScore(mid, next, type);
- count+=data.list.length;
- for (let i = 0; i < data.list.length; i++) {
- score += data.list[i].score;
- }
- render(type, count * 100 / total);
- next = data.next;
- if (next == 0) {
- return {"score": score, "count": count};
- }
- }
- }
- //作用:视频评分统计主函数,返回最后评分和评分人数
- async function mediaScoreMain(id){
- //所用参数
- let shortScore = 0, //短评总分数
- shortCount = 0, //短评人数
- shortAverage = 0, //短评平均分
- longScore = 0,
- longCount = 0,
- longAverage = 0,
- totalCount = 0,
- totalAverage = 0;
- const func = beforeRender("media");
- const shortData = await mediaGetAllScores(id, "short", func.render);
- shortScore = shortData.score, shortCount = shortData.count;
- shortAverage = shortScore / shortCount;
- console.log(`短评评分人数:${shortCount}`);
- console.log(`短评平均分数:${shortAverage}`);
- const longData = await mediaGetAllScores(id, "long", func.render);
- longScore = longData.score, longCount = longData.count;
- longAverage = longScore / longCount;
- console.log(`长评评分人数:${longCount}`);
- console.log(`长评平均分数:${longAverage}`);
- func.rmDialog();
- totalCount = shortCount + longCount;
- totalAverage = (shortScore + longScore) / totalCount;
- console.log(`总平均分数:${totalAverage}`);
- showStackToast("统计结束");
- showStackToast(`共统计${totalCount}条评价`);
- showStackToast(`真实评分为:${totalAverage.toFixed(1)}`);
- return {"score": totalAverage, "count": totalCount};
- }
-
- //作用:视频评分最后添加元素对真实评分进行显示
- function mediaShowScore(score, count){
- const trueScore = score.toFixed(1);
- const starLc = parseInt(Math.round(trueScore / 2));
- const starHc = 5 - starLc;
- let container = document.querySelector("#app > div.media-info-wrp > div.media-info-content > div > div.media-info-r > div.media-info-datas > div.media-info-score-wrp");
- if(!container){
- alert("获取评分容器失败,不能添加元素!");
- throw new Error("获取评分容器失败,不能添加元素!");
- }
-
- let parent = document.createElement("div");
- container.appendChild(parent);
- parent.className="media-info-score";
- parent.innerHTML=`<div class="media-info-score-content" style="color: #00aeec">${trueScore}</div> <div class="media-info-star-wrapper"><span class="review-stars"></span><div class="media-info-review-times" style="color: #00aeec">${count}人评</div> <div class="to-review-btn"><i class="icon-edit"></i>
- 我要点评
- </div></div>`;
-
- //创建星星样式
- let style = document.createElement("style");
- style.innerText = `.icon-star-light-mod:before {
- content: "\\E906";
- color: #00aeec;
- }`;
- document.head.appendChild(style);
-
- let starsDom = parent.querySelector("span.review-stars");
- for (let i = 0; i < starLc; i++) {
- const star = document.createElement('i');
- star.className = "icon-star icon-star-light-mod";
- starsDom.appendChild(star);
- }
- for (let i = 0; i < starHc; i++) {
- const star = document.createElement('i');
- star.className = "icon-star";
- starsDom.appendChild(star);
- }
- }
-
- //作用:视频评分统计主函数
- function statMedia(mid){
- //添加开始统计按钮
- var container=document.querySelector("#app > div.media-info-wrp > div.media-info-content > div > div.media-info-r > div.media-info-btns");
- if(!container){
- alert("获取按钮容器失败,请刷新重试!");
- throw new Error("获取按钮容器失败,请刷新重试!");
- }
- var button=document.createElement("div");
- button.setAttribute("class", "btn-pay-wrapper");
- button.setAttribute("style", "margin-left: 20px");
- button.innerHTML=`<a href="javascript:;" class="pay-btn ">计算真实评分</a> <div class="pic-wrapper"></div>`;
- button.addEventListener("click", async () => {
- let { score, count } = await mediaScoreMain(mid);
- mediaShowScore(score, count);
- });
- container.appendChild(button);
- }
-
- class NetworkError extends Error {
- constructor(message) {
- super(message);
- this.name = "NetworkError";
- }
- }
-
- //作用:根据传入的原型params生成sign访问api,并将访问结果返回
- async function gameQuery(params){
- const url = "https://line1-h5-pc-api.biligame.com/game/comment/page";
- const sign = CryptoJS.MD5(params + "BdiI92bjmZ9QRcjJBWv2EEssyjekAGKt");
- const data = await fetch(url+"?"+params+"&sign="+sign)
- .then(function(response) {
- if(!response.ok) {
- throw new NetworkError(`HTTP error! status: ${response.status}`);
- }
- return response.json();
- }).catch(error => {
- if (error instanceof NetworkError) {
- console.error("Network error: ", error.message);
- } else {
- console.error("Other error: ", error);
- alert("获取api数据失败,请联系开发者");
- }
- });
- return data;
- }
-
- //作用:获取request_id,即一串32位长度的字符串
- function getRequestId(){
- const a = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
- let request_id = "";
- for(let i = 0;i < 32;i++){
- request_id+=a[Math.floor(Math.random()*32)];
- }
- return request_id;
- }
-
- //作用:统计游戏评论主函数,统计的同时调用render进行进度条渲染,返回当前总分数和总人数
- async function gameGetAllScores(gid, render) {
- let score=0, //目前总分数
- count=0; //目前总人数
- let request_id = getRequestId();
- let params = `appkey=h9Ejat5tFh81cq8V&game_base_id=${gid}&page_num=1&page_size=10&rank_type=3&request_id=${request_id}&ts=9692695382316`;
- let { code, data } = await gameQuery(params);
- if(0!==code){
- alert("访问api失败,请联系开发者");
- console.log(code, data);
- throw new Error("访问api失败,请联系开发者");
- }
- const page_count = data.page_count + 1;
- const total = page_count * 10;
- count+=data.list.length;
- //console.log(render);
- //console.log(count, total);
- for (let i = 0; i < data.list.length; i++) {
- score += data.list[i].grade;
- }
- render(count * 100 / total);
-
- for (let page = 2; page <= page_count; page++) {
- request_id = getRequestId();
- params = `appkey=h9Ejat5tFh81cq8V&game_base_id=${gid}&page_num=${page}&page_size=10&rank_type=3&request_id=${request_id}&ts=9692695382316`;
- const data = await gameQuery(params);
- if ( -703===data.code ) break; //返回数据为空
- if ( 0!==data.code ){
- alert("api访问异常,请联系开发者");
- console.log(data);
- throw new Error("api访问异常,请联系开发者");
- }
- count+=data.data.list.length;
- for (let i = 0; i < data.data.list.length; i++) {
- score += data.data.list[i].grade;
- }
- render(count * 100 / total);
- }
- return {"score": score, "count": count};
- }
-
- //作用:游戏评分统计主函数,返回最后评分和评分人数
- async function gameScoreMain(id){
- //所用参数
- let totalAverage = 0;
- const func = beforeRender("game");
- const { score, count } = await gameGetAllScores(id, func.render);
- totalAverage = score / count;
- console.log(`评分人数:${count}`);
- console.log(`平均分数:${totalAverage}`);
- func.rmDialog();
- showStackToast("统计结束");
- showStackToast(`共统计${count}条评价`);
- showStackToast(`真实评分为:${totalAverage.toFixed(1)}`);
- return {"score": totalAverage, "count": count};
- }
-
- //作用:游戏评分最后添加元素对真实评分进行显示
- function gameShowScore(score, count){
- const trueScore = score.toFixed(1);
- const starLc = parseInt(Math.round(trueScore / 2));
- const starHc = 5 - starLc;
- const container = document.querySelector("body > div.bui-gc > div.header-bar.one-row > div.right-panel > div > div > div.game-introduce > div.introduce-title > div.introduce-info");
- if(!container){
- showStackToast("获取评分容器失败,无法将评分放入页面内!");
- throw new Error("获取评分容器失败,无法将评分放入页面内!");
- }
- const brother = container.querySelector("div.introduce-count");
- if(!brother){
- alert("获取brother评分容器失败,不能添加元素!");
- throw new Error("获取brother评分容器失败,不能添加元素!");
- }
-
- let parent = document.createElement("div");
- container.insertBefore(parent, brother);
- parent.className="introduce-rate";
- parent.innerHTML=`<div class="mini-grade-summary"><span class="bui-star"></span><span class="grade introduce-grade" style="color: #00aeec !important">${trueScore}分</span></div>`;
-
- //创建星星样式
- let style = document.createElement("style");
- style.innerText = `.bui-star .bui-icon-star.filled-mod {
- fill: #00aeec;
- }`;
- document.head.appendChild(style);
-
- let starsDom = parent.querySelector("span.bui-star");
- for (let i = 0; i < starLc; i++) {
- const star = document.createElementNS("http://www.w3.org/2000/svg", "svg");
- star.setAttribute("class","bui-icon bui-icon-star filled-mod");
- star.setAttribute("x",'0');
- star.setAttribute("y",'0');
- star.setAttribute("viewBox",'0 0 20 20');
- const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
- path.setAttribute("d", "M17.7,5.6l-2.3-0.3c-0.8-0.1-1.6-0.7-2-1.5l-1.1-2.3c-1-2-3.7-2-4.7,0l-1,2.3c-0.4,0.8-1.1,1.4-2,1.5L2.2,5.6\n\t\tc-2.2,0.3-3,3.2-1.4,4.8l1.5,1.6c0.6,0.6,0.9,1.6,0.8,2.5l-0.4,2.3c-0.4,2.3,1.8,4,3.8,3l2.2-1.2c0.7-0.4,1.6-0.4,2.4,0l2.2,1.2\n\t\tc1.9,1,4.2-0.7,3.8-3l-0.4-2.3c-0.2-0.9,0.1-1.9,0.8-2.5l1.6-1.6C20.8,8.8,19.9,5.9,17.7,5.6z");
- star.appendChild(path);
- starsDom.appendChild(star);
- }
- for (let i = 0; i < starHc; i++) {
- const star = document.createElementNS("http://www.w3.org/2000/svg", "svg");
- star.setAttribute("class","bui-icon bui-icon-star");
- star.setAttribute("x",'0');
- star.setAttribute("y",'0');
- star.setAttribute("viewBox",'0 0 20 20');
- const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
- path.setAttribute("d", "M17.7,5.6l-2.3-0.3c-0.8-0.1-1.6-0.7-2-1.5l-1.1-2.3c-1-2-3.7-2-4.7,0l-1,2.3c-0.4,0.8-1.1,1.4-2,1.5L2.2,5.6\n\t\tc-2.2,0.3-3,3.2-1.4,4.8l1.5,1.6c0.6,0.6,0.9,1.6,0.8,2.5l-0.4,2.3c-0.4,2.3,1.8,4,3.8,3l2.2-1.2c0.7-0.4,1.6-0.4,2.4,0l2.2,1.2\n\t\tc1.9,1,4.2-0.7,3.8-3l-0.4-2.3c-0.2-0.9,0.1-1.9,0.8-2.5l1.6-1.6C20.8,8.8,19.9,5.9,17.7,5.6z");
- star.appendChild(path);
- starsDom.appendChild(star);
- }
- }
-
- //作用:创建一个在右下角出现的悬浮窗按钮,点击即可执行对应函数
- function createFloatButton(name, func){
-
- // 创建一个 div 元素
- var floatWindow = document.createElement('div');
-
- // 设置 div 的内容
- //floatWindow.innerHTML = '点我执行代码';
- floatWindow.innerHTML = name;
-
- // 设置 div 的样式
- floatWindow.style.position = 'fixed';
- floatWindow.style.bottom = '10px';
- floatWindow.style.right = '10px';
- floatWindow.style.padding = '5px 10px';
- floatWindow.style.backgroundColor = '#333';
- floatWindow.style.color = '#fff';
- floatWindow.style.cursor = 'pointer';
-
- // 将悬浮窗的优先级提高
- floatWindow.style.zIndex = "99999";
-
- var isDragging = false;
- var currentX;
- var currentY;
- var initialX;
- var initialY;
- var xOffset = 0;
- var yOffset = 0;
- var cursorX;
- var cursorY;
-
- floatWindow.addEventListener("mousedown", function(e) {
- if (!isDragging) {
- cursorX = e.clientX;
- cursorY = e.clientY;
- initialX = cursorX - xOffset;
- initialY = cursorY - yOffset;
- isDragging = true;
- }
- });
- floatWindow.addEventListener("mousemove", function(e) {
- if (isDragging) {
- e.preventDefault();
- currentX = e.clientX - initialX;
- currentY = e.clientY - initialY;
-
- xOffset = currentX;
- yOffset = currentY;
-
- setTranslate(currentX, currentY, floatWindow);
- }
- });
- floatWindow.addEventListener("mouseup", async function(e) {
- initialX = currentX;
- initialY = currentY;
-
- isDragging = false;
- // 如果点击时鼠标的位置没有改变,就认为是真正的点击
- if (cursorX === e.clientX && cursorY === e.clientY) {
- await func();
- }
- });
-
- // 为悬浮窗添加事件处理程序,用来监听触摸开始和触摸移动事件
- // 这些事件处理程序的实现方式与上面的鼠标事件处理程序类似
- floatWindow.addEventListener('touchstart', (event) => {
- if (!isDragging) {
- cursorX = event.touches[0].clientX;
- cursorY = event.touches[0].clientY;
- initialX = cursorX - xOffset;
- initialY = cursorY - yOffset;
- isDragging = true;
- }
- });
- floatWindow.addEventListener('touchmove', (event) => {
- if (isDragging) {
- currentX = event.touches[0].clientX - initialX;
- currentY = event.touches[0].clientY - initialY;
-
- xOffset = currentX;
- yOffset = currentY;
-
- setTranslate(currentX, currentY, floatWindow);
- }
- });
-
- // 为悬浮窗添加事件处理程序,用来监听触摸结束事件
- // 这个事件处理程序的实现方式与上面的鼠标事件处理程序类似
- floatWindow.addEventListener('touchend', async () => {
- initialX = currentX;
- initialY = currentY;
-
- isDragging = false;
- // 如果点击时鼠标的位置没有改变,就认为是真正的点击
- if (cursorX === event.touches[0].clientX && cursorY === event.touches[0].clientY) {
- await func();
- }
- });
-
- function setTranslate(xPos, yPos, el) {
- el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
- }
-
- // 将悬浮窗添加到 body 元素中
- document.body.appendChild(floatWindow);
- }
-
- //作用:游戏评分统计主函数
- function statGame(gid){
- //添加悬浮窗按钮
- if(settings["game_float_button"]){
- createFloatButton("计算真实评分", async () => {
- let { score, count } = await gameScoreMain(gid);
- gameShowScore(score, count);
- });
- }
- setTimeout( () => {
- //添加开始统计按钮
- var container=document.querySelector("body > div.bui-gc > div.header-bar.one-row > div.right-panel > div > div > div.game-download > div.download-buttons.not-exist-app-store");
- if(!container){
- showStackToast("获取按钮容器失败,请使用右下角悬浮窗按钮计算真实评分!");
- throw new Error("获取按钮容器失败,请使用右下角悬浮窗按钮计算真实评分!");
- }
- var button=document.createElement("a");
- button.innerHTML=`<span>计算真实评分</span>`;
- button.addEventListener("click", async () => {
- let { score, count } = await gameScoreMain(gid);
- gameShowScore(score, count);
- });
- container.insertBefore(button, container.firstChild);
- }, 800);
- }
-
- //作用:生成toast,让其在toast_container中,显示在页面中上部,会永久性向页面添加一个id为ths_toast_container的div标签
- function showStackToast(message, timeout=3000){
- //没有容器则生成容器
- let box=document.querySelector("body > div#ths_toast_container");
- if(!box){
- box=document.createElement('div');
- box.id="ths_toast_container";
- box.style.cssText = `
- position: fixed;
- top: 10px;
- left: 50%;
- transform: translateX(-50%);
- right: 10px;
- width: 300px;
- height: auto;
- display: flex;
- z-index: 9999;
- flex-direction: column-reverse;`;
- document.body.appendChild(box);
- }
- //创建toast
- const toast = document.createElement('div');
- toast.innerText = message;
- toast.style.cssText = `
- padding: 10px;
- background-color: rgb(76, 175, 80);
- color: rgb(255, 255, 255);
- border-radius: 10px;
- font-size: 24px;
- font-weight: bold;
- text-align: center;
- box-shadow: rgb(0 0 0 / 30%) 0px 5px 10px;
- opacity: 1;
- transition: opacity 0.3s ease-in-out 0s;
- z-index: 9999;
- margin: 5px;
- `;
- box.appendChild(toast);
- toast.style.opacity = 1;
- if(timeout > 0){
- setTimeout(() => {
- toast.style.opacity = 0;
- setTimeout(() => {
- box.removeChild(toast);
- }, 300);
- }, timeout);
- }
- return toast;
- }
-
- (function() {
- 'use strict';
- mainFunction();
- })();
-
-
-
-
-
-
-
-
-
-