使用 setAttribute() 添加“onclick”函数

Sta*_*wed 2 javascript jquery

为什么以下不起作用?显然该功能尚未添加!

function activatetypeinput(event, devtype){
  //The function is called but it doesn't set the attribute
  var dev_input = document.getElementById("device_input");
  dev_input.setAttribute("onclick","add_device_input(event, this);");
}
Run Code Online (Sandbox Code Playgroud)

在我的 HTML 中,我有这样的内容(除其他外):

<select class="text-input" id="device_input">
   <option>--</option>
</select>
Run Code Online (Sandbox Code Playgroud)

zer*_*0ne 7


\n问题\n--\n
\n
\n

“为什么以下不起作用?显然该功能没有添加!”

\n
\n
dev_input.setAttribute("onclick","add_device_input(event, this);");\n
Run Code Online (Sandbox Code Playgroud)\n
\n解释\n---\n
\n虽然我还没有找到对这种特定情况的参考,但我会指出我观察到的情况:\n
    \n
  • 查看 Devtools F12,您将看到已onclick添加该属性和值。尽管它存在并且语法正确,但它不起作用。请参阅演示部分 - 来源:#btn3

    \n
  • \n
  • 如果通过 JavaScript 添加相同的属性和值作为属性,则它可以作为属性工作。属性不会显示在标记中,而属性则不会。出于所有意图和目的,onclick属性和onclick属性是相同的

    \n
  • \n
  • 此行为是 jQuery 方法attr()prop(). 作为一个例子,我经常看到这样的情况:

    \n

    $(":checkbox").prop("checked", true);

    \n

    $(":checkbox").attr("checked", true);

    \n
  • \n
\n
\n事件处理\n----\n
\n事件被注册到 DOM 中的元素或浏览器相关的非 DOM 对象(如 Window)。事件注册有 3 种类型:\n
    \n
  1. 事件属性:像污垢一样古老,并且普遍受到 Web 开发社区的劝阻和皱眉。这是 OP 代码尝试使用方法以编程方式创建的事件处理程序类型setAttribute()。看来on 事件超出了set/get/removeAttribute()方法的范围,而且很可能也超出了 jQuery 方法的范围attr()(未经测试且不那么好奇)。请参阅部分:演示 - 来源:#btn0

    \n
    <button onclick="funcName(event)">Discouraged</button>\n
    Run Code Online (Sandbox Code Playgroud)\n
  2. \n
\n
\n 2. \xe2\xad\x90 **On-event 属性:** 这是一个旧的事件处理,也被轻视,但因为与它的前身 *Event Listener* 相比,它是有限的。**就 DOM 元素而言,onclick 属性和 onclick 属性是一回事。使用此函数而不是 `setAttribute()`。** ***请参阅演示部分 - 来源:`#btn1`***\n

\xe2\xad\x90document.getElementById(\'id\').onclick = funcName;

\n
\n 3. **事件监听器:** 这种类型的事件处理采用方法`add/removeEventListener("event", funcName)`,是最标准、当前和首选的方式。***请参阅演示部分 - 来源:`#btn2`***\n

document.getElementById(\'id\').addEventListener("event", funcName);

\n
\n有关前两种类型的事件处理为何受到谩骂的详细信息,请阅读 **[DOM 事件处理程序][1]** 以了解技术原因,并阅读 **[Reddit 文章][2]** 以了解开发和设计导向的原因。我个人对此主题持矛盾态度,因为事件处理程序并未被弃用,而且诸如表示分离、行为、结构、语义等概念也不像以前那么重要。\n
\n

##解决方案

\n
\n

除了使用活动财产之外我们可以使用属性解析整个元素的 htmlStringonclick。这可以使用以下方法完成:

\n
    \n
  • innerHTML 覆盖内容
  • \n
\n

或者

\n\n

### 请参阅部分:演示- 来源:#btn4

\n
var htmlString = `<button onclick="funcName(event, this)">4</button>`\n\ndocument.querySelector(\'${selectorOfTarget}\').insertAdjacentHTML("${position}", htmlString);\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • “目标选择器”:一个 CSS 字符串,表示我们希望在其中或周围插入 htmlString 的 DOM 元素。
  • \n
  • "div"......: < div id="ID" class="CLASS"></ div >
  • \n
  • "#ID“......: <div id="ID" class="CLASS"></div>
  • \n
  • ".CLASS"....: <div id="ID" class="CLASS" ></div>
  • \n
  • #ID + ul....: <div id="ID" class="CLASS"></div>\n< ul ></ ul >
  • \n
  • #ID + ul li.: <div id="ID" class="CLASS"></div>\n< ul >< li ></ li ></ ul >
  • \n
\n
\n * ***"position":*** 一个字符串,用于确定 htmlSting 相对于目标元素的插入位置:\n
    <!--"beforebegin"-->\n    <ul>\n    <!--"afterbegin"-->\n      <li>ITEM</li>\n      <li>ITEM</li>\n      <li>ITEM</li>\n    <!--"beforeend"-->\n    </ul>\n    <!--"afterend"-->\n
Run Code Online (Sandbox Code Playgroud)\n
\n * ***htmlString:*** 字面表示 HTML 的字符串。不使用字符串文字,而是使用 **[模板文字][4]**:\n

字符串字面量

\n
    \'<div id="\'+ID+\'" class="\'+CLASS+\'">+CONTENT+</div>\'\n
Run Code Online (Sandbox Code Playgroud)\n

模板文字

\n
    `<div id="${ID}" class="${CLASS}">${CONTENT}</div>`\n
Run Code Online (Sandbox Code Playgroud)\n
\n(请参阅部分:**事件处理** - 列表项:2。**事件属性**和部分:**演示** - 来源:`#btn1`。)\n
\n##演示\n
\n

\r\n
\r\n
dev_input.setAttribute("onclick","add_device_input(event, this);");\n
Run Code Online (Sandbox Code Playgroud)\r\n
<button onclick="funcName(event)">Discouraged</button>\n
Run Code Online (Sandbox Code Playgroud)\r\n
var htmlString = `<button onclick="funcName(event, this)">4</button>`\n\ndocument.querySelector(\'${selectorOfTarget}\').insertAdjacentHTML("${position}", htmlString);\n
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n