checkbox inside label fires twice
HTML
<p id="explanation">Click <strong>checkbox</strong> to fire onclick only once.<br />
Click <strong>label-text</strong> to fire onclick twice.</p>
<div>
<label id="untreated">
<input type="checkbox" />
<span>onclick untreated</span>
</label>
</div>
<div>
<label id="treated">
<input type="checkbox" />
<span>onclick treated</span>
</label>
Measure:
<select id="measure">
<option>stopPropagation</option>
<option>stopImmediatePropagation</option>
<option>preventDefault</option>
<option>return false</option>
<option>return true</option>
</select>
</div>
<div class="working">
<label id="onchange">
<input type="checkbox" />
<span>onchange</span>
</label>
</div>
<div class="working">
<label>
<input type="checkbox" id="inputclick" />
<span>onclick untreated, but bind on input rather than label</span>
</label>
</div>
<p>Event counter: <span id="counter">0</span></p>
CSS
label {
margin-right: 20px;
background-color: tomato;
}
.working label {
background-color: springgreen;
}
div {
padding: 15px;
}
#explanation {
color: #777;
}
#explanation::before {
content: 'Explanation:';
display: block;
font-weight: bold;
}
JavaScript
var
counter = document.querySelector('#counter'),
measure = document.querySelector('#measure')
;
function count_up(){
counter.innerText = parseInt(counter.innerText, 10) +1;
}
// the problem.
document.querySelector('#untreated').onclick = function(){
count_up();
};
//------------------------------------------------------------
// figuring out a solution.
document.querySelector('#treated').onclick = function(ev){
count_up();
switch (measure.value) {
// changes nothing.
case 'stopPropagation':
ev.stopPropagation();
break;
// changes nothing.
case 'stopImmediatePropagation':
ev.stopImmediatePropagation();
break;
// stops twice-ness, but prevents the tick, even for the checkbox's onclick.
case 'preventDefault':
ev.preventDefault();
break;
// stops twice-ness, but prevents the tick, even for the checkbox's onclick.
case 'return false':
return false;
break;
// changes nothing.
case 'return true':
return true;
break;
}
};
//------------------------------------------------------------
// this is the only solution that works.
document.querySelector('#onchange').onchange = function(){
count_up();
};
document.querySelector('#inputclick').onclick = function(){
count_up();
};