将 Object 传递给 onclick 方法 html 的有效方法

Efficient way to pass an Object to onclick method html

提问人:TheBestPlayer 提问时间:7/12/2023 更新时间:7/12/2023 访问量:57

问:

我最近发现了一个问题,即不允许我将对象参数传递给方法。onclick()

我做了一些研究,这似乎是一个受欢迎的问题。我已经读过这个: javascript:将一个对象作为参数传递给字符串中的 onclick 函数,我试图在传递给 an 之前将对象字符串化,但这似乎不起作用。onclick()

enter image description here

我的代码:

        var object_info= {
            TypeID:11000,
            TypeValue:5,
            ValueID:12103,
            ValueValue:15,
            CorrectionID:11020,
            CorrectionValue:0,
            LabelStr:Analog_input_name[11000],
            TypeStr:InputATypeStr[5],
            DivId:"Test123",
        };

        Append_html_block(object_info);

功能:Append_html_block

function Append_html_block(object) {
    var generated_html = document.getElementById("custom_DIV");
    var stringifiedObj = JSON.stringify(object);

    generated_html .innerHTML += `
    <table class="sensor-values-table">
        <tr>
        <td class="top-item" style="width:90%;">${object.LabelStr}</td>
            <td>
                <button style="border:none;background-color:inherit;" onclick="Expand_selection(${stringifiedObj})">
       
                </button>
            </td>
        </tr>

    </table>
<br>
`;
}

逻辑很简单: 我创建了一个对象,我将其传递给函数。在这个函数中,我有一个按钮。如果单击此按钮,我想执行特定操作,为了执行这些操作,我必须知道有关对象的所有信息,因此我需要传递对象变量。Append_html_block

我没有设法找到一个清晰而简单的解决方案来将 ojbect 变量传递给 .也许有人可以建议一种简洁明了的方法?提前致谢!onclick()

JavaScript HTML 对象

评论

0赞 Simone Rossaini 7/12/2023
为什么不这样做,而是简单地使用具有某些唯一 ID 的对象信息数组和数据属性?
0赞 TheBestPlayer 7/12/2023
你能提供一个简单的例子,因为我不完全确定理解你的意思。

答:

-1赞 Izebeafe 7/12/2023 #1

从您链接到的类似问题的答案中,尝试在返回值上使用函数,然后在需要对象的地方使用该函数,执行相反的过程:对函数的返回值使用该函数:encodeURIComponentJSON.stringifyJSON.parsedecodeURIComponent

function Append_html_block(object) { // try appendHtmlBlock instead (Camel Case
    var generated_html = document.getElementById("custom_DIV");
    var encodedObj = encodeURIComponent(JSON.stringify(object));

    generated_html .innerHTML += `
    <table class="sensor-values-table">
        <tr>
        <td class="top-item" style="width:90%;">${object.LabelStr}</td>
            <td>
                <button style="border:none;background-color:inherit;" onclick="Expand_selection(${encodedObj})">
       
                </button>
            </td>
        </tr>

    </table>
<br>
`;
}

然后在您的函数中(可能是):Expand_selectionexpandedSelection

function Expand_selection(encodedObject) {
  var object = JSON.parse(decodeURIComponent(encodedObject))
  console.log(object) // should work now
  // Do other stuff.
}

希望这能奏效,如果它确实:)👍请告诉我

答案参考:@João Pimentel Ferreira 的这个答案

评论

0赞 TheBestPlayer 7/12/2023
我已经测试过了,它似乎:)javascript 在将对象传递给 onclick 函数时如此奇怪有什么特别的原因吗?
0赞 Izebeafe 7/12/2023
不知道,但我的大部分项目都是用 react js 完成的,而且我不经常遇到这类问题。也许因为所有东西基本上都是 JavaScript,所以所有这些字符串化 - 解析 gist 对于传递这样的🤷 ♂️参数并不是真正必要的
1赞 KooiInc 7/12/2023 #2

使用内联事件处理程序通常不是一个好主意

您可以尝试使用事件委派来处理该按钮。

这是一个最小的可重现示例

document.addEventListener(`click`, handle);
const object_info = {
  TypeID: 11000,
  TypeValue: 5,
  ValueID: 12103,
  ValueValue: 15,
  CorrectionID: 11020,
  CorrectionValue: 0,
  LabelStr: `EXAMPLE-Analog_input_name[11000]`,
  TypeStr: `EXAMPLE-InputATypeStr[5]`,
  DivId: 'Test123',
};

Append_html_block(object_info);

function handle(evt) {
  if (evt.target.dataset.expand) {
    evt.target.closest(`td`).querySelector(`pre`).classList.toggle(`hidden`);
  }
}

function Append_html_block(object) {
  var stringifiedObj = JSON.stringify(object, null, 2);
  document.querySelector(`#generated`).insertAdjacentHTML(`beforeend`,
    `<table class="sensor-values-table">
      <tr>
        <td>${object.LabelStr}</td>
        <td>
          <button data-expand="1">Expand/Hide</button>
          <pre class="hidden">${stringifiedObj}</pre>
        </td>
      </tr>
   </table>`);
}
.hidden {
  display: none;
}

td {
  vertical-align: top;
}
<div id="generated"></div>

评论

0赞 Quentin 7/12/2023
<pre class="hidden">${stringifiedObj}</pre>— 这似乎更适合某个属性。JSON 不会以原始方式向用户显示,是吗?data-*
0赞 Simone Rossaini 7/12/2023 #3

正如我在评论中所说,您可以使用唯一 ID(我使用)来调用源对象,例如:TypeID

const objctInfo = [{
    TypeID: 11000,
    TypeValue: 5,
    ValueID: 12103,
    ValueValue: 15,
    CorrectionID: 11020,
    CorrectionValue: 0,
    LabelStr: 1,
    TypeStr: 5,
    DivId: "Test123",
  },
  {
    TypeID: 11001,
    TypeValue: 5,
    ValueID: 12103,
    ValueValue: 15,
    CorrectionID: 11020,
    CorrectionValue: 0,
    LabelStr: 2,
    TypeStr: 5,
    DivId: "Test124",
  },
];
objctInfo.forEach(Append_html_block);

function Append_html_block(obj) { 
    var generated_html = document.getElementById("custom_DIV");

    generated_html .innerHTML += `
    <table class="sensor-values-table" border=1>
        <tr>
        <td class="top-item" style="width:90%;">${obj.LabelStr}</td>
            <td>
                <button style="border:none;background-color:inherit;" onclick="Expand_selection(${obj.TypeID})">
        click me
                </button>
            </td>
        </tr>

    </table>
<br>
`;
}

function Expand_selection(id){
  const obj = objctInfo.find(obj => obj.TypeID === parseInt(id));
  console.log(obj);
}
<div id="custom_DIV"></div>

评论

0赞 TheBestPlayer 7/12/2023
请您澄清一下我对这种方法的一些担忧:1.此方法仅在全局声明对象时才有效(需要确保expand_selection方法可以访问该对象)。2. 此外,如果我有多个对象,例如 objcetInfo1、objectInfo2、objectInfo3 等,会发生什么?
0赞 Simone Rossaini 7/12/2023
1. 是的(只使用一个变量) 2.只需将所有对象分组到一个数组中,就像我的例子一样let