Ext出现的问题:this.dom is undefined

解决ExtJS弹窗关闭问题
本文探讨了在使用ExtJS框架中遇到的弹出窗口关闭导致父页面元素未定义错误的问题,通过设置窗口关闭行为为隐藏而不是关闭,并提供了解决方案及详细原因解释。

问题描述:

      首先一个带有grid的页面,此页面弹出一个窗口,此窗口选择一些数据返回给父页面也就是那个带有grid的页面;数据填充好了而父页面却无法提交提示 this.dom is undefined。   

 

解决方法:

   弹出的窗口的closeAction的不要设置为close,要设置成hide和弹出的窗口的关闭方式改为win.hide()就好了!

 

原因不明!

 

var win = new Ext.Window({
   layout : '',
   title : '',
   closeAction : 'hide',//如果值是close 可能会产生this.dom is undefined
   items : {},
   buttons: [{
        text: '保 存',
        handler:function(){}
              },{
                text: '取 消',
  handler:function(){
    win.close();//win.hiden()可能会产生页面元素错乱的情况
              }
            }]
});

close () : void
关闭窗口,从DOM中删除它,并销毁窗口对象。 在关闭之前触发beforeclose事件,如果事件处理器返回...
在关闭之前触发beforeclose事件,如果事件处理器返回false则取消关闭操作 Closes the Window, removes it from the DOM, 销毁window对象 和所有子控件. 在关闭之前触发 beforeclose事件 如果

事件处理器返回false则取消关闭操作


注: 此方法不会被 closeAction 设置影响,仅当点击 'close'顶部按钮有影响. 如果要隐藏window并不销毁,调用 hide方法.

参数:
     无。
返回值:
     void


hide ([ String/Element animateTarget ],  [ Function callback ],  [ Object scope ] ) : Ext.Window
隐藏窗口,将其设置为不可见,并设置一个负数偏移量。
 
 参数:
    1、animateTarget : String/Element
       (可选)目标元素或者id,在window隐藏时动画效果的起始处 (默认为null,没有动画效果)
    2、callback : Function
       (可选)在window被隐藏后需要调用的回调函数
    3、scope : Object
       (可选)作用域( this 引用)回调函数将在其中被执行。默认为当前window.
 返回值:
    1、Ext.Window
       this

 

------------------------------------------------转载----------------------------------------------------------------

 

1.使用Ext新增一个弹出窗口(组件)时,窗口(组件)的配置对象里的id属性如果和页面上的某个元素E的id相同时,组件会被渲染到元素E上,如果元素E的样式和弹出窗口(组件)的样式不一致时,会导致窗口不能被正常显示。如:

<html>
<head><title>Ext Js</title>
<link href="ext/resources/css/ext-all.css" type="text/css" rel="stylesheet"/>
<script language="javascript" src="ext/adapter/ext/ext-base.js"></script>
<script language="javascript" src="ext/ext-all.js"></script>
<script language="javascript">
function genWindow()
{
  var _window = new Ext.Window({id:'treeWindow',border:0,layout:'fit',modal:true,width:200,height:350,html:'myWindow'});
//与页面上的div treeWindow冲突,弹出窗口不能被正常显示
  _window.show();
}
Ext.onReady(function(genWindow();));
</script>
<body>
<div id="treeWindow" style="height:400px; width:500px; text-align:center;">content</div>
</body>
</html>

 

2.Ext弹出窗口(组件)的隐藏和销毁:如果窗口(组件)的内容不是动态获取的,并且有多次调用窗口(组件)的情况或可能时,则需要使用单例模式来创建弹出窗口(组件)对象,并且窗口(组件)的属性closeAction:'hide'(如果有使用窗口的'X'关闭功能),用hide()方法隐藏弹出窗口(组件),而不能closeAction:'hide'或者用close()方法将窗口(组件)销毁.因为用closeAction:'hide'或者用close()方法会将窗口(组件)销毁的同时也将页面上的静态内容一并销毁,第二次调用就会出错(不正常)或者没有内容。

   function openTeachPlanList()
   {
                /**************************************************************************
                 *如果不是动态内容,并且此方法可能调用多次时,配置窗口属性closeAction:'hide',
                 *不然可能会出现第二次调用此方式时,静态内容已经被删除。
                 *每次调用此方法先检查窗口是否已经打开(隐藏)了,是则show(),否则创建
                 *这种情况属于单例模式的应用,需遵守单例的规则
                ***************************************************************************/
                   if(Ext.getCmp('_tplWindow'))
                {
                        Ext.getCmp('_tplWindow').show();
                        return;
                }
                        
                var tplWin = new Ext.Window({
                        id:'_tplWindow',
                        contentEl:'teachPlanList',//静态内容
                        title:'教案列表',
                        border:0,
                        layout:'fit',
                        buttonAlign:'center',
                        closeAction:'hide',//注意这里使用了hide
                        modal:true,
                        width:500,
                        height:250
                });
                
                tplWin.show();
   }

 

3、Extjs.Window中closeAction:"hide":是将window隐藏,用window.show()可以将它再次显示出来。这样就导致一个问题,如果其他事件调用此window,那么window的部分控件就会因重名而显示不出来。要想显示出来,就得将Window的 closeAction属性改成"close",这样关闭window就将它从内存中撤销了。其他事件调用此window又可以正常显示了。

 

 

--------- beginning of system --------- beginning of main ---------------------------- PROCESS STARTED (3330) for package org.cocos2d.demo ---------------------------- 2025-07-15 15:48:35.316 3330-3359 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082da 2025-07-15 15:48:35.316 3330-3359 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082e5 2025-07-15 15:48:35.328 3330-3359 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x00008c29 2025-07-15 15:48:35.328 3330-3359 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000087fe 2025-07-15 15:48:35.363 3330-3359 EGL_emulation org.cocos2d.demo E tid 3359: eglSurfaceAttrib(1493): error 0x3009 (EGL_BAD_MATCH) 2025-07-15 15:48:36.976 3330-3357 jswrapper org.cocos2d.demo E ScriptEngine::onGetStringFromFile stream not found, possible missing file. 2025-07-15 15:48:36.976 3330-3357 jswrapper org.cocos2d.demo E ScriptEngine::runScript script stream, buffer is empty! 2025-07-15 15:48:36.976 3330-3357 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-15 15:48:37.026 3330-3357 jswrapper org.cocos2d.demo E ScriptEngine::evalString catch exception: 2025-07-15 15:48:37.050 3330-3357 jswrapper org.cocos2d.demo E ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 STACK: [0]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:2 [1]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:3 [2]anonymous@jsb-adapter/jsb-engine.js:2975 [3]download@jsb-adapter/jsb-engine.js:2984 [4]downloadScript@jsb-adapter/jsb-engine.js:2971 [5]a@src/cocos2d-jsb.28d62.js:16668 [6]anonymous@src/cocos2d-jsb.28d62.js:16678 [7]retry@src/cocos2d-jsb.28d62.js:18111 [8]download@src/cocos2d-jsb.28d62.js:16663 [9]load@src/cocos2d-jsb.28d62.js:17318 [10]94.e.exports@src/cocos2d-jsb.28d62.js:17134 [11]_flow@src/cocos2d-jsb.28d62.js:17579 [12]async@src/cocos2d-jsb.28d62.js:17574 [13]anonymous@src/cocos2d-jsb.28d62.js:17261 [14]forEach@src/cocos2d-jsb.28d62.js:18189 [15]94.e.exports@src/cocos2d-jsb.28d62.js:17244 [16]_flow@src/cocos2d-jsb.28d62.js:17579 [17]anonymous@src/cocos2d-jsb.28d62.js:17586 [18]98.e.exports@src/cocos2d-jsb.2 2025-07-15 15:48:37.052 3330-3357 jswrapper org.cocos2d.demo E ScriptEngine::evalString script src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js, failed! 2025-07-15 15:48:37.053 3330-3357 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-15 15:48:49.228 1715-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-15 15:48:49.228 1715-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-15 15:48:49.241 1452-1763 OMXNodeInstance media.codec E setConfig(0xf5210060:google.mp3.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001) 2025-07-15 15:48:49.241 1452-1763 OMXNodeInstance media.codec E getConfig(0xf5210060:google.mp3.decoder, ConfigAndroidVendorExtension(0x6f100004)) ERROR: Undefined(0x80001001) 2025-07-15 15:49:00.001 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.015 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.024 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.037 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.045 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.054 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.061 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.071 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.081 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.091 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.107 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.115 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.123 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.132 1573-1586 memtrack system_server E Couldn't load memtrack module
07-16
<template> <div> <!-- 头部组件 --> <Header /> <div class="notice-container" style="width: 90%; margin: 0 auto;"> <!-- 面包屑导航 --> <div class="breadcrumb"> <el-breadcrumb separator-class="el-icon-arrow-right"> <el-breadcrumb-item :to="{ path: '/front' }">首页</el-breadcrumb-item> <el-breadcrumb-item>值班信息列表</el-breadcrumb-item> </el-breadcrumb> </div> <!-- 数据表格 --> <el-table v-loading="loading" :data="tableData" style="width: 100%" border > <el-table-column prop="name" label="部门" width="150"></el-table-column> <el-table-column label="标题"> <template v-slot="{ row }"> <span class="title-text">{{ row.title }}</span> </template> </el-table-column> <el-table-column prop="updateTime" label="更新时间" width="180"> <template v-slot="{ row }"> {{ formatTime(row.updateTime) }} </template> </el-table-column> <el-table-column label="操作" width="180"> <template v-slot="{ row }"> <el-button size="mini" type="primary" @click="downloadFile(row)" :disabled="!row.fileUrl" > 下载 </el-button> <el-button size="mini" type="success" @click="previewFile(row)" :disabled="!canPreview(row.fileUrl)" > 预览 </el-button> </template> </el-table-column> </el-table> <!-- 分页组件 --> <div class="pagination"> <el-pagination background @current-change="handlePageChange" @size-change="handleSizeChange" :current-page="pageNum" :page-size="pageSize" :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next, jumper" :total="total" ></el-pagination> </div> <!-- 预览对话框 --> <el-dialog :title="previewTitle" :visible.sync="previewVisible" width="80%" top="5vh" > <div v-if="previewType === 'pdf'" class="pdf-preview"> <div class="pagination-controls"> <el-button @click="prevPage" :disabled="currentPage === 1" icon="el-icon-arrow-left" circle ></el-button> <div class="page-info"> <span>第 {{ currentPage }} / {{ totalPages }} 页</span> </div> <el-button @click="nextPage" :disabled="currentPage === totalPages" icon="el-icon-arrow-right" circle ></el-button> <div class="page-jump"> <el-input-number v-model="jumpPage" :min="1" :max="totalPages" controls-position="right" size="mini" ></el-input-number> <el-button type="primary" size="mini" @click="jumpToPage" >跳转</el-button> </div> <div class="zoom-controls"> <el-button @click="changeZoom(-0.1)" icon="el-icon-minus" circle size="mini" ></el-button> <span>{{ (zoomLevel * 100).toFixed(0) }}%</span> <el-button @click="changeZoom(0.1)" icon="el-icon-plus" circle size="mini" ></el-button> </div> </div> <div class="pdf-viewer"> <canvas ref="pdfCanvas"></canvas> </div> </div> <div v-else-if="previewType === 'docx'" class="docx-preview"> <div ref="docxContainer" class="docx-container"></div> </div> <div v-else-if="previewType === 'xlsx'" class="excel-preview"> <div id="luckysheet" style="height: 600px"></div> </div> <div v-else-if="isImage" class="image-preview"> <el-image :src="previewFileUrl" fit="contain" style="max-height: 70vh; width: 100%" > <div slot="error" class="image-error"> <i class="el-icon-picture-outline"></i> <p>图片加载失败</p> </div> </el-image> </div> <div v-else class="unsupported-preview"> <div class="unsupported-content"> <i class="el-icon-warning-outline"></i> <h3>不支持预览此文件类型</h3> <p>请下载文件后使用本地应用打开</p> </div> </div> </el-dialog> </div> <Footer /> </div> </template> <script> import { filePreviewUtil } from '@/utils/filePreview'; import { getFileExtension } from '@/utils/fileUtils'; import Footer from '@/components/Footer.vue' import Header from '@/components/Header.vue'; export default { name: 'DutyMore', components: { Header, Footer }, data() { return { loading: false, pageNum: 1, pageSize: 10, total: 0, tableData: [], searchParams: { name: '', title: '' }, // 预览相关数据 previewVisible: false, previewTitle: '', previewFileUrl: '', previewType: '', isImage: false, // PDF预览相关 pdfDoc: null, currentPage: 1, totalPages: 0, jumpPage: 1, zoomLevel: 1.0, }; }, created() { this.loadData(); }, methods: { // 加载数据 async loadData() { this.loading = true; try { const res = await this.$request.get('/duty/selectPage', { params: { pageNum: this.pageNum, pageSize: this.pageSize, ...this.searchParams } }); if (res.code === '200') { this.tableData = res.data?.list || []; this.total = res.data?.total || 0; } else { this.$message.error(res.msg || '加载数据失败'); } } catch (error) { console.error('加载值班数据失败:', error); this.$message.error('数据加载失败'); } finally { this.loading = false; } }, // 分页大小变化 handleSizeChange(newSize) { this.pageSize = newSize; this.pageNum = 1; this.loadData(); }, // 页码变化 handlePageChange(val) { this.pageNum = val; this.loadData(); }, // 时间格式化 formatTime(time) { if (!time) return ''; const date = new Date(time); return `${date.getFullYear()}-${(date.getMonth()+1).toString().padStart(2,'0')}-${date.getDate().toString().padStart(2,'0')}`; }, // 下载文件 downloadFile(row) { if (!row.fileUrl) { this.$message.warning('该记录没有可下载的文件'); return; } const link = document.createElement('a'); link.href = this.getFullFileUrl(row.fileUrl); link.download = row.title || '值班文件'; link.style.display = 'none'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }, // 判断是否支持预览 canPreview(fileUrl) { if (!fileUrl) return false; const ext = getFileExtension(fileUrl).toLowerCase(); return ['pdf', 'docx', 'xlsx', 'jpg', 'jpeg', 'png', 'gif'].includes(ext); }, // 预览文件 previewFile(row) { if (!row.fileUrl) { this.$message.warning('该记录没有可预览的文件'); return; } this.previewTitle = row.title; this.previewFileUrl = this.getFullFileUrl(row.fileUrl); this.previewType = getFileExtension(row.fileUrl).toLowerCase(); this.isImage = ['jpg', 'jpeg', 'png', 'gif'].includes(this.previewType); // 在打开新弹窗前清理上一次的预览资源 filePreviewUtil.resetPreviousPreview(); if (!this.canPreview(row.fileUrl)) { this.$message.warning('不支持预览此文件类型'); this.previewVisible = true; return; } this.previewVisible = true; this.$nextTick(async () => { try { this.loading = true; if (this.previewType === 'pdf') { await filePreviewUtil.togglePreview( 'pdf', this.previewFileUrl, { canvas: this.$refs.pdfCanvas, currentPage: this.currentPage, zoomLevel: this.zoomLevel } ); } else if (this.previewType === 'docx') { await filePreviewUtil.togglePreview( 'docx', this.previewFileUrl, { container: this.$refs.docxContainer } ); } else if (this.previewType === 'xlsx') { await filePreviewUtil.togglePreview( 'xlsx', this.previewFileUrl, { containerId: 'luckysheet', fileName: this.previewTitle } ); } } catch (error) { console.error('预览失败:', error); this.$message.error('预览失败: ' + error.message); } finally { this.loading = false; } }); }, // 获取完整文件URL getFullFileUrl(url) { return url.includes('http') ? url : (this.$baseUrl + url); }, // PDF预览方法 async previewPDF() { try { const { pdfDoc, totalPages } = await filePreviewUtil.previewPDF( this.previewFileUrl, { canvas: this.$refs.pdfCanvas, currentPage: this.currentPage, zoomLevel: this.zoomLevel } ); this.pdfDoc = pdfDoc; this.totalPages = totalPages; this.currentPage = 1; this.jumpPage = 1; } catch (error) { console.error('PDF预览失败:', error); throw error; } }, // DOCX预览方法 async previewDocx() { try { await filePreviewUtil.previewDocx(this.previewFileUrl, { container: this.$refs.docxContainer }); } catch (error) { console.error('DOCX预览失败:', error); throw error; } }, // Excel预览方法 async previewExcel() { try { await filePreviewUtil.previewExcel(this.previewFileUrl, { containerId: 'luckysheet', fileName: this.previewTitle }); } catch (error) { console.error('Excel预览失败:', error); throw error; } }, // PDF分页控制方法 async prevPage() { if (this.currentPage > 1) { this.currentPage--; this.jumpPage = this.currentPage; await this.renderPDFPage(this.currentPage); } }, async nextPage() { if (this.currentPage < this.totalPages) { this.currentPage++; this.jumpPage = this.currentPage; await this.renderPDFPage(this.currentPage); } }, async jumpToPage() { if (this.jumpPage >= 1 && this.jumpPage <= this.totalPages) { this.currentPage = this.jumpPage; await this.renderPDFPage(this.currentPage); } else { this.$message.warning('请输入有效的页码'); } }, async renderPDFPage(pageNum) { if (!this.pdfDoc || pageNum < 1 || pageNum > this.totalPages) return; try { await filePreviewUtil.renderPDFPage( this.pdfDoc, pageNum, this.$refs.pdfCanvas, this.zoomLevel ); } catch (error) { console.error('渲染PDF页面失败:', error); this.$message.error('渲染页面失败: ' + error.message); } }, async changeZoom(delta) { this.zoomLevel = Math.min(Math.max(this.zoomLevel + delta, 0.25), 3.0); await this.renderPDFPage(this.currentPage); } }, beforeDestroy() { // 清理预览资源 if (this.previewType === 'xlsx') { filePreviewUtil.resetExcel(); } if (this.previewType === 'pdf') { filePreviewUtil.resetPDF(this.$refs.pdfCanvas); } } }; </script> <style scoped> .notice-container { margin-top: 20px; } .breadcrumb { margin-bottom: 20px; padding: 10px 0; border-bottom: 1px solid #eee; } .title-text { color: #333; } .pagination { margin-top: 20px; text-align: center; } .el-table { margin-top: 10px; } /* 预览相关样式 */ .pdf-preview { display: flex; flex-direction: column; height: 100%; } .pagination-controls { display: flex; justify-content: center; align-items: center; gap: 15px; padding: 10px; margin-bottom: 10px; flex-wrap: wrap; } .page-info { font-size: 14px; min-width: 100px; text-align: center; } .page-jump { display: flex; align-items: center; gap: 8px; } .zoom-controls { display: flex; align-items: center; gap: 8px; } .pdf-viewer { min-height: 500px; max-height: 70vh; overflow: auto; } .docx-preview { min-height: 500px; max-height: 70vh; overflow: auto; } .excel-preview { min-height: 500px; max-height: 70vh; } .image-preview { display: flex; justify-content: center; align-items: center; min-height: 500px; max-height: 70vh; } .unsupported-preview { display: flex; justify-content: center; align-items: center; min-height: 200px; } .unsupported-content { text-align: center; } .unsupported-content i { font-size: 40px; color: #e6a23c; margin-bottom: 10px; } .unsupported-content h3 { margin-bottom: 10px; color: #606266; } </style>// src/utils/filePreview.js import { renderAsync } from "docx-preview"; import LuckyExcel from "luckyexcel"; import axios from "axios"; import { asynLoad } from "@/utils/excel"; // src/utils/filePreview.js export const previewPDF = { async initPDF(fileUrl) { const pdfjsLib = await this.loadPDFJS(); const pdfData = await this.fetchPDFData(fileUrl); // 设置 workerSrc pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.16.105/build/pdf.worker.min.js"; // 初始化 PDF 文档 return pdfjsLib.getDocument({ data: pdfData, cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.16.105/cmaps/", cMapPacked: true }).promise; }, async fetchPDFData(fileUrl) { try { const response = await fetch(fileUrl, { method: 'GET', mode: 'cors' }); if (!response.ok) throw new Error('Failed to fetch PDF file'); const arrayBuffer = await response.arrayBuffer(); return new Uint8Array(arrayBuffer); } catch (error) { console.error('Error fetching PDF:', error); throw error; } }, async loadPDFJS() { const scripts = [ "https://unpkg.com/pdfjs-dist@2.16.105/build/pdf.min.js", "https://unpkg.com/pdfjs-dist@2.16.105/build/pdf.worker.min.js" ]; await Promise.all(scripts.map(src => asynLoad(src))); return window.pdfjsLib; }, async renderPage(pdfDoc, pageNum, canvas, zoomLevel = 1.0) { if (!pdfDoc || pageNum < 1 || pageNum > pdfDoc.numPages) return; try { const page = await pdfDoc.getPage(pageNum); const viewport = page.getViewport({ scale: zoomLevel }); // 设置 Canvas 尺寸 canvas.width = viewport.width; canvas.height = viewport.height; const renderContext = { canvasContext: canvas.getContext('2d'), viewport: viewport }; await page.render(renderContext).promise; return pdfDoc.numPages; } catch (error) { console.error('Error rendering PDF page:', error); throw error; } } }; // DOCX预览工具 export const previewDocx = { async render(fileUrl, containerElement) { try { const response = await fetch(fileUrl); const blob = await response.blob(); await renderAsync(blob, containerElement); return true; } catch (error) { throw new Error('DOCX预览失败: ' + error.message); } } }; // src/utils/filePreview.js export const previewExcel = { async render(fileUrl, fileName, containerId) { try { // 动态加载 LuckySheet 资源 const baseURL = "https://unpkg.com/luckysheet@latest/dist"; // 替换为备用 CDN const resources = [ `${baseURL}/plugins/css/pluginsCss.css`, `${baseURL}/plugins/plugins.css`, `${baseURL}/css/luckysheet.css`, `${baseURL}/assets/iconfont/iconfont.css`, `${baseURL}/plugins/js/plugin.js`, `${baseURL}/luckysheet.umd.js` ]; await Promise.all(resources.map(src => asynLoad(src, src.endsWith('.css')))); if (!window.luckysheet) { throw new Error('Luckysheet 加载失败'); } // 获取 Excel 文件 const response = await axios.get(fileUrl, { responseType: 'arraybuffer' }); const arrayBuffer = new Uint8Array(response.data); const file = new File([arrayBuffer], fileName); // 转换并渲染 Excel return new Promise((resolve, reject) => { LuckyExcel.transformExcelToLucky(file, (exportJson, luckyIns) => { if (!exportJson.sheets || !exportJson.sheets.length) { reject('无法读取 Excel 文件内容'); return; } window.luckysheet.create({ container: containerId, data: exportJson.sheets, title: exportJson.info.name, lang: 'zh', showinfobar: false, allowEdit: false }); resolve(luckyIns); }, () => { reject('转换 Excel 文件失败'); }); }); } catch (error) { console.error('Error rendering Excel:', error); throw error; } }, destroy(instance) { if (instance && typeof instance.destroy === 'function') { instance.destroy(); } } }; // 通用预览工具 // src/utils/filePreview.js export const filePreviewUtil = { async togglePreview(fileType, fileUrl, options) { // 清理上一次的预览资源 this.resetPreviousPreview(); switch (fileType.toLowerCase()) { case 'pdf': await this.previewPDF(fileUrl, options); break; case 'docx': await this.previewDocx(fileUrl, options); break; case 'xlsx': await this.previewExcel(fileUrl, options); break; default: throw new Error('Unsupported file type for preview'); } }, async previewPDF(fileUrl, { canvas, currentPage = 1, zoomLevel = 1.0 }) { const pdfDoc = await previewPDF.initPDF(fileUrl); await previewPDF.renderPage(pdfDoc, currentPage, canvas, zoomLevel); return { pdfDoc, totalPages: pdfDoc.numPages }; }, async previewDocx(fileUrl, { container }) { await previewDocx.render(fileUrl, container); }, async previewExcel(fileUrl, { containerId, fileName }) { return previewExcel.render(fileUrl, fileName, containerId); }, resetPreviousPreview() { // 清理 PDF 预览 if (this.currentPreviewType === 'pdf') { this.resetPDF(this.currentCanvas); } // 清理 Excel 预览 if (this.currentPreviewType === 'xlsx') { this.resetExcel(); } // 清理 DOCX 预览 if (this.currentPreviewType === 'docx') { this.resetDocx(this.currentDocxContainer); } // 重置当前预览类型 this.currentPreviewType = null; this.currentCanvas = null; this.currentDocxContainer = null; }, resetPDF(canvas) { if (canvas) { const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); canvas.width = 0; canvas.height = 0; } }, resetExcel() { if (window.luckysheet && typeof window.luckysheet.destroy === 'function') { window.luckysheet.destroy(); } window.luckysheet = null; }, resetDocx(container) { if (container) { container.innerHTML = ''; } } }; 如果我先预览pdf在预览excel不会有问题,但我现预览excel在预览pdf时,excel弹窗依旧纯在,报错Uncaught runtime errors: × ERROR Script error. at handleError (webpack-internal:///./node_modules/webpack-dev-server/client/overlay.js:299:58) at eval (webpack-internal:///./node_modules/webpack-dev-server/client/overlay.js:318:7)以及location.js:61 Uncaught TypeError: Cannot read properties of undefined (reading 'left') at $s (location.js:61:37) at Object.overshow (postil.js:161:21) at HTMLDocument.<anonymous> (handler.js:1533:26) at HTMLDocument.dispatch (plugin.js:1:39175) at d.handle (plugin.js:1:37266)
06-20
// ====== 环境修复与全局对象安全 ====== (function() { // 安全获取全局对象的函数(支持严格模式和所有环境) const getGlobalObject = () => { // 1. 优先使用现代标准 globalThis if (typeof globalThis !== 'undefined') return globalThis; // 2. 处理严格模式限制 try { const globalFromFn = Function('return this')(); if (globalFromFn) return globalFromFn; } catch (e) { console.warn('[EnvFix] Function constructor blocked in strict mode'); } // 3. 环境特定对象 if (typeof global !== 'undefined') return global; // Node.js if (typeof window !== 'undefined') return window; // 浏览器 if (typeof self !== 'undefined') return self; // Web Worker // 4. Cocos Creator 原生环境特殊处理 if (typeof cc !== 'undefined' && cc.sys && cc.sys.__globalAdapter) { return cc.sys.__globalAdapter; } // 5. 最后手段:创建新的全局对象 console.error('[EnvFix] Unable to determine global object, creating new'); return {}; }; const globalObj = getGlobalObject(); // 修复关键全局变量(使用 Object.defineProperty 防止覆盖) const defineGlobal = (name, value) => { if (typeof globalObj[name] === 'undefined') { Object.defineProperty(globalObj, name, { value, writable: true, configurable: true, enumerable: true }); console.log(`[EnvFix] Defined global: ${name}`); } }; // 定义关键全局对象 defineGlobal('global', globalObj); defineGlobal('self', globalObj); defineGlobal('globalThis', globalObj); defineGlobal('window', globalObj); // 原生平台特殊处理 if (cc && cc.sys && cc.sys.isNative) { // 确保 XMLHttpRequest 存在 if (typeof XMLHttpRequest === 'undefined') { defineGlobal('XMLHttpRequest', function() { return cc.loader.getXMLHttpRequest(); }); } // 确保 document 对象存在 if (typeof document === 'undefined') { defineGlobal('document', { createElement: () => ({ appendChild: () => {} }), head: { appendChild: () => {} }, body: { appendChild: () => {} } }); } // 确保 location 对象存在 if (typeof location === 'undefined') { defineGlobal('location', { href: 'file://', protocol: 'file:', hostname: 'localhost', host: 'localhost', origin: 'file://' }); } console.log('[EnvFix] Native environment patched'); } // 确保 require 函数存在 if (typeof globalObj.require === 'undefined') { defineGlobal('require', function(module) { if (globalObj.__modules && globalObj.__modules[module]) { return globalObj.__modules[module]; } console.warn(`[RequireFallback] Module '${module}' not found`); return {}; }); } })(); // ====== 引擎初始化保护系统 ====== const EngineReady = (function() { let _promise = null; let _resolve = null; let _isReady = false; let _checkInterval = null; const safeCheckEngine = () => { // 引擎已初始化 if (cc && cc.game && cc.game._isEngineInited) { return true; } // 尝试监听初始化事件 if (cc && cc.game && cc.game.once) { const eventName = cc.game.EVENT_ENGINE_INITED || 'engine-inited'; cc.game.once(eventName, () => { _resolve && _resolve(); _isReady = true; _checkInterval && clearInterval(_checkInterval); }); return true; } return false; }; return { get isReady() { return _isReady; }, get promise() { return _promise; }, init() { if (!_promise) { _promise = new Promise(resolve => { _resolve = () => { _isReady = true; resolve(); _checkInterval && clearInterval(_checkInterval); }; // 首次检查 if (safeCheckEngine()) return; // 轮询检查 _checkInterval = setInterval(() => { safeCheckEngine() && _resolve(); }, 100); }); } return _promise; }, safeAccess(callback) { if (_isReady) { try { return callback(); } catch (e) { console.error('[EngineSafe] Error:', e); } } return _promise.then(callback).catch(e => { console.error('[EngineSafe] Async error:', e); }); } }; })(); EngineReady.init(); // ====== 游戏主入口 ====== async function gameMainEntry() { try { console.log('[Main] Waiting for engine initialization...'); await EngineReady.promise; console.log('[Main] Engine ready'); // 基本引擎配置 EngineReady.safeAccess(() => { if (cc.view) { cc.view.enableRetina(true); cc.view.resizeWithBrowserSize(true); cc.view.setDesignResolutionSize(960, 640, cc.ResolutionPolicy.SHOW_ALL); } }); // 加载SDK await loadGravityEngineSDK(); // 加载启动场景 await loadStartScene(); } catch (error) { console.error('[Main] Initialization failed:', error); try { cc.director.loadScene('start'); } catch (fallbackError) { displayErrorFallback('启动失败\n请重启应用'); } } } // 错误显示后备方案 function displayErrorFallback(message) { try { const errorDiv = document.createElement('div'); errorDiv.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: black; color: white; display: flex; justify-content: center; align-items: center; z-index: 9999; font: 24px Arial, sans-serif; text-align: center; white-space: pre-line; padding: 20px; `; errorDiv.textContent = message; document.body.appendChild(errorDiv); } catch (e) { console.error('[Fallback] Display failed:', e); } } // ====== SDK加载器增强版 ====== async function loadGravityEngineSDK() { // 使用相对路径解决加载问题 const sdkPaths = [ './assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js', '_plugs/lib/gravityengine.mg.cocoscreator.min.js', 'lib/gravityengine.mg.cocoscreator.min.js' ]; for (const path of sdkPaths) { try { // 关键修复:在加载 SDK 前确保全局对象完整 ensureGlobalEnvironment(); // JSB 特殊处理:使用 require 加载 if (cc.sys.isNative && cc.sys.__globalAdapter?.require) { cc.sys.__globalAdapter.require(path); console.log('[SDK] Native require loaded:', path); } else { await loadScript(path); console.log('[SDK] Loaded from:', path); } // 关键修复:加载后再次检查全局对象 ensureGlobalEnvironment(); initGravityEngine(); return; } catch (e) { console.warn('[SDK] Load failed:', path, e.message); } } console.error('[SDK] All paths failed'); handleSDKLoadFailure(); } function ensureGlobalEnvironment() { // 获取全局对象 const getGlobalObject = () => { if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; if (typeof self !== 'undefined') return self; return Function('return this')() || {}; }; const globalObj = getGlobalObject(); // 确保 self 在所有环境中都存在 if (typeof self === 'undefined') { console.warn('[GlobalFix] self is undefined, patching...'); Object.defineProperty(globalObj, 'self', { value: globalObj, writable: true, configurable: true, enumerable: true }); } // 确保其他关键全局对象存在 const requiredGlobals = ['window', 'global', 'globalThis', 'document', 'location']; requiredGlobals.forEach(name => { if (typeof globalObj[name] === 'undefined') { console.warn(`[GlobalFix] ${name} is undefined, patching...`); Object.defineProperty(globalObj, name, { value: globalObj, writable: true, configurable: true, enumerable: true }); } }); // 原生平台特殊处理 if (cc && cc.sys && cc.sys.isNative) { // 确保 location 对象存在 if (typeof location === 'undefined') { Object.defineProperty(globalObj, 'location', { value: { href: 'file://', protocol: 'file:', hostname: 'localhost' }, writable: false, configurable: false, enumerable: true }); } } } function loadScript(path) { return new Promise((resolve, reject) => { // 优先使用 Cocos 的加载系统 if (cc.assetManager?.loadScript) { cc.assetManager.loadScript(path, (err) => { if (err) { // 原生平台特殊处理 if (cc.sys.isNative) { console.warn('[SDK] Using native fallback for script loading'); try { // 原生平台直接执行脚本 const jsb = cc.sys.__globalAdapter; if (jsb && jsb.require) { jsb.require(path); return resolve(); } } catch (nativeError) { console.error('[SDK] Native require failed:', nativeError); } } reject(err); } else { resolve(); } }); return; } // 后备方案:直接创建 script 标签 try { const script = document.createElement('script'); script.src = path; script.onload = () => resolve(); script.onerror = () => reject(new Error(`Failed to load ${path}`)); document.head.appendChild(script); console.warn('[SDK] Using DOM fallback for script loading'); } catch (e) { reject(e); } }); } function initGravityEngine() { let GravityEngine = null; // 1. 尝试标准方式获取 if (typeof GravityEngine === 'function') { console.log('[SDK] GravityEngine found in local scope'); } // 2. 尝试从全局对象中查找 else if (typeof window.GravityEngine === 'function') { GravityEngine = window.GravityEngine; console.warn('[SDK] Found GravityEngine in window object'); } // 3. 尝试从其他全局对象中查找 else if (typeof global.GravityEngine === 'function') { GravityEngine = global.GravityEngine; console.warn('[SDK] Found GravityEngine in global object'); } // 4. 尝试从 self 对象中查找 else if (typeof self.GravityEngine === 'function') { GravityEngine = self.GravityEngine; console.warn('[SDK] Found GravityEngine in self object'); } // 5. 最后尝试从 globalThis 中查找 else if (typeof globalThis.GravityEngine === 'function') { GravityEngine = globalThis.GravityEngine; console.warn('[SDK] Found GravityEngine in globalThis object'); } else { console.error('[SDK] GravityEngine not found'); return; } try { // 使用您的 AppID 624768904 GravityEngine.init({ appId: '624768904', enableLog: true }); console.log('[SDK] GravityEngine initialized with AppID 624768904'); } catch (e) { console.error('[SDK] Init failed:', e); } } function handleSDKLoadFailure() { console.warn('[SDK] Using fallback analytics'); window.GravityEngine = { init: () => console.warn('SDK unavailable'), trackEvent: () => {} }; } // ====== 场景加载器 ====== async function loadStartScene() { try { // 加载主资源包 await new Promise((resolve) => { if (!cc.assetManager?.loadBundle) { console.warn('[Scene] AssetManager unavailable'); return resolve(); } cc.assetManager.loadBundle('main', (err) => { if (err) console.error('[Scene] Bundle load error:', err); resolve(); }); }); // 加载场景 if (cc.director?.loadScene) { cc.director.loadScene('start'); } else { throw new Error('Director unavailable'); } } catch (error) { console.error('[Scene] Load failed:', error); try { cc.director.loadScene('start'); } catch (e) { throw new Error('Fallback scene load failed'); } } } // ====== UI_Entry组件 ====== const { ccclass, property } = cc._decorator; @ccclass export default class UI_Entry extends cc.Component { @property(cc.ProgressBar) progress_loading = null; loginTimeoutHandler = null; onLoad() { EngineReady.safeAccess(() => { try { cc.director.getCollisionManager().enabled = true; this._show(); } catch (e) { console.error('[UI] onLoad error:', e); this.startLoadGame(); } }).catch(e => { console.error('[UI] Engine access error:', e); this.startLoadGame(); }); } onDestroy() { this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler); } async _show() { this.progress_loading.progress = 0; // 平台SDK初始化 if (cc.sys.isBrowser) { try { await this.initYPSDK(); } catch (e) { console.error('[YPSDK] Init failed:', e); this.startLoadGame(); } } else { this.startLoadGame(); } // 登录超时保护 this.setLoginTimeout(); } setLoginTimeout() { if (cc.tween) { this.loginTimeoutHandler = cc.tween(this) .delay(10) .call(() => { console.warn('[Login] Timeout after 10s'); this.startLoadGame(); }) .start(); } else { setTimeout(() => this.startLoadGame(), 10000); } } async initYPSDK() { if (typeof YPSDK === 'undefined') { console.warn('[YPSDK] SDK unavailable'); return; } const config = { gameChannelList: { h5: { platformType: "h5", version: "1.0.0" }, tt: { platformType: "tt", appId: "tt09297f94961f881b02" }, wx: { platformType: "wx", appId: "wx6baaaa27ab5186ff" } } }; await YPSDK.init(39, "https://platform-shop-dev.hanyougame.com", config); await YPSDK.login(); if (YPSDK.setLoginCallBack) { YPSDK.setLoginCallBack(success => { if (!success) return; // 取消超时 this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler); // 初始化分析SDK if (r_GravityPlatform.default?.GA_Init) { r_GravityPlatform.default.GA_Init(YPSDK.Platform.loginData.bindingId); } this.startLoadGame(); }); } else { this.startLoadGame(); } } startLoadGame() { const tasks = [ this._loadGameConfig, this._loadRemoteConfig, this._loadExcelData, this._loadUserData, this._loadCommonBundle, this._loadMainBundle ].map(fn => fn.bind(this)); this.executeTasks(tasks, () => this._loadGame()); } executeTasks(tasks, finalCallback) { let completed = 0; const total = tasks.length; const runTask = async (index) => { if (index >= total) { finalCallback(); return; } try { await tasks[index](); completed++; this._setProgress(completed / total); runTask(index + 1); } catch (e) { console.error(`[Task ${index}] Failed:`, e); completed++; this._setProgress(completed / total); runTask(index + 1); // 继续执行后续任务 } }; runTask(0); } async _loadExcelData() { if (!r_ExcelLoader?.ExcelLoader?.loadAll) { console.warn('[Data] ExcelLoader unavailable'); return; } await r_ExcelLoader.ExcelLoader.loadAll(); console.log('[Data] Excel loaded'); } async _loadGameConfig() { if (!r_ResLoader.default?.loadRes) { console.warn('[Config] ResLoader unavailable'); return; } const jsonAsset = await r_ResLoader.default.loadRes( "resources", "config/GameConfig", cc.JsonAsset ); if (jsonAsset && r_GameConfig.default) { r_GameConfig.default.appConfig = jsonAsset.json; jsonAsset.decRef && jsonAsset.decRef(); console.log('[Config] Game config loaded'); } } async _loadRemoteConfig() { if (!r_GameConfig.default?.appConfig?.RemoteUrl) { console.warn('[Config] RemoteUrl not set'); return; } const remoteUrl = r_GameConfig.default.appConfig.RemoteUrl; const remotePath = cc.path.join(remoteUrl, "ADConfig.json"); try { const remoteConfig = await r_ResLoader.default.loadRemote(remotePath, { ext: ".json" }); if (remoteConfig?.json && r_GravityPlatform.default) { r_GravityPlatform.default.videoId = remoteConfig.json.ADUnitId[0]; r_GameConfig.default.adConfig = remoteConfig.json; console.log('[Config] Remote config loaded'); } } catch (e) { console.error('[Config] Remote load failed:', e); } } async _loadCommonBundle() { if (!r_ResLoader.default?.loadBundle) { console.warn('[Bundle] ResLoader unavailable'); return; } try { await r_ResLoader.default.loadBundle(r_BundleConfig.BundleNames.Common); console.log('[Bundle] Common loaded'); } catch (e) { console.error('[Bundle] Common load failed:', e); } } async _loadMainBundle() { if (!r_ResLoader.default?.loadBundle) { console.warn('[Bundle] ResLoader unavailable'); return; } try { await r_ResLoader.default.loadBundle(r_BundleConfig.MainGameBundle); console.log('[Bundle] Main loaded'); } catch (e) { console.error('[Bundle] Main load failed:', e); } } async _loadUserData() { try { // 音频初始化 r_AudioManager.AudioMgr?.init(); // 全局配置 r_GameGlobalVariable.GameGlobalVariable?.initPeiZhi(); // 网络检测 if (YPSDK?.Common?.curChannelData) { const platformType = YPSDK.Common.curChannelData.platformType; if (platformType === YPSDK.GamePlatformType.WX || platformType === YPSDK.GamePlatformType.TT) { r_YpNetMag.YpNetMag?.failSever(() => { r_YpNetMag.YpNetMag.isFail = true; }); } } // 用户数据初始化 if (YPSDK?.Platform?.loginData) { await r_YpNetMag.YpNetMag?.initServer(YPSDK.Platform.loginData); } } catch (e) { console.error('[User] Load failed:', e); } } _loadGame() { try { const guideIndex = r_PlayerDataManager.PlayerDataMgr.GetGuideIndexByTaskName( r_Const_Common.GuideName.战斗背包 ); if (guideIndex !== r_Const_Common.GameBagGuideIndex.引导完结) { // 新玩家流程 r_PlayerDataManager.PlayerDataMgr.GMSetGuideIndex?.( r_Const_Common.GuideName.战斗背包, r_Const_Common.GameBagGuideIndex.引导初始1 ); r_GameDataManager.GameDataMgr?.ClearGameBagData(); r_GameGlobalVariable.GameGlobalVariable.nowlevel = 1; r_UIManager.default?.open( r_BundleConfig.BundleNames.Game, r_UIConfig_Game.UIView_Game.UI_GameView ); } else { // 老玩家流程 r_EventManager.EventMgr?.dispatchEvent(r_EvenType.EVENT_TYPE.Game_Load_View, true); r_UIManager.default?.open( r_BundleConfig.BundleNames.Home, r_UIConfig_Home.UIView_Home.UI_Hall ); } // 白名单检查 this.checkWhiteList(); } catch (e) { console.error('[Game] Load failed:', e); try { cc.director.loadScene('start'); } catch (sceneError) { console.error('[Game] Scene load failed:', sceneError); } } } async checkWhiteList() { try { if (!YPSDK?.Platform?.loginData || !YPSDK.platformUrl) return; const url = `${YPSDK.platformUrl}/User/GetCfgData?userId=${YPSDK.Platform.loginData.userUid}&keyId=NoVideo`; if (r_HttpManager.HttpMgr?.requestData) { r_HttpManager.HttpMgr.requestData(res => { if (res?.data?.keyData === "true") { r_PlayerDataManager.PlayerDataMgr.WHITE_NAME_NO_VIDEO = true; } }, url); } } catch (e) { console.error('[WhiteList] Check failed:', e); } } _setProgress(progress) { if (!this.progress_loading) return; this.progress_loading.progress = Math.max(0, Math.min(1, progress)); } } // ====== 启动游戏 ====== if (cc?.game?.run) { cc.game.run(() => { // 确保环境修复完成 ensureGlobalEnvironment(); gameMainEntry(); }); } else { setTimeout(() => { ensureGlobalEnvironment(); gameMainEntry(); }, 1000); } 针对上述问题 给我修改后的完整代码
07-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值