script设为text/babel/text/jsx时window load事件监听失效如何解决
问题产生原因
当你给script标签设置type="text/jsx"或text/babel时,浏览器不会直接解析执行这段脚本,而是交由babel-standalone处理。babel-standalone的执行逻辑是等待window的load事件触发完成后,才会批量编译所有标记为babel/jsx类型的脚本并执行。
你在jsx脚本中绑定window.load事件时,load事件已经触发完毕,因此绑定的回调函数永远不会被触发,并不是全局事件监听器停止工作:仅已经触发过的一次性生命周期事件(如load、DOMContentLoaded)会出现这个问题,resize、scroll、click等持续触发的全局事件可以正常绑定监听。
修复方案
- 方案一:将不需要JSX编译的全局事件绑定逻辑,放到无type属性的普通script标签中执行。普通script会被浏览器同步解析,此时绑定的load事件监听可以正常被触发。
- 方案二:如果逻辑必须和JSX代码放在同一文件中,可以直接删除load事件的包裹层。babel-standalone执行你的JSX代码时,页面已经加载完成,需要在load阶段执行的初始化逻辑直接写在顶级作用域即可正常运行。
- 方案三:若要监听非一次性的全局事件,直接在JSX脚本中正常编写监听代码即可,没有兼容性问题。
代码示例
调整后的dos.js代码(方案二)
ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root') ); // 直接执行初始化逻辑,无需包裹load监听 console.log('hi') // 其他全局事件监听可正常编写 window.addEventListener('resize', () => { console.log('窗口尺寸更新') })
调整后的HTML代码(方案一)
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <!-- 普通script标签放置全局事件逻辑 --> <script> window.addEventListener('load', () => { console.log('hi') }) </script> <script src="dos.js" type="text/jsx"></script> </body> </html>
内容的提问来源于stack exchange,提问作者scotby
相关产品推荐
相关产品推荐

