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

如何重写JavaScript函数?第三方Guestplan插件函数重写失败求助

解决重写外部插件_gstpln.openWidget/closeWidget函数的问题

你的问题核心在于异步脚本加载的时机,以及插件可能对这些方法的后续赋值覆盖。我给你几个可行的解决思路:

1. 监听插件脚本加载完成后再重写(最可靠)

因为你初始化插件时用了async=1,脚本是异步加载的——这意味着你之前在$(document).ready或者初始化脚本末尾的赋值,大概率在插件脚本还没加载完成时就执行了,此时_gstpln上的closeWidget和openWidget还没被插件定义,等插件加载完成后,它会自己给_gstpln添加这些方法,直接覆盖了你之前的修改。

修改初始化脚本,在脚本的onload回调里执行重写逻辑:

(function(g,s,t,p,l,n){ 
  g["_gstpln"]={}; 
  (l=s.createElement(t)),(n=s.getElementsByTagName(t)[0]); 
  l.async=1;
  l.src=p;
  
  // 等插件脚本加载完成后再重写方法
  l.onload = function() {
    // 先保存原函数,避免丢失原有功能
    const originalClose = _gstpln.closeWidget;
    _gstpln.closeWidget = function() {
      // 这里添加你的自定义逻辑
      console.log('执行自定义关闭逻辑');
      // 调用原函数(如果需要保留原有功能的话)
      originalClose.apply(this, arguments);
    };

    // 同理处理openWidget
    const originalOpen = _gstpln.openWidget;
    _gstpln.openWidget = function() {
      console.log('执行自定义打开逻辑');
      originalOpen.apply(this, arguments);
    };
  };
  
  n.parentNode.insertBefore(l,n); 
})(window,document,"script","https://cdn.guestplan.com/widget.js"); 

// 初始化配置保持不变
_gstpln.accessKey = "cebd85865b61ba61961cc749c8ca02e43cad6535"; 
_gstpln.color = "#000000"; 
_gstpln.showFab = false;

2. 使用Proxy代理拦截方法调用

如果插件内部用闭包封装了方法,直接修改_gstpln的属性可能无效,这时可以用ES6的Proxy来拦截对这些方法的访问:

(function(g,s,t,p,l,n){ 
  g["_gstpln"]={}; 
  (l=s.createElement(t)),(n=s.getElementsByTagName(t)[0]); 
  l.async=1;
  l.src=p;
  
  l.onload = function() {
    window._gstpln = new Proxy(window._gstpln, {
      get(target, prop) {
        // 拦截closeWidget调用
        if (prop === 'closeWidget') {
          return function() {
            // 自定义逻辑
            console.log('自定义关闭动作');
            // 调用原方法
            return target[prop].apply(target, arguments);
          };
        }
        // 拦截openWidget调用
        if (prop === 'openWidget') {
          return function() {
            console.log('自定义打开动作');
            return target[prop].apply(target, arguments);
          };
        }
        // 其他属性直接返回原对象的值
        return target[prop];
      }
    });
  };
  
  n.parentNode.insertBefore(l,n); 
})(window,document,"script","https://cdn.guestplan.com/widget.js"); 

// 初始化配置不变
_gstpln.accessKey = "cebd85865b61ba61961cc749c8ca02e43cad6535"; 
_gstpln.color = "#000000"; 
_gstpln.showFab = false;

3. 轮询检测方法是否存在(兼容旧环境)

如果你需要兼容不支持Proxy的旧浏览器,可以用定时器轮询,直到_gstpln的目标方法存在再重写:

$(document).ready(function() {
  const checkInterval = setInterval(() => {
    // 确认目标方法已被插件定义
    if (window._gstpln && typeof window._gstpln.closeWidget === 'function') {
      // 重写closeWidget
      const originalClose = window._gstpln.closeWidget;
      window._gstpln.closeWidget = function() {
        console.log('自定义关闭逻辑');
        originalClose.call(this, ...arguments);
      };

      // 重写openWidget
      const originalOpen = window._gstpln.openWidget;
      window._gstpln.openWidget = function() {
        console.log('自定义打开逻辑');
        originalOpen.call(this, ...arguments);
      };

      // 停止轮询
      clearInterval(checkInterval);
    }
  }, 100); // 每隔100ms检查一次,可根据实际调整间隔
});

额外建议

先查看插件的官方文档,看是否提供了官方的事件回调(比如onWidgetOpen、onWidgetClose),如果有的话,优先使用官方API,这样更稳妥,也避免插件更新后你的重写逻辑失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 17:53:10