开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜