Problem
--
“为什么以下不起作用?显然该功能没有添加!”
dev_input.setAttribute("onclick","add_device_input(event, this);");
Explanation
---
Although I haven't found a reference to this specific circumstance, I'll point out what I observed:
-
Look in Devtools F12 and you'll see that the onclick
attribute is added and the value as well. Although it is there and syntactically correct, it doesn't function. See section Demo - Source: #btn3
-
If the same attribute and value is added via JavaScript as a property it works, as a property. An attribute will not show up in markup, whilst a property does not. For all intents and purposes, the onclick
property and onclick
attribute is one and the same????.
-
此行为是 jQuery 方法的标准行为attr()
and prop()
。作为一个例子,我经常看到这样的情况:
???? $(":checkbox").prop("checked", true);
???? $(":checkbox").attr("checked", true);
Event Handling
----
Events are registered to either an element within the DOM or browser related Non-DOM Object like Window. There are 3 types of event registration:
-
事件属性:古老得像泥土一样,普遍受到网络开发社区的劝阻和皱眉。这是 OP 代码尝试以编程方式创建的事件处理程序类型setAttribute()
方法。看来,一个on event是遥不可及的set/get/removeAttribute()
方法和最可能的 jQuery 方法attr()
以及(未经测试,也不那么好奇)。请参阅部分:演示 - 来源:#btn0
<button onclick="funcName(event)">Discouraged</button>
2. ⭐ **On-event Property:** This is event handling is old and looked down upon as well but because it's limited compared to its predecessor *Event Listener*. **An onclick property and onclick attribute are one and the same as far as DOM elements are concerned. Use this and not `setAttribute()`.** ***See section Demo - Source: `#btn1`***
⭐document.getElementById('id').onclick = funcName;
3. **Event Listener:** This type of event handling employs the methods `add/removeEventListener("event", funcName)` and is the most standard, current, and preferred way. ***See section Demo - Source: `#btn2`***
document.getElementById('id').addEventListener("event", funcName);
For details why the first 2 types of event handling are reviled, read **[DOM on-event handlers][1]** for the technical reasons and this **[Reddit article][2]** for development and design oriented reasons. I'm personally ambivalent about the subject because on-event handlers aren't deprecated and concepts such as separation of presentation, behavior, structure, semantics, etc. are not as important as they were before.
##解决方案
Other than using an On-event Property???? we can parse a htmlString of the entire element with the onclick
attribute. This can be done using:
OR
- ????**insertAdjacentHTML() https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML** 不覆盖内容;灵活的;快速地
###???? 请参阅部分:Demo- 来源:#btn4
????
var htmlString = `<button onclick="funcName(event, this)">4</button>`
document.querySelector('${selectorOfTarget}').insertAdjacentHTML("${position}", htmlString);
-
“目标选择器”:一个 CSS 字符串,表示我们希望在其中或周围插入 htmlString 的 DOM 元素。
-
"div"
……:divid =“ID”class =“CLASS”>div>
-
"#ID
“......:id="ID"类=“CLASS”>
-
".CLASS"
....: 类=“类”>
-
#ID + ul
....: id="ID"类=“CLASS”>
ul>ul>
-
#ID + ul li
.: id="ID"类=“CLASS”>
ul><li>li>ul>
* ***"position":*** A string that determines where the htmlSting will be inseted in relation to the target element:
<!--"beforebegin"-->
<ul>
<!--"afterbegin"-->
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<!--"beforeend"-->
</ul>
<!--"afterend"-->
* ***htmlString:*** A String that literally represents HTML. Instead of using String Literals, use **[Template Literals][4]**:
字符串字面量
'<div id="'+ID+'" class="'+CLASS+'">+CONTENT+</div>'
模板文字
`<div id="${ID}" class="${CLASS}">${CONTENT}</div>`
????(See section: **Event Handling** - list item: 2. **On-event Property** and section: **Demo** - source: `#btn1`.)
##Demo
var htmlString = `<button id='btn4' onclick='showHide(event)'>4</button>
<div class='content hide'>
<h4>Dynamically Registered On Event Attribute by Parsing htmlString</h4>
<pre><code>
document.querySelector('#btn3+div+hr').insertAdjacentHTML('afterend', htmlString);
</code></pre>
</div>
<hr>`;
function showHide(event) {
var tgt = event.target;
if (tgt.tagName === "BUTTON") {
var code = tgt.nextElementSibling;
code.classList.toggle('hide');
}
return false;
}
//#btn1
//On-Event Property
document.getElementById('btn1').onclick = showHide;
//#btn2
//EventListener
document.getElementById('btn2').addEventListener('click', showHide);
//#btn3
//Dynamically registered On event Attribute by setAttribute() method.
document.getElementById('btn3').setAttribute('onclick', "showHide(event, this)");
//#btn4
//Dynamically Registered On Event Attribute by Parsing htmlString
document.querySelector('#btn3+div+hr').insertAdjacentHTML('afterend', htmlString);
* {
margin: 0;
padding: 0
}
button {
padding: 2px 5px;
}
button+div {
opacity: 1;
transition: opacity 1s ease;
}
.content {
margin: 0 0 20px 0
}
button+div.hide {
opacity: 0;
transition: 1s ease;
}
code {
background: #000;
color: lime;
}
<!--#btn0-->
<button id='btn0' onclick="showHide(event, this)">0</button>
<div class='content hide'>
<h4>On-Event Attribute</h4>
<pre><code>
<button id='btn0' onclick="showHide(event, this)">On-Event Attribute</button>
</code></pre>
</div>
<hr>
<!--#btn1-->
<button id="btn1">1</button>
<div class='content hide'>
<h4>On-Event Property</h4>
<pre><code>
document.getElementById('btn1').onclick = showHide;
</code></pre>
</div>
<hr>
<!--#btn2-->
<button id='btn2'>2</button>
<div class='content hide'>
<h4>EventListener</h4>
<pre><code>
document.getElementById('btn2').addEventListener('click', showHide);
</code></pre>
</div>
<hr>
<!--#btn3-->
<button id='btn3'><del>3</del></button>
<div class='content'>
<h4>Dynamically Registered On Event Attribute by <code>setAttribute()</code> method <b>FAILED</b></h4>
<pre><code>
<del>document.getElementById('btn3').setAttribute('onclick', 'showHide(event)');</del>
</code></pre>
</div>
<hr>
<!--#btn4 is dynamically created and will be inserted here-->
<!--Selector: '#btn3+div+hr' || Position: 'afterend'-->