我怎样才能对我的示例代码应用适当的事件处理甚至事件委托?
How could I apply a proper event handling or even event delegation to my example code?
我正在尝试使用相同的函数来更改三个不同 div 的颜色,但它不起作用。请看下面的代码:
const hours=document.getElementById('hours');
const minutes=document.getElementById('minutes');
const seconds=document.getElementById('seconds');
hours.addEventListener('click',changeColor);
minutes.addEventListener('click', changeColor);
seconds.addEventListener('click', changeColor);
function changeColor(obj){
if(obj.style.backgroundColor==='seashell'){
obj.style.backgroundColor='red';
} else{
obj.style.backgroundColor='seashell';
}
}
事件侦听器的参数是 Event
对象,而不是事件的目标。使用 event.target
获取被点击的元素。
function changeColor(event) {
let obj = event.target;
if (obj.style.backgroundColor === 'seashell') {
obj.style.backgroundColor = 'red';
} else {
obj.style.backgroundColor = 'seashell';
}
}
handler function (callback) of a registered event listener gets passed an event
object. If one wants to access the element where the listener has been registered at then one should use the event
's currentTarget
property and not target
因为后者不能与前者相同
OP 的事件处理 示例...
function changeColor(evt) {
const obj = evt.currentTarget;
const objStyle = obj.style;
const bgColor = (objStyle.backgroundColor === 'seashell')
? 'red'
: 'seashell';
objStyle.backgroundColor = bgColor;
}
document
.querySelectorAll('[type="number"]')
.forEach(elmNode =>
elmNode.addEventListener('click' ,changeColor)
);
<input id="hours" type="number" min="0" max="23" />
<input id="minutes" type="number" min="0" max="59" />
<input id="seconds" type="number" min="0" max="59" />
...变成了一个事件委托的例子...
function handleColorChange(evt) {
const target = evt.target;
if (target) {
if (
target.classList.contains('label') ||
(target.tagName.toUpperCase() === 'LABEL')
) {
// evt.stopImmediatePropagation();
// evt.stopPropagation();
// prevent input field event delegation.
evt.preventDefault();
// prevents that a click on the label appears
// to always set a red background color due to
// handling this event twice once for the label
// and a second time for the number input field.
}
const inputRoot = evt.target?.closest('label');
if (inputRoot) {
const inputNode =
inputRoot.querySelector('[type="number"]');
const inputStyle = inputNode?.style;
if (inputStyle) {
const bgColor = (inputStyle.backgroundColor === 'seashell')
? 'red'
: 'seashell';
inputStyle.backgroundColor = bgColor;
}
}
}
console.log('evt.target ... ', target);
}
document
.querySelector('form')
.addEventListener('click' , handleColorChange/*, true*/);
body { margin: -2px 0 0 0; }
label { padding-left: 8px; padding-right: 8px,}
.as-console-wrapper { max-height: 140px!important; }
<form>
<fieldset>
<legend>Time Settings</legend>
<label>
<span class="label">
hours
</span>
<input name="hours" type="number" min="0" max="23" />
</label>
<label>
<span class="label">
minutes
</span>
<input name="minutes" type="number" min="0" max="59" />
</label>
<label>
<span class="label">
seconds
</span>
<input name="seconds" type="number" min="0" max="59" />
</label>
</fieldset>
</form>
我正在尝试使用相同的函数来更改三个不同 div 的颜色,但它不起作用。请看下面的代码:
const hours=document.getElementById('hours');
const minutes=document.getElementById('minutes');
const seconds=document.getElementById('seconds');
hours.addEventListener('click',changeColor);
minutes.addEventListener('click', changeColor);
seconds.addEventListener('click', changeColor);
function changeColor(obj){
if(obj.style.backgroundColor==='seashell'){
obj.style.backgroundColor='red';
} else{
obj.style.backgroundColor='seashell';
}
}
事件侦听器的参数是 Event
对象,而不是事件的目标。使用 event.target
获取被点击的元素。
function changeColor(event) {
let obj = event.target;
if (obj.style.backgroundColor === 'seashell') {
obj.style.backgroundColor = 'red';
} else {
obj.style.backgroundColor = 'seashell';
}
}
handler function (callback) of a registered event listener gets passed an event
object. If one wants to access the element where the listener has been registered at then one should use the event
's currentTarget
property and not target
因为后者不能与前者相同
OP 的事件处理 示例...
function changeColor(evt) {
const obj = evt.currentTarget;
const objStyle = obj.style;
const bgColor = (objStyle.backgroundColor === 'seashell')
? 'red'
: 'seashell';
objStyle.backgroundColor = bgColor;
}
document
.querySelectorAll('[type="number"]')
.forEach(elmNode =>
elmNode.addEventListener('click' ,changeColor)
);
<input id="hours" type="number" min="0" max="23" />
<input id="minutes" type="number" min="0" max="59" />
<input id="seconds" type="number" min="0" max="59" />
...变成了一个事件委托的例子...
function handleColorChange(evt) {
const target = evt.target;
if (target) {
if (
target.classList.contains('label') ||
(target.tagName.toUpperCase() === 'LABEL')
) {
// evt.stopImmediatePropagation();
// evt.stopPropagation();
// prevent input field event delegation.
evt.preventDefault();
// prevents that a click on the label appears
// to always set a red background color due to
// handling this event twice once for the label
// and a second time for the number input field.
}
const inputRoot = evt.target?.closest('label');
if (inputRoot) {
const inputNode =
inputRoot.querySelector('[type="number"]');
const inputStyle = inputNode?.style;
if (inputStyle) {
const bgColor = (inputStyle.backgroundColor === 'seashell')
? 'red'
: 'seashell';
inputStyle.backgroundColor = bgColor;
}
}
}
console.log('evt.target ... ', target);
}
document
.querySelector('form')
.addEventListener('click' , handleColorChange/*, true*/);
body { margin: -2px 0 0 0; }
label { padding-left: 8px; padding-right: 8px,}
.as-console-wrapper { max-height: 140px!important; }
<form>
<fieldset>
<legend>Time Settings</legend>
<label>
<span class="label">
hours
</span>
<input name="hours" type="number" min="0" max="23" />
</label>
<label>
<span class="label">
minutes
</span>
<input name="minutes" type="number" min="0" max="59" />
</label>
<label>
<span class="label">
seconds
</span>
<input name="seconds" type="number" min="0" max="59" />
</label>
</fieldset>
</form>