api.jquery.com icon indicating copy to clipboard operation
api.jquery.com copied to clipboard

:checkbox, :password and other selectors have innacurate documentation

Open acdcjunior opened this issue 10 years ago • 10 comments

By checking http://api.jquery.com/checkbox-selector/ (and others similarly) we are told that

$( ":checkbox" ) is equivalent to $( "[type=checkbox]" ). (...)

But that is false:

$('<span type="checkbox"></span>').is(":checkbox") // yields false
$('<span type="checkbox"></span>').is("[type=checkbox]") // yields true

I know that usually that attribute is used in <input> elements, but that does not make the documentation statement true.

acdcjunior avatar May 15 '14 21:05 acdcjunior

I know the question may sound trivial but should we update the documentation or the method?

AurelioDeRosa avatar Jul 06 '14 21:07 AurelioDeRosa

It seems the method does better than the documentation. Its current behavior ($('<span type="checkbox"></span>').is(":checkbox") returning false) is smarter than a mere [type=checkbox]. I think the problem is with the docs. The method probably does input[type=checkbox], but without the docs as they are, all we can do is guess/hope or take the time and dig out the source for what it really does.

acdcjunior avatar Jul 07 '14 00:07 acdcjunior

We should definitely update the documentation. I was thinking about how to rewrite this and was struggling a bit because it is similar to using the universal selector — $( "*[type='checkbox']" ) — in that it traverses every single element in the DOM, and that is where the drawback lies regarding performance. But it is equivalent to $( "input[type='checkbox']" ) in its result set because it checks for element.nodeName.toLowerCase() === "input" as well as the type property.

kswedberg avatar Jul 07 '14 01:07 kswedberg

Here is the function that Sizzle uses for these pseudo-selectors, for what it's worth:

function createInputPseudo( type ) {
    return function( elem ) {
        var name = elem.nodeName.toLowerCase();
        return name === "input" && elem.type === type;
    };
}

kswedberg avatar Jul 07 '14 01:07 kswedberg

Hi @kswedberg. This is not an easy decision to make because, based on the code, the pseudo-selector always select input elements. So, from a certain point of view suggesting users to write $('input:checkbox') is a bit redundant.

Probably the best thing to do, is to write that $(':checkbox') is equivalent to $('input[type="checkbox"]') and then add a global note about performance (I mean stored in the notes.xsl file).

What do you think?

AurelioDeRosa avatar Jul 07 '14 17:07 AurelioDeRosa

This is not an easy decision to make because, based on the code, the pseudo-selector always select input elements.

Well it always selects inputs but it can potentially iterate through every element on the page to find them. So as far as efficiency goes, it's not a good idea to use :checkbox by itself and we shouldn't be encouraging it.

dmethvin avatar Jul 07 '14 18:07 dmethvin

Also, the :text selector will select <input type="datetime"> and other HTML5 elements when the selector is used in a browser that doesn't support HTML5 inputs. That's because the property defaults to text on an unknown type attribute. Another good reason to use the attribute selector instead!

dmethvin avatar Jul 07 '14 18:07 dmethvin

yeah, @dmethvin, that was the point I was trying to make as well. it definitely presents a documentation challenge. I'll see what I can come up with tonight.

kswedberg avatar Jul 07 '14 18:07 kswedberg

To clarify the exact behavior: $(":checkbox") is equivalent to $("*").filter("input[type='checkbox']"); <--- using :checkbox is the same as using *:checkbox, so it does * then filter to only <input>

gnarf avatar Jul 07 '14 19:07 gnarf

$("input:checkbox") would be a significant gain to only have to filter across input elements instead of the implicit * on a ":checkbox" selector

gnarf avatar Jul 07 '14 19:07 gnarf