如何在React组件中实现第三方嵌入按钮与脚本并监听点击事件?
可行的WeTravel嵌入按钮React组件实现方案及问题解答
原代码问题分析
你的React代码无法运行主要有几个核心问题:
- 笔误:
triggerScript函数里的etAction应为setAction - React语法错误:按钮的类名属性需用
className而非原生HTML的class - 脚本加载逻辑不合理:每次
action状态变化都会重复添加/移除脚本,易引发DOM操作错误,且第三方脚本无需重复加载
修复后的React组件代码
import { useEffect, useRef } from 'react'; const WeTravelBookButton = () => { // 用ref标记脚本是否已加载,避免重复注入 const scriptLoaded = useRef(false); useEffect(() => { if (!scriptLoaded.current) { const script = document.createElement('script'); script.src = "https://cdn.wetravel.com/widgets/embed_checkout.js"; script.async = true; // 脚本加载完成后标记状态 script.onload = () => { scriptLoaded.current = true; }; document.body.appendChild(script); return () => { // 移除前先检查脚本是否存在于DOM中,避免报错 if (document.body.contains(script)) { document.body.removeChild(script); scriptLoaded.current = false; } }; } }, []); return ( <button className="wtrvl-checkout_button" id="wetravel_button_widget" data-env="https://maximumimpacttravel.wetravel.com" data-version="v0.3" data-uid="62302" data-uuid="54806750" href="https://maximumimpacttravel.wetravel.com/checkout_embed?uuid=54806750" style={{ backgroundColor:'#33ae3f', color:'#ffffff', border: '0px', borderRadius: '5px', fontFamily: "'Poppins', sans-serif", fontWeight: 400, fontSize: '14px', padding: '13px 24px', textDecoration: 'none', textAlign: 'center', lineHeight: '14px', display: 'inline-block', cursor: 'pointer' }} > Book Now </button> ); }; export default WeTravelBookButton;
相关问题解答
1. 能否监听该脚本的按钮点击事件?
可以通过两种方式实现:
- 直接监听按钮点击:给按钮添加
onClick回调,既能触发自定义逻辑,也不会干扰平台脚本的原有功能,示例:<button // 其他属性不变 onClick={() => { console.log('按钮被点击,可在此添加自定义逻辑'); }} > Book Now </button> - 监听脚本触发的自定义事件:部分第三方脚本会在执行关键操作时触发自定义DOM事件,可尝试全局监听:
useEffect(() => { const handleCheckoutOpen = (e) => { console.log('弹窗iframe已打开', e.detail); }; // 事件名称需参考WeTravel官方文档,若未提供可通过浏览器开发者工具排查 document.addEventListener('wetravel-checkout-open', handleCheckoutOpen); return () => { document.removeEventListener('wetravel-checkout-open', handleCheckoutOpen); }; }, []);
2. React组件中能否实现该弹窗iframe效果?
完全可以,有两种实现路径:
- 复用平台脚本:上面修复后的组件已能让平台脚本正常工作,自动生成弹窗iframe,无需额外开发。
- 自行实现弹窗iframe:若想完全控制弹窗逻辑,可自己创建iframe组件,通过状态控制显示隐藏:
这种方式需自行处理弹窗样式、关闭逻辑,注意确认平台是否允许直接嵌入该iframe(避免跨域限制)。import { useState } from 'react'; const CustomWeTravelCheckout = () => { const [showCheckout, setShowCheckout] = useState(false); return ( <> <button onClick={() => setShowCheckout(true)} style={{/* 按钮样式同之前 */}} > Book Now </button> {showCheckout && ( <div style={{ position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0,0,0,0.5)', display: 'flex', justifyContent: 'center', alignItems: 'center', zIndex: 9999 }}> <iframe src="https://maximumimpacttravel.wetravel.com/checkout_embed?uuid=54806750" style={{ width: '80%', height: '80%', borderRadius: '8px', border: 'none' }} /> <button onClick={() => setShowCheckout(false)} style={{ position: 'absolute', top: '20px', right: '20px', fontSize: '24px', background: 'none', border: 'none', color: 'white', cursor: 'pointer' }} > × </button> </div> )} </> ); };
内容的提问来源于stack exchange,提问作者kingNodejs
相关产品推荐
相关产品推荐

