如何覆写CMS默认行为 阻止按钮点击自动执行testFunction
问题说明
当前所用CMS存在默认行为:按钮点击时会自动触发testFunction执行。需求为覆写该默认逻辑,点击目标按钮时跳过testFunction调用,原有实现代码未达到预期。
原有代码存在两个基础问题:
- 选择器写法错误:
:not(selected)不是合法的筛选写法,筛选类名需要加类前缀为:not(.selected),筛选属性需要写为:not([selected]) - 事件回调内仅声明了同名函数,既没有覆盖全局的
testFunction,也没有拦截CMS的默认事件触发逻辑,无法生效;另外全局函数定义处多写了一组括号,存在语法错误。
原有问题代码如下:
$(".classTest:not(selected)").find("button").on("click", function (){ function testFunction(element,isSelected) }); // 此处多了一组括号,存在语法错误 function testFunction(element, isSelected)(){ //code }
可行解决思路
根据CMS的事件绑定逻辑,可选择以下任意一种方案实现:
方案1:高优先级拦截点击事件(推荐,适配绝大多数场景)
DOM事件流遵循「先捕获、后冒泡」的规则,CMS通常会把默认事件绑定在冒泡阶段,我们可以在捕获阶段绑定自定义事件,拦截事件传播,直接跳过后续所有默认逻辑:
// 原生JS写法,第三个参数true代表在捕获阶段绑定,优先级高于所有冒泡阶段绑定的事件 document.querySelectorAll(".classTest:not(.selected) button").forEach(btn => { btn.addEventListener('click', function(e) { // 阻断事件继续传播,阻止后续所有同事件的回调执行(包括CMS触发testFunction的逻辑) e.stopImmediatePropagation(); // 此处写你需要的自定义点击逻辑即可 }, true); });
如果是jQuery环境,且需要兼容更老的浏览器,可以通过调整事件绑定顺序实现:
// 确保这段代码在CMS的事件绑定代码执行完成后再运行 $(".classTest:not(.selected)").find("button").each(function() { const $btn = $(this); // 先绑定自定义事件 $btn.on("click", function(e) { e.stopImmediatePropagation(); // 此处写自定义点击逻辑 }); // 取出当前按钮已绑定的所有click事件,把刚绑定的自定义事件挪到执行队列的第一位 const eventList = $._data(this, "events").click; eventList.unshift(eventList.pop()); });
方案2:覆写全局testFunction加判断跳过
如果CMS是直接调用全局作用域下的testFunction,可以直接重写该函数,匹配到目标按钮时直接返回不执行原有逻辑:
// 先缓存原函数,非目标场景下可以正常调用原有逻辑 const _originTestFn = window.testFunction; window.testFunction = function(element, isSelected) { // 判断当前触发元素是不是要跳过逻辑的目标按钮 const isTargetBtn = $(element).is(".classTest:not(.selected) button"); if (isTargetBtn) return; // 非目标元素正常执行原逻辑 return _originTestFn.apply(this, arguments); }
方案3:清空原有绑定事件重写(谨慎使用)
如果确认按钮上除了CMS的默认testFunction触发逻辑外没有其他需要保留的事件,可以直接清空原有绑定再重写逻辑:
$(".classTest:not(.selected)").find("button").each(function() { // 清除内联onclick事件 this.onclick = null; // 清除所有jQuery绑定的click事件 $(this).off("click"); // 绑定自定义点击逻辑 $(this).on("click", function() { // 自定义逻辑 }); });
注意:该方案会清除按钮上所有已绑定的点击事件,若按钮存在其他需要保留的交互逻辑请勿使用。
内容的提问来源于stack exchange,提问作者Saduni Jayalath
相关产品推荐
相关产品推荐

