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

基于JS对象批量生成CMS自定义按钮及绑定点击函数的问题求助

问题描述

正在通过Tampermonkey为CMS添加带点击函数的自定义UI按钮,现有代码可正常运行,但正优化为基于对象键值对渲染按钮HTML(此部分已实现)。当前需求是将每个按钮的独立点击函数合并为单个函数,根据遍历的对象键注入对应值,但在注入函数时遇到阻碍。


新格式(基于对象)代码

let campaignButtonsObj = [
{
name: 'tenZeroZero',
id: 'ten-zero-zero',
cta: '1000',
width:'45',
onclick: 'tenZeroZeroClick',
function: 'tenZeroZeroButtonClick',
searchQuery: '#10 #00 - 1000',
addFunction: 'addTenZeroZero',
clickValue: 'NEW1000'
},
{
name: 'twentyOnly',
id: 'twenty-only',
cta: '20', width: '35',
onclick: 'twentyClick',
function: 'twentyButtonClick',
searchQuery: '#20 - 20',
addFunction:'addTwentyOnly',
clickValue: 'NEW20'
}
];

const generatedHtml = Object.keys(campaignButtonsObj).reduce((accum, currKey) => accum + `<span class="sc-GQHCi fjxikX" style="display: block;"><button onclick="${campaignButtonsObj[currKey].onclick}()"class="sc-cUEOzv hEBGGF eEeywh" id="${campaignButtonsObj[currKey].id}" style="margin-right: 0.571429rem;background-color: rgb(36, 137, 169);color:#fff;border-radius:300px;border:none"><div style="height: 20px;width: ${campaignButtonsObj[currKey].width}px;display: flex;align-items: center;justify-content: center;">${campaignButtonsObj[currKey].cta}</div></button></span>`, '');

// 此处报错,需要帮助
const buttonClick = Object.keys(campaignButtonsObj).reduce((accum, currKey) => accum + `function ${campaignButtonsObj[currKey].onclick}(){document.querySelector('[id="${campaignButtonsObj[currKey].id}"]').innerHTML = '${campaignButtonsObj[currKey].clickValue}';`, '');

const buttonAdd = Object.keys(campaignButtonsObj).reduce((accum, currKey) => accum + `function ${campaignButtonsObj[currKey].addFunction}(){document.querySelector('[id="new-button-container"]').insertAdjacentHTML('beforeend', ${campaignButtonsObj[currKey].name});document.getElementById("${campaignButtonsObj[currKey].id}").onclick = function() {${campaignButtonsObj[currKey].onclick}();};}`, '');

let newButtonContainer = '<div id="new-button-container" style="display:flex;align-items:center"></div>';
document.querySelector('[id="myDiv"]').insertAdjacentHTML('afterend', newButtonContainer);
document.querySelector('[id="new-button-container"]').insertAdjacentHTML('beforeend', generatedHtml);

初始独立元素与函数写法

let tenZeroZero = '<span class="sc-GQHCi fjxikX" style="display: block;"><button id="ten-zero-zero" class="sc-cUEOzv hEBGGF eEeywh" style="margin-right: 0.571429rem;background-color: rgb(36, 137, 169);color:#fff;border-radius:300px;border:none"><div style="height: 20px;width: 35px;display: flex;align-items: center;justify-content: center;">1000</div></button></span>';

let twentyOnly = '<span class="sc-GQHCi fjxikX" style="display: block;"><button id="twenty-only" class="sc-cUEOzv hEBGGF eEeywh" style="margin-right: 0.571429rem;background-color: rgb(36, 137, 169);color:#fff;border-radius:300px;border:none"><div style="height: 20px;width: 35px;display: flex;align-items: center;justify-content: center;white-space:pre">20</div></button></span>';


// 希望将遍历对象的值注入到此类函数中
function tenZeroZeroClick() {
  var input = document.querySelector('[id="campaign-search-input"]');
  var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
  nativeInputValueSetter.call(input, '#10 #00 - 1000');
  var ev2 = new Event('input', {
    bubbles: true
  });
  input.dispatchEvent(ev2);
}

function twentyClick() {
  var input = document.querySelector('[id="campaign-search-input"]');
  var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
  nativeInputValueSetter.call(input, '#20 - 20');
  var ev2 = new Event('input', {
    bubbles: true
  });
  input.dispatchEvent(ev2);
}

function addTenZeroZero() {
  document.querySelector('[id="new-button-container"]').insertAdjacentHTML('beforeend', tenTwenty);
  document.getElementById("ten-zero-zero").onclick = function() {
    tenZeroZeroClick();
  };
}

function addTwentyOnly() {
  document.querySelector('[id="new-button-container"]').insertAdjacentHTML('beforeend', twentyOnly);
  document.getElementById("twenty-only").onclick = function() {
    twentyClick();
  };
}

解决方案

核心思路

放弃通过字符串拼接生成函数的方式,改用通用处理函数结合事件绑定的方案,直接利用对象中的配置参数完成逻辑,避免动态生成函数带来的语法错误和维护问题。

优化后代码

let campaignButtonsObj = [
  {
    name: 'tenZeroZero',
    id: 'ten-zero-zero',
    cta: '1000',
    width:'45',
    searchQuery: '#10 #00 - 1000',
    clickValue: 'NEW1000'
  },
  {
    name: 'twentyOnly',
    id: 'twenty-only',
    cta: '20', 
    width: '35',
    searchQuery: '#20 - 20',
    clickValue: 'NEW20'
  }
];

// 通用点击处理函数
function handleButtonClick(config) {
  // 更新按钮显示文本
  document.getElementById(config.id).innerHTML = `<div style="height: 20px;width: ${config.width}px;display: flex;align-items: center;justify-content: center;">${config.clickValue}</div>`;
  
  // 执行搜索输入逻辑
  const input = document.querySelector('[id="campaign-search-input"]');
  const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
  nativeInputValueSetter.call(input, config.searchQuery);
  const ev2 = new Event('input', { bubbles: true });
  input.dispatchEvent(ev2);
}

// 通用添加按钮函数
function addButton(config) {
  const buttonHtml = `<span class="sc-GQHCi fjxikX" style="display: block;"><button class="sc-cUEOzv hEBGGF eEeywh" id="${config.id}" style="margin-right: 0.571429rem;background-color: rgb(36, 137, 169);color:#fff;border-radius:300px;border:none"><div style="height: 20px;width: ${config.width}px;display: flex;align-items: center;justify-content: center;">${config.cta}</div></button></span>`;
  document.querySelector('[id="new-button-container"]').insertAdjacentHTML('beforeend', buttonHtml);
  
  // 绑定点击事件,传入当前按钮配置
  document.getElementById(config.id).addEventListener('click', () => handleButtonClick(config));
}

// 初始化容器并渲染所有按钮
const newButtonContainer = '<div id="new-button-container" style="display:flex;align-items:center"></div>';
document.querySelector('[id="myDiv"]').insertAdjacentHTML('afterend', newButtonContainer);

// 遍历对象,批量添加按钮
campaignButtonsObj.forEach(config => addButton(config));

优化点说明

  1. 移除冗余字段:删除了对象中onclick、function、addFunction等冗余字段,直接通过配置对象传递参数。
  2. 通用函数复用:创建handleButtonClick和addButton两个通用函数,分别处理按钮点击逻辑和按钮添加逻辑,无需为每个按钮单独定义函数。
  3. 事件绑定更可靠:使用addEventListener绑定事件,避免内联onclick属性的安全风险和维护问题,同时通过箭头函数直接传入当前按钮的配置对象。
  4. 避免字符串拼接函数:彻底放弃动态生成函数字符串的方案,消除语法错误隐患,代码可读性和可维护性大幅提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:05:03