You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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组件,通过状态控制显示隐藏:
    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>
          )}
        </>
      );
    };
    
    这种方式需自行处理弹窗样式、关闭逻辑,注意确认平台是否允许直接嵌入该iframe(避免跨域限制)。

内容的提问来源于stack exchange,提问作者kingNodejs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 09:22:01