checkbox inside span onclick of span.. check input.. jquery recursion problem
This code causes a recursive behavior..
开发者_如何学编程I want to be able to click the text in the span and check/uncheck the child input and trigger the click event for the child input.
http://jsfiddle.net/cwfontan/ALEBr/
<span class="RedHover">
<input type="checkbox" name="chkShowBusn" id="chkShowBusn" tabindex="9" />Business
</span>
$('.RedHover').click(
function (e) {
try {
$(this).children('input').trigger('click');
e.stopPropagation();
e.preventDefault();
console.log('here');
} catch (e) {
//handle no click event.alert
console.log(e.description);
}
}
);
<input type="checkbox" name="chkShowBusn" id="chkShowBusn" tabindex="9" />
<label for="chkShowBusn">Business</label>
And you don't even need jQuery...
The problem is that the event triggered on the input
element then bubbles up and is handled on the span
. This happens for the original event and for the event that you fire programmatically.
The solution is probably to check to see if the event originated on an input
element, and not to handle it if it did:
$('.RedHover').click(
function (e) {
if (e.target.nodeName.toLowerCase() !== 'input') {
$(this).children('input').trigger('click');
e.stopPropagation();
e.preventDefault();
console.log('here');
}
}
);
The try/catch
was unnecessary, jQuery will ensure that the event object always exists and has the methods you use.
The calls to stopPropgation
and preventDefault
may be unnecessary, depending on your expected behaviour.
Since the span
only has one child, you could do this another way round. If this
(the element where the event is handled, always the span
) is the same as e.target
(the element where the event originated, either the span
or the input
), you can proceed:
$('.RedHover').click(
function (e) {
if (this === e.target) {
$(this).children('input').trigger('click');
e.stopPropagation();
e.preventDefault();
console.log('here');
}
}
);
Note that this is much less stable than checking the nodeName
: if you altered your HTML in future, it may break this code.
You can stop the propagation in the click of the checkbox like so
$('input[type=checkbox]').click(function(e){
e.stopPropagation();
e.preventDefault();
});
check this jsfiddle
I had a similar problem and found this to be the solution.
HTML
<span for="chkCheckbox">
<input id="chkCheckbox" type="checkbox" />
<label for="chkCheckbox">My Checkbox Label</label>
</span>
Javascript (expanding to jQuery is easy, I am not including it since it was answered by @lonesomeday, and I always prefer Javascript over using another library)
var checkboxSpans = document.querySelectorAll("span[for]");
for (var i = 0; i < checkboxSpans.length; i++) {
var forCheckbox = checkboxSpans[i].getAttribute("for");
forCheckbox = document.getElementById(forCheckbox);
if (forCheckbox != null) {
checkboxSpans[i].onclick = function (chk) {
return function (e) {
if (this === e.target) {
e.stopPropagation();
e.preventDefault();
if (chk.checked != true) {
chk.checked = true;
} else {
chk.checked = false;
}
}
}
}(forCheckbox);
}
}
This way you can use it the same as if you would use a label. This can actually be added to any type of element.
This was expanded from the answer provided by @lonesomeday
精彩评论