您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
使用rrweb录制网页操作,方便测试同学快速定位问题
// ==UserScript== // @name RRWeb 测试录制工具 // @namespace http://tampermonkey.net/ // @version 1.0.0 // @description 使用rrweb录制网页操作,方便测试同学快速定位问题 // @author RRWeb Recorder Team // @match *://*/* // @grant none // @license MIT // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/rrweb.min.js // @supportURL https://github.com/your-username/rrweb-recorder/issues // @homepageURL https://github.com/your-username/rrweb-recorder // ==/UserScript== (function () { 'use strict'; // 录制相关变量 let isRecording = false; let stopRecording = null; let events = []; let startTime = null; // 创建悬浮按钮 function createFloatingButton() { const button = document.createElement('div'); button.id = 'rrweb-recorder-btn'; button.innerHTML = ` <div class="recorder-icon"> <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"> <circle cx="12" cy="12" r="8"/> </svg> </div> <span class="recorder-text">开始录制</span> `; // 样式 button.style.cssText = ` position: fixed; bottom: 20px; right: 20px; width: 120px; height: 50px; background: #4CAF50; color: white; border-radius: 25px; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 14px; font-weight: 500; transition: all 0.3s ease; user-select: none; gap: 8px; `; // 悬停效果 button.addEventListener('mouseenter', () => { button.style.transform = 'scale(1.05)'; button.style.boxShadow = '0 6px 16px rgba(0,0,0,0.2)'; }); button.addEventListener('mouseleave', () => { button.style.transform = 'scale(1)'; button.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)'; }); // 点击事件 button.addEventListener('click', toggleRecording); document.body.appendChild(button); return button; } // 切换录制状态 function toggleRecording() { if (isRecording) { stopRecordingSession(); } else { startRecordingSession(); } } // 开始录制 function startRecordingSession() { if (typeof rrweb === 'undefined') { showNotification('rrweb库加载失败,请刷新页面重试', 'error'); return; } events = []; startTime = Date.now(); isRecording = true; try { stopRecording = rrweb.record({ emit(event) { events.push(event); }, checkoutEveryNms: 10 * 1000, // 每10秒创建一个检查点 maskTextSelector: '[data-sensitive]', // 遮蔽敏感文本 maskInputOptions: { password: true, email: false, text: false } }); updateButtonState(); showNotification('开始录制...', 'success'); } catch (error) { console.error('录制启动失败:', error); showNotification('录制启动失败: ' + error.message, 'error'); isRecording = false; } } // 停止录制 function stopRecordingSession() { if (stopRecording) { stopRecording(); stopRecording = null; } isRecording = false; updateButtonState(); if (events.length > 0) { showNotification('录制完成,准备下载...', 'success'); downloadRecording(); } else { showNotification('没有录制到任何事件', 'warning'); } } // 更新按钮状态 function updateButtonState() { const button = document.getElementById('rrweb-recorder-btn'); const icon = button.querySelector('.recorder-icon svg circle'); const text = button.querySelector('.recorder-text'); if (isRecording) { button.style.background = '#f44336'; text.textContent = '停止录制'; icon.style.animation = 'pulse 1.5s infinite'; // 添加脉冲动画 if (!document.getElementById('rrweb-pulse-style')) { const style = document.createElement('style'); style.id = 'rrweb-pulse-style'; style.textContent = ` @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } `; document.head.appendChild(style); } } else { button.style.background = '#4CAF50'; text.textContent = '开始录制'; icon.style.animation = 'none'; } } // 下载录制文件 function downloadRecording() { const recordingData = { events: events, startTime: startTime, endTime: Date.now(), url: window.location.href, userAgent: navigator.userAgent, timestamp: new Date().toISOString() }; const dataStr = JSON.stringify(recordingData, null, 2); const dataBlob = new Blob([dataStr], { type: 'application/json' }); const link = document.createElement('a'); link.href = URL.createObjectURL(dataBlob); link.download = `recording-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.json`; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(link.href); } // 显示通知 function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 12px 20px; border-radius: 8px; color: white; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 14px; z-index: 10001; max-width: 300px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); transition: all 0.3s ease; `; // 根据类型设置颜色 const colors = { success: '#4CAF50', error: '#f44336', warning: '#ff9800', info: '#2196F3' }; notification.style.background = colors[type] || colors.info; notification.textContent = message; document.body.appendChild(notification); // 3秒后自动移除 setTimeout(() => { if (notification.parentNode) { notification.style.opacity = '0'; notification.style.transform = 'translateX(100%)'; setTimeout(() => { document.body.removeChild(notification); }, 300); } }, 3000); } // 等待页面加载完成后初始化 function init() { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); return; } // 检查rrweb是否加载 if (typeof rrweb === 'undefined') { console.warn('rrweb库未加载,等待加载...'); setTimeout(init, 1000); return; } createFloatingButton(); console.log('RRWeb录制工具已加载'); } // 启动初始化 init(); // 页面卸载时停止录制 window.addEventListener('beforeunload', () => { if (isRecording) { stopRecordingSession(); } }); })();