Good day, comrades.
I ran into one problem in jQuery and now I want to find out: is everything as always (fool himself and goodbye to the remnants of karma) or is it still such a feature of jQuery?
Suppose there is the following HTML code:
< input id ="dis" type ="checkbox" /> <br> < input id ="chb" type ="checkbox" />< input id ="txt" type ="text" /> <br><br> * This source code was highlighted with Source Code Highlighter .
')
The scheme of operation is extremely simple: the #chb checkbox controls the activity of the #txt text field (when checked -! Disabled and vice versa), and the #dis checkbox disables (disabled = "disabled") the #chb checkbox and switches its status.
Here is an example code:
$( "#chb" ).click( function () {<br> $( "#txt" ).attr( "disabled" , ! this . checked );<br>});<br><br>$( "#dis" ).click( function () {<br> if ( $( "#chb" ).attr( "checked" ) )<br> {<br> $( "#chb" ).click();<br> }<br><br> $( "#chb" ).attr( "disabled" , this . checked ); <br>}); <br><br> * This source code was highlighted with Source Code Highlighter .
It would seem nothing unusual?
By clicking on #chb, the text field will turn on / off as necessary. But clicking on #dis, we get only disable #chb. What about #txt? After all, the execution of $ ("# chb"). Click () should guarantee that it will also be disabled. (If not, correct me, please, and give a link to the explanatory article. Thank you.)
As the test showed, there is some inconsistency in the sequence of actions.
When clicking on the checkbox with the mouse:
1) switch checked;
2) execute handlers hanged per click.
When you click () programmatically:
1) execute handlers hanged per click;
2) switch checked.
(you can check by hanging on click alert)That is,
the same (seemingly) operation causes
different sequences of actions.
Now it’s clear why #txt is not disabled: at the moment when the handler is executed (checking if the control box is checked and not checked?), The checkbox is still checked.
So what to do?
Once we know what is happening, then we can solve the problem.
Everything would be just great if somewhere not only the current state of the element (checked) was stored, but also the state change (+1 - checked changed from false to true, -1 - c true to false). Unfortunately, as far as I know, jQuery doesn't follow this.
A little materiel for understanding further. When clicking on an element, three events are sequentially generated:
1) mousedown
2) mouseup
3) click
Click is responsible for switching the checkbox state. And since it doesn’t behave the way we want, we’ll turn it off completely and use mouseup.
This is how I see the solution:
$( "#chb" ).click( function (e) {<br> // , <br> e.preventDefault();<br>});<br><br>$( "#dis" ).click( function () {<br> if ( $( "#chb" ).attr( "checked" ) )<br> {<br> $( "#chb" ).mouseup();<br> }<br><br> $( "#chb" ).attr( "disabled" , this . checked );<br>});<br><br>$( "#chb" ).mouseup( function () { <br> // — <br> this . checked = ! this . checked ; <br><br> $( "#txt" ).attr( "disabled" , ! this . checked ); <br>}); <br><br> * This source code was highlighted with Source Code Highlighter .
Thus, from mouseup, we made a click with predictable behavior.
I apologize for the writing style, it is difficult to read, but I can not write in another way. I hope someday this will come in handy.
And in the comments I will be happy with the explanations of such an unusual phenomenon, criticism and simpler solutions (if they are required at all). Thanks for attention.
upd: Habrayuzer
Yeah prompted the triggerHandler function, which can call handlers hung on events without triggering standard behavior. Then you can make it easier by changing a couple of lines in the initial version:
$( "#dis" ).click(function() {
if ( $( "#chb" ).attr( "checked" ) )
{
// : ,
$( "#chb" ).attr( "checked" , false );
$( "#chb" ).triggerHandler( 'click' );
}
$( "#chb" ).attr( "disabled" , this . checked );
});
* This source code was highlighted with Source Code Highlighter .
And no mouseup. But the question remains in the reasons for this behavior.