如何在WordPress插件中覆盖Hero API的JS函数并调整房源打开方式
我正在开发一款WordPress插件,调用Hero物业管理API展示房源列表。需要覆盖API中iframe点击事件触发的openListingFromSummary函数,实现单条房源在新页面打开。原API函数示例如下:
openListingFromSummary('listingId', 'listingDesc');
我尝试用以下代码覆盖,但原函数仍然执行,推测是自定义插件的JS加载早于API的JS文件:
var orig_openListingFromSummary = window.openListingFromSummary('TX055461L', '$1995/month 2 bedroom / 2.5 bathroom Single family'); window.openListingFromSummary = function(){ orig_openListingFromSummary(); alert('HI'); }
请问如何确保自定义JS在API JS之后加载?
首先纠正你代码里的一个错误:你现在是把window.openListingFromSummary()的执行结果存在变量里,而不是保存函数本身。正确的保存原函数方式应该是const orig_openListingFromSummary = window.openListingFromSummary;(不带括号),否则变量存的是函数执行后的返回值,不是函数引用,这也是原函数没被正确覆盖的原因之一。
下面是几种确保自定义JS在API之后加载并成功覆盖函数的方法:
1. 轮询监听API函数,延迟执行覆盖逻辑
不用硬等加载完成,而是定时检查API函数是否存在,存在后再执行覆盖:
function overrideListingFunction() { // 检查目标函数是否已存在 if (typeof window.openListingFromSummary === 'function') { // 保存原函数引用 const orig_openListingFromSummary = window.openListingFromSummary; // 重写函数,实现新页面打开逻辑 window.openListingFromSummary = function(listingId, listingDesc) { // 替换成你的房源详情页URL,把listingId作为参数传递 window.open(`/property-details?listingId=${listingId}`, '_blank'); // 如果需要保留原API的函数行为,取消下面的注释 // orig_openListingFromSummary(listingId, listingDesc); }; } else { // 每隔100ms检查一次,可根据实际情况调整间隔 setTimeout(overrideListingFunction, 100); } } // 启动监听 overrideListingFunction();
2. 在WordPress中通过脚本依赖控制加载顺序
如果Hero API的JS是通过WordPress的wp_enqueue_script函数注册加载的,你可以在注册自己的JS时,将API的脚本设为依赖,这样WordPress会自动确保你的JS在API之后加载:
// 假设Hero API的脚本注册句柄是'hero-property-api'(需根据实际情况修改) wp_enqueue_script( 'custom-hero-override', // 你的自定义脚本句柄 plugins_url('js/override-script.js', __FILE__), // 自定义脚本的路径 array('hero-property-api'), // 声明依赖API脚本,确保加载顺序 '1.0', // 脚本版本号 true // 设置为true,让脚本在页脚加载,进一步避免顺序问题 );
如果不知道API脚本的句柄,可以用浏览器开发者工具查看页面加载的JS文件,或者添加以下代码到主题的functions.php,打印所有注册的脚本句柄来查找:
add_action('wp_print_scripts', function() { global $wp_scripts; foreach($wp_scripts->registered as $script) { echo $script->handle . '<br>'; } });
3. 监听iframe的load事件(如果API内容在iframe内)
因为触发函数的逻辑在iframe里,你可以监听iframe的加载完成事件,等iframe加载完毕后再覆盖函数:
// 根据实际情况修改选择器,找到加载Hero API的iframe const heroIframe = document.querySelector('iframe[src*="hero"]'); if (heroIframe) { heroIframe.addEventListener('load', function() { // 此时iframe已加载完成,API函数应该已存在 const orig_openListingFromSummary = window.openListingFromSummary; window.openListingFromSummary = function(listingId, listingDesc) { window.open(`/property-details?listingId=${listingId}`, '_blank'); // orig_openListingFromSummary(listingId, listingDesc); }; }); }
内容的提问来源于stack exchange,提问作者Homaira S

