/** * 弹窗组件 * 使用方法: * 1. 引入此JS文件 * 2. 调用 PopupManager.init() 初始化 * 3. 调用 PopupManager.show() 显示弹窗 * 4. 调用 PopupManager.hide() 隐藏弹窗 */ (function(window) { 'use strict'; // 表单管理器 const FormManager = { // 配置选项 config: { // 弹窗模式配置 scrollThreshold: 0.6, // 滚动阈值 autoShow: true, // 是否自动显示 overlayClose: false, // 点击遮罩层是否关闭 confirmClose: false, // 关闭时是否确认 // 内嵌模式配置 containerId: '', // 内嵌容器ID // 成功提示配置 successPromptAutoHide: false, // 是否自动隐藏成功提示 successPromptDuration: 3000 // 成功提示显示时长(毫秒) }, // 状态管理 state: { popupShown: false, popupInitialized: false, inlineInitialized: false }, // DOM元素 elements: { // 弹窗元素 popupContainer: null, popupOverlay: null, popupForm: null, // 内嵌元素 inlineContainer: null, inlineForm: null }, // CSS样式 styles: ` /* 弹窗样式 */ .popup-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 99998; display: none; opacity: 0; transition: opacity 0.3s ease; } .popup-overlay.show { display: block; opacity: 1; } .popup-container { background: white; border-radius: 16px; width: 100%; max-width: 800px; padding-top: 30px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 99999; margin: auto; display: none; opacity: 0; transition: opacity 0.3s ease; } .popup-container.show { display: block; opacity: 1; } /* 内嵌样式 */ #inhtm-form-box{ background: white; } .inline-form-container { background: white; width: 100%; max-width: 1200px; padding: 30px; margin: 20px auto; box-sizing: border-box; } .inline-form-container .form-content{ max-height: 100%; overflow: hidden; } /* 通用样式 */ .form-content { padding: 30px; max-height: 80vh; overflow-y: auto; } .form-header { text-align: center; margin-bottom: 32px; position: relative; } .form-main-title { font-size: 21px; font-weight: bold; color: #000; margin-bottom: 8px; } .form-subtitle { font-size: 13px; color: #697990; } .popup-close-btn { position: absolute; top: 10px; right: 10px; width: 18px; height: 18px; border-radius: 50%; background: #fff; border: 1px solid #000; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; color: #000; } .popup-close-btn::after{ content:''; width:50%; height:1px; background:#000; position:absolute; top:0; left:0; right:0; bottom:0; margin:auto; transform: rotate(45deg); } .popup-close-btn::before{ content:''; width:50%; height:1px; background:#000; position:absolute; top:0; left:0; right:0; bottom:0; margin:auto; transform: rotate(-45deg); } .form-group { margin-bottom: 12px; } .form-label { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 400; font-size: 12px; color: #0D1414; margin-bottom: 8px; } .form-input { width: 100%; padding: 12px 16px; border: 1px solid rgba(112,124,141,0.5216); border-radius: 8px; font-size: 12px; background: white; box-sizing: border-box; } .form-input:focus { outline: none; border-color: #0066FF; } .form-input::placeholder { color: #999; } .form-select { width: 100%; padding: 12px 16px; border: 1px solid rgba(112,124,141,0.5216); border-radius: 8px; font-size: 12px; background: white; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8.825L1.175 4 2.238 2.938 6 6.7l3.763-3.762L10.825 4z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; cursor: pointer; box-sizing: border-box; } .form-select:focus { outline: none; border-color: #0066FF; } .form-radio-group, .form-checkbox-group { display: flex; flex-wrap: wrap; gap: 10px; } .form-radio-item, .form-checkbox-item { min-width:calc(50% - 10px); display: flex; align-items: center; cursor: pointer; } .form-radio-input, .form-checkbox-input { background-color: transparent; -webkit-appearance: none; width:0; hieght:0; margin:0; } .form-radio-input::before, .form-checkbox-input::before{ content: ''; position: absolute; left: 0; top: 0; width: 17px; height: 17px; border: 1px solid #687C9B; border-radius: 50%; background: white; } .form-radio-label, .form-checkbox-label { position: relative; padding-left: 28px; cursor: pointer; font-size: 12px; color: #000; line-height: 20px; } .form-radio-input:checked::before{ border-color: #0066FF; } .form-checkbox-input:checked::before{ border-color: #0066FF; background: #0066FF; } .form-radio-input:checked::after{ content: ''; position: absolute; left: 5px; top: 5px; width: 9px; height: 9px; border-radius: 50%; background: #0066FF; } .form-checkbox-input:checked::after { content: ''; position: absolute; left: 6px; top: 3px; width: 5px; height: 9px; border-radius: 0 0 3px 0; border: 2px solid #fff; border-width: 0 2px 2px 0; transition: all 0.3s ease; transform: rotate(45deg); } .form-textarea { width: 100%; padding: 5px 10px; border: 1px solid rgba(112,124,141,0.5216); border-radius: 8px; font-size: 12px; background: white; resize: none; min-height: 100px; font-family: inherit; box-sizing: border-box; } .form-textarea:focus { outline: none; border-color: #0066FF; } .form-submit-btn { width: 100%; padding: 16px; background: #141421; color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: background-color 0.3s; } .form-submit-btn:hover { background: #141421; } .form-submit-btn:active { transform: translateY(1px); } /* 移动端样式 */ @media (max-width: 768px) { .popup-container { position: fixed; bottom: 0; left: 0; top: auto; transform: none; max-width: 100%; border-radius: 16px 16px 0 0; margin: 0; } .form-content { padding: 17px; } .popup-close-btn { top: 10px; right: 10px; width: 18px; height: 18px; font-size: 18px; } .inline-form-container { // margin: 10px; padding: 17px; } } /* PC端样式 */ @media (min-width: 769px) { .form-content{ padding-left:5%; padding-right:5%; } .form-main-title { font-size: 24px; margin-bottom: 12px; } .form-submit-btn{ max-width:400px; margin:0 auto; display:block; } .form-subtitle { font-size: 14px; } .popup-close-btn { top: 15px; right: 15px; width: 24px; height: 24px; font-size: 20px; } .form-group { margin-bottom: 20px; display: flex; align-items: center; } .form-label { margin-right: 15px; width: 100px; flex-shrink: 0; text-align: right; word-wrap:break-word; } .form-input, .form-select, .form-textarea { flex: 1; } .form-radio-group, .form-checkbox-group { flex: 1; gap: 10px; } .form-radio-item, .form-checkbox-item { min-width:calc(25% - 10px); } .inline-form-container{ padding-left:5%; padding-right:5%; } } /* 去除默认样式 */ .form-input, .form-select, .form-textarea { -webkit-appearance: none; -moz-appearance: none; appearance: none; } .form-input:focus, .form-select:focus, .form-textarea:focus { outline: none; } .form-textarea { resize: none; } /* 去除移动端点击高亮 */ .popup-container *, .inline-form-container * { -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .form-input, .form-textarea { -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; } .banner{ width: 100%; position: relative; } .banner img{ display: block; width: 100%; border-radius: 16px; } .prompt-q{ position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index:100000; display:none; } .prompt-q .prompt-box{ width: 100%; height:100%; display: flex; align-items: center; justify-content: center; } .prompt-q .prompt-box .prompt{ position: relative; width: 248px; // height: 154px; padding:30px 10px; background: #FFFFFF; border-radius: 12px; display: flex; align-items: center; justify-content: center; flex-direction: column; font-family: MiSans, MiSans; font-weight: 400; font-size: 12px; color: #A7AEBD; } .prompt-q .prompt-box .prompt-icon{ width: 40px; height: 40px; border-radius: 50%; background: #00D483; display: flex; align-items: center; justify-content: center; margin-bottom: 10px; position: relative; } .prompt-q .prompt-box .prompt-icon::after{ content:''; width:25%; height:50%; border-color:#fff; border-style: solid; border-width: 0 4px 4px 0; transform: rotate(45deg); margin-top:-5px } .prompt-q .prompt-box .prompt-icon.error{ background:rgba(241, 61, 61,1); } .prompt-q .prompt-box .prompt-icon.error::before{ content:''; width:3px; height:50%; border-width: 0; background:#fff; transform: rotate(45deg); position:absolute; top:0; left:0; right:0; bottom:0; margin:auto; } .prompt-q .prompt-box .prompt-icon.error::after{ content:''; width:3px; height:50%; border-width:0; background:#fff; transform: rotate(-45deg); position:absolute; top:0; left:0; right:0; bottom:0; margin:auto; } .prompt-q .prompt-box .close-btn { position: absolute; top: 10px; right: 10px; width: 18px; height: 18px; border-radius: 50%; background: #fff; border: 1px solid #000; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; color: #000; } .prompt-q .prompt-box .close-btn::after{ content:''; width:50%; height:1px; background:#000; position:absolute; top:0; left:0; right:0; bottom:0; margin:auto; transform: rotate(45deg); } .prompt-q .prompt-box .close-btn::before{ content:''; width:50%; height:1px; background:#000; position:absolute; top:0; left:0; right:0; bottom:0; margin:auto; transform: rotate(-45deg); } /* 文件上传样式 */ .form-upload-item { display: flex; flex-wrap: wrap; gap: 10px; flex:1; height:148px; } .form-upload-label { flex:1; padding: 8px 16px; border: 1px solid rgba(112,124,141,0.5216); background:#fff; border-radius: 6px; cursor: pointer; font-size: 12px; color: #666; transition: all 0.3s ease; min-width: 80px; display: flex; align-items: center; justify-content: center; flex-direction: column; position: relative; } .form-upload-input { display: none; } .form-upload-label .upload-text{ padding-top:30px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M21 15V19C21 19.5304 20.7893 20.0391 20.4142 20.4142C20.0391 20.7893 19.5304 21 19 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V15' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M17 8L12 3L7 8' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M12 3V15' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: top 0 center; background-size: 24px 24px; font-family: MiSans, MiSans; font-weight: 400; font-size: 14px; color: #0B1426; } .form-upload-label .upload-des{ font-family: MiSans, MiSans; font-weight: 400; font-size: 12px; color: #A7AEBD; } /* 拖拽状态样式 */ .form-upload-label.drag-over { border-color: #0066FF; background-color: rgba(0, 102, 255, 0.1); color: #0066FF; } .form-upload-label.drag-over .upload-text { color: #0066FF; } .form-upload-label.drag-over .upload-text { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M21 15V19C21 19.5304 20.7893 20.0391 20.4142 20.4142C20.0391 20.7893 19.5304 21 19 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V15' stroke='%230066FF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M17 8L12 3L7 8' stroke='%230066FF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M12 3V15' stroke='%230066FF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); } .upload-preview { position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; border-radius: 6px; z-index: 1; } .upload-preview-item { position: relative; width: 120px; height: 120px; border: 1px solid #ddd; border-radius: 6px; overflow: hidden; background: #f9f9f9; } .upload-preview-item img, .upload-preview-item video { width: 100%; height: 100%; object-fit: cover; } .upload-preview-item video { position: relative; } .upload-preview-item video::-webkit-media-controls-play-button { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 60px; height: 60px; background: rgba(0, 0, 0, 0.7); border-radius: 50%; border: none; outline: none; } .upload-preview-item video::-webkit-media-controls-play-button:before { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 0; height: 0; border-left: 20px solid white; border-top: 12px solid transparent; border-bottom: 12px solid transparent; margin-left: 4px; } /* 禁止视频播放的样式 */ .upload-preview-item video { pointer-events: none; cursor: default; } .upload-preview-item video::-webkit-media-controls { display: none !important; } .upload-preview-item video::-webkit-media-controls-panel { display: none !important; } .upload-preview-item video::-webkit-media-controls-play-button { display: none !important; } .upload-preview-item video::-webkit-media-controls-start-playback-button { display: none !important; } .upload-preview-item .remove-btn { position: absolute; top: 2px; right: 2px; width: 18px; height: 18px; background: rgba(0, 0, 0, 0.6); color: white; border: none; border-radius: 50%; cursor: pointer; font-size: 12px; display: flex; align-items: center; justify-content: center; } .upload-preview-item .remove-btn:hover { background: rgba(255, 0, 0, 0.8); } .upload-preview-item .file-info { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, 0.7); color: white; font-size: 10px; padding: 2px 4px; text-align: center; } .upload-preview-item .file-icon { display: flex; align-items: center; justify-content: center; height: 100%; font-size: 24px; color: #999; } `, // HTML模板 template: `

Form Submition

`, // 初始化弹窗模式 init: function(options = {}) { if (this.state.popupInitialized) { console.warn('弹窗已经初始化过了'); return; } // 合并配置 this.config = Object.assign({}, this.config, options); // 注入样式 this.injectStyles(); // 创建弹窗DOM元素 this.createPopupElements(); // 绑定弹窗事件 this.bindPopupEvents(); // 设置状态 this.state.popupInitialized = true; console.log('弹窗初始化完成'); }, // 初始化内嵌模式 initInline: function(options = {}) { if (this.state.inlineInitialized) { console.warn('内嵌表单已经初始化过了'); return; } // 合并配置 const inlineConfig = Object.assign({}, this.config, options); // 注入样式 this.injectStyles(); // 创建内嵌DOM元素 this.createInlineElements(inlineConfig); // 绑定内嵌事件 this.bindInlineEvents(inlineConfig); // 设置状态 this.state.inlineInitialized = true; console.log('内嵌表单初始化完成'); }, // 注入样式 injectStyles: function() { if (document.getElementById('form-styles')) { return; } const style = document.createElement('style'); style.id = 'form-styles'; style.textContent = this.styles; document.head.appendChild(style); }, // 创建全局弹窗 createGlobalPrompt: function() { // 检查是否已经存在全局弹窗 if (document.getElementById('global-prompt')) { return; } // 创建全局弹窗HTML const promptHTML = `
`; // 添加到body document.body.insertAdjacentHTML('beforeend', promptHTML); // 绑定关闭按钮事件 const closeBtn = document.querySelector('#global-prompt .close-btn'); if (closeBtn) { closeBtn.addEventListener('click', () => { this.hidePromptDialog(); }); } console.log('全局弹窗创建完成'); }, // 创建弹窗DOM元素 createPopupElements: function() { // 创建遮罩层 this.elements.popupOverlay = document.createElement('div'); this.elements.popupOverlay.className = 'popup-overlay'; this.elements.popupOverlay.id = 'popupOverlay'; // 创建弹窗容器 this.elements.popupContainer = document.createElement('div'); this.elements.popupContainer.className = 'popup-container'; this.elements.popupContainer.id = 'popupContainer'; // 创建关闭按钮 const closeBtn = document.createElement('button'); closeBtn.className = 'popup-close-btn'; closeBtn.id = 'popupCloseBtn'; // closeBtn.innerHTML = '×'; // 创建表单内容 const temp = document.createElement('div'); temp.innerHTML = this.template; const formContent = temp.querySelector('.form-content'); this.elements.popupForm = temp.querySelector('.form-element'); this.elements.popupContainer.appendChild(closeBtn); this.elements.popupContainer.appendChild(formContent); // 添加到页面 document.body.appendChild(this.elements.popupOverlay); document.body.appendChild(this.elements.popupContainer); var bg = document.getElementById('form-header-id').dataset.bg_color let targetContainer = document.getElementsByClassName('popup-container'); for (let i = 0; i < targetContainer.length; i++) { targetContainer[i].style.backgroundColor = bg; } }, // 创建内嵌DOM元素 createInlineElements: function(config) { // 创建内嵌容器 this.elements.inlineContainer = document.createElement('div'); this.elements.inlineContainer.className = 'inline-form-container'; this.elements.inlineContainer.id = 'inlineFormContainer'; // 创建表单内容 const temp = document.createElement('div'); temp.innerHTML = this.template; const formContent = temp.querySelector('.form-content'); this.elements.inlineForm = temp.querySelector('.form-element'); // 组装内嵌表单 this.elements.inlineContainer.appendChild(formContent); // 查找目标容器 if(!config.containerId)return let targetContainer = document.getElementById(config.containerId); if (!targetContainer) { // 如果目标容器不存在 return // targetContainer = document.createElement('div'); // targetContainer.id = config.containerId; // document.body.appendChild(targetContainer); } // 添加到目标容器 targetContainer.appendChild(this.elements.inlineContainer); var bg = document.getElementById('form-header-id').dataset.bg_color let element = document.getElementsByClassName('inline-form-container'); for (let i = 0; i < element.length; i++) { element[i].style.backgroundColor = bg; } }, // 绑定弹窗事件 bindPopupEvents: function() { // 关闭按钮 document.getElementById('popupCloseBtn').addEventListener('click', () => { this.close(); }); // 遮罩层点击 this.elements.popupOverlay.addEventListener('click', () => { if (this.config.overlayClose) { this.hide(); } }); // 表单提交 this.elements.popupForm.addEventListener('submit', (e) => { e.preventDefault(); this.handlePopupSubmit(); }); // 文件上传事件 this.bindUploadEvents(this.elements.popupForm); // 成功弹窗关闭按钮 const closeBtn = document.querySelector('.prompt-q .close-btn'); if (closeBtn) { closeBtn.addEventListener('click', () => { this.hideSuccessPrompt(); }); } // 滚动监听 if (this.config.autoShow) { this.bindScrollListener(); } }, // 绑定内嵌事件 bindInlineEvents: function(config) { // 表单提交 this.elements.inlineForm.addEventListener('submit', (e) => { e.preventDefault(); this.handleInlineSubmit(); }); // 文件上传事件 this.bindUploadEvents(this.elements.inlineForm); // 成功弹窗关闭按钮(内嵌表单也需要) const closeBtn = this.elements.inlineForm.querySelector('.prompt-q .close-btn'); if (closeBtn) { closeBtn.addEventListener('click', () => { this.hideSuccessPrompt(); }); } }, // 绑定滚动监听 bindScrollListener: function() { const checkScrollPosition = () => { if (this.state.popupShown) return; const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const windowHeight = window.innerHeight; const documentHeight = document.documentElement.scrollHeight; const scrollPercentage = scrollTop / (documentHeight - windowHeight); if (scrollPercentage >= this.config.scrollThreshold) { this.show(); window.removeEventListener('scroll', checkScrollPosition); } }; window.addEventListener('scroll', checkScrollPosition); }, // 显示弹窗 show: function() { if (!this.state.popupInitialized) { console.error('弹窗未初始化,请先调用 init()'); return; } this.elements.popupOverlay.classList.add('show'); this.elements.popupContainer.classList.add('show'); this.state.popupShown = true; console.log('弹窗已显示'); }, // 隐藏弹窗 hide: function() { if (!this.state.popupInitialized) { return; } this.elements.popupOverlay.classList.remove('show'); this.elements.popupContainer.classList.remove('show'); this.state.popupShown = false; console.log('弹窗已隐藏'); }, // 关闭弹窗(带确认) close: function() { if (this.config.confirmClose) { if (confirm('确定要关闭弹窗吗?')) { this.hide(); } } else { this.hide(); } }, // 处理弹窗表单提交 handlePopupSubmit: function() { var formData = new FormData(this.elements.popupForm); this.handleSubmit(formData,1) return }, // 处理内嵌表单提交 handleInlineSubmit: function() { var formData = new FormData(this.elements.inlineForm); this.handleSubmit(formData,2) }, // 处理表单提交 handleSubmit: function(formData,type) { // 创建formData对象 // 使用Fetch API进行AJAX提交 fetch('https://portal.remotivia-i.com/subform?site=5f8305fa20ad18a2c2425bfdace3a553', { method: 'POST', body: formData }) .then(response => { if (!response.ok) { throw new Error('网络响应不正常'); } return response.json(); }) .then(data => { if(data.code == 1){ if(type == 1)this.elements.popupForm.reset(); else this.elements.inlineForm.reset(); this.showSuccess(data.msg); return false; }else { this.showError(data.msg); return false } }) .catch(error => { this.showError(error.message); }); }, // 显示公共提示弹窗 showPrompt: function(type = 'success', message = '') { // 确保全局弹窗存在 this.createGlobalPrompt(); // 获取全局弹窗 const globalPrompt = document.getElementById('global-prompt'); if (!globalPrompt) { console.error('全局弹窗创建失败'); return; } const promptIcon = globalPrompt.querySelector('.prompt-icon'); const promptText = globalPrompt.querySelector('.prompt > div:last-child'); // 设置图标状态 if (type === 'success') { promptIcon.classList.remove('error'); promptText.textContent = message || '操作成功'; } else if (type === 'error') { promptIcon.classList.add('error'); promptText.textContent = message || '操作失败'; } // 显示弹窗 globalPrompt.style.display = 'block'; console.log('全局弹窗显示:', type, message); // 根据配置自动隐藏 if (this.config.successPromptAutoHide) { setTimeout(() => { this.hidePromptDialog(); }, this.config.successPromptDuration); } }, // 隐藏提示弹窗 hidePromptDialog: function() { // 隐藏全局弹窗 const globalPrompt = document.getElementById('global-prompt'); if (globalPrompt) { globalPrompt.style.display = 'none'; } }, // 公共方法:显示成功提示 showSuccess: function(message = '操作成功') { this.showPrompt('success', message); }, // 公共方法:显示错误提示 showError: function(message = '操作失败') { this.showPrompt('error', message); }, // 公共方法:手动隐藏提示 hidePrompt: function() { this.hidePromptDialog(); }, // 绑定文件上传事件 bindUploadEvents: function(form) { const uploadLabels = form.querySelectorAll('.form-upload-item .form-upload-label'); if (!uploadLabels || uploadLabels.length === 0) return; uploadLabels.forEach((labelEl) => { const uploadInput = labelEl.querySelector('.form-upload-input'); const uploadPreview = labelEl.querySelector('.upload-preview'); if (!uploadInput || !uploadPreview) return; // 文件选择事件(每个控件独立绑定) uploadInput.addEventListener('change', (e) => { this.handleFileSelect(e.target.files, uploadPreview); }); // 拖拽事件(每个控件独立绑定) labelEl.addEventListener('dragover', (e) => { e.preventDefault(); e.stopPropagation(); labelEl.classList.add('drag-over'); }); labelEl.addEventListener('dragleave', (e) => { e.preventDefault(); e.stopPropagation(); labelEl.classList.remove('drag-over'); }); labelEl.addEventListener('drop', (e) => { e.preventDefault(); e.stopPropagation(); labelEl.classList.remove('drag-over'); const files = e.dataTransfer.files; this.handleFileSelect(files, uploadPreview); }); // 防止页面默认拖拽行为 labelEl.addEventListener('dragenter', (e) => { e.preventDefault(); e.stopPropagation(); }); }); }, // 处理文件选择 handleFileSelect: function(files, previewContainer) { Array.from(files).forEach(file => { // 验证文件类型 // if (!this.validateFileType(file)) { // alert(`文件 ${file.name} 类型不支持,请选择图片或视频文件`); // return; // } // 验证文件大小 if (!this.validateFileSize(file)) { alert(`文件 ${file.name} 过大,请选择小于50MB的文件`); return; } // 创建预览 this.createFilePreview(file, previewContainer); }); }, // 验证文件类型 validateFileType: function(file) { const allowedTypes = [ 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp', 'video/mp4', 'video/avi', 'video/mov', 'video/wmv', 'video/flv', 'video/webm' ]; return allowedTypes.includes(file.type); }, // 验证文件大小 validateFileSize: function(file) { const maxSize = 100 * 1024 * 1024; // 50MB return file.size <= maxSize; }, // 创建文件预览 createFilePreview: function(file, container) { // 清空之前的预览 container.innerHTML = ''; const previewItem = document.createElement('div'); previewItem.className = 'upload-preview-item'; previewItem.dataset.fileName = file.name; previewItem.dataset.fileSize = this.formatFileSize(file.size); previewItem.dataset.fileType = file.type; // 创建文件信息 const fileInfo = document.createElement('div'); fileInfo.className = 'file-info'; fileInfo.textContent = this.formatFileSize(file.size); if (file.type.startsWith('image/')) { // 图片预览 const img = document.createElement('img'); const reader = new FileReader(); reader.onload = (e) => { img.src = e.target.result; }; reader.readAsDataURL(file); previewItem.appendChild(img); } else if (file.type.startsWith('video/')) { // 视频预览(禁止播放) const video = document.createElement('video'); video.controls = false; video.muted = true; video.preload = 'metadata'; // 禁止播放 video.addEventListener('play', (e) => { e.preventDefault(); video.pause(); }); video.addEventListener('click', (e) => { e.preventDefault(); }); const reader = new FileReader(); reader.onload = (e) => { video.src = e.target.result; }; reader.readAsDataURL(file); previewItem.appendChild(video); } else { // 其他文件类型显示图标 const fileIcon = document.createElement('div'); fileIcon.className = 'file-icon'; fileIcon.innerHTML = '📄'; previewItem.appendChild(fileIcon); } // previewItem.appendChild(removeBtn); previewItem.appendChild(fileInfo); container.appendChild(previewItem); }, // 显示上传提示 showUploadPrompt: function(container) { container.innerHTML = ''; container.style.display = 'none'; }, // 格式化文件大小 formatFileSize: function(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }, // 获取上传的文件列表 getUploadedFiles: function(form) { const previewItems = form.querySelectorAll('.upload-preview-item'); const files = []; previewItems.forEach(item => { const fileName = item.dataset.fileName; const fileSize = item.dataset.fileSize; const fileType = item.dataset.fileType; files.push({ name: fileName, size: fileSize, type: fileType }); }); return files; }, // 销毁弹窗 destroyPopup: function() { if (this.elements.popupOverlay) { this.elements.popupOverlay.remove(); } if (this.elements.popupContainer) { this.elements.popupContainer.remove(); } this.state.popupInitialized = false; this.state.popupShown = false; console.log('弹窗已销毁'); }, // 销毁内嵌表单 destroyInline: function() { if (this.elements.inlineContainer) { this.elements.inlineContainer.remove(); } this.state.inlineInitialized = false; console.log('内嵌表单已销毁'); }, // 销毁所有 destroy: function() { this.destroyPopup(); this.destroyInline(); if (document.getElementById('form-styles')) { document.getElementById('form-styles').remove(); } } }; // 主管理器 window.FormManager = FormManager; // 自动初始化(可选) if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { FormManager.init(); FormManager.initInline(); FormManager.createGlobalPrompt(); // 创建全局弹窗 }); } else { FormManager.init(); FormManager.initInline(); FormManager.createGlobalPrompt(); // 创建全局弹窗 } })(window);