LoginSignup
2
0

More than 5 years have passed since last update.

`$("input:enabled:invalid")`で「unsupported pseudo: invalid」というエラーが出る(jQuery 3.3.1)

Last updated at Posted at 2018-03-25

環境

  • jQuery 3.3.1

以下のHTMLを使います。

<input type="text" required value="test"> <!-- valid -->
<input type="text" required> <!-- invalid(requiedなのにvalueがない) -->
<input type="text" required disabled> 

See the Pen $("input:enabled:invalid ")の確認 by yuji38kwmt (@yuji38kwmt) on CodePen.

問題

以下のJavaScriptをChromeで実行したところ、$("input:enabled:invalid").lengthでSyntax Errorが発生しました。

Console
$("input:enabled:invalid").length; //⇒Syntax Error ("1"を期待していた)
$("input:enabled").length; //⇒2
$("input:invalid").length; //⇒1
$("input.not-exists:enabled:invalid").length; //⇒0("input.not-exists"は存在しない要素)
console
Error: Syntax error, unrecognized expression: unsupported pseudo: invalid
    at Function.Sizzle.error (jquery-3.3.1.js:1541)
    at PSEUDO (jquery-3.3.1.js:1888)
    at matcherFromTokens (jquery-3.3.1.js:2437)
    at Sizzle.compile (jquery-3.3.1.js:2591)
    at Sizzle.select (jquery-3.3.1.js:2677)
    at Function.Sizzle [as find] (jquery-3.3.1.js:845)
    at jQuery.fn.init.find (jquery-3.3.1.js:2873)
    at new jQuery.fn.init (jquery-3.3.1.js:2983)
    at jQuery (jquery-3.3.1.js:139)
    at sample.html:36

他のブラウザで検証した結果

ブラウザ 結果
Google Chrome 65.0.3325.181 NG
Internet Explorer 11.309.16299.0 NG
Microsoft Edge 41.16299.248.0 OK
Firefox 59.0.1 OK

エラーの調査

jquery-3.3.1.js_(1881行-1916行)
        "PSEUDO": function( pseudo, argument ) {
            // pseudo-class names are case-insensitive
            // http://www.w3.org/TR/selectors/#pseudo-classes
            // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
            // Remember that setFilters inherits from pseudos
            var args,
                fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
                    Sizzle.error( "unsupported pseudo: " + pseudo );

            // The user may use createPseudo to indicate that
            // arguments are needed to create the filter function
            // just as Sizzle does
            if ( fn[ expando ] ) {
                return fn( argument );
            }

            // But maintain support for old signatures
            if ( fn.length > 1 ) {
                args = [ pseudo, pseudo, "", argument ];
                return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
                    markFunction(function( seed, matches ) {
                        var idx,
                            matched = fn( seed, argument ),
                            i = matched.length;
                        while ( i-- ) {
                            idx = indexOf( seed, matched[i] );
                            seed[ idx ] = !( matches[ idx ] = matched[i] );
                        }
                    }) :
                    function( elem ) {
                        return fn( elem, 0, args );
                    };
            }

            return fn;
        }

at PSEUDO (jquery-3.3.1.js:1888)は、以下の処理です。

jquery-3.3.1.js_(1886行-1888行)
            var args,
                fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
                    Sizzle.error( "unsupported pseudo: " + pseudo );

Expr.pseudos[ pseudo ] , Expr.setFilters[ pseudo.toLowerCase() ]がundefined or nullのため、Sizzle.errorが呼ばれたようです。

以下の場合、1888行目の処理を通りませんでした。

  • Firefoxで、$("input:enabled:invalid").lengthを実行したとき
  • Chromeで、$("input:invalid").lengthを実行したとき

これ以上のことは分かりませんでした。

【補足】document.querySelectorAllの場合

Chromeでエラーは発生しませんでした。

Console
document.querySelectorAll("input:enabled").length; //⇒2
document.querySelectorAll("input:invalid").length; //⇒1
document.querySelectorAll("input:enabled:invalid").length; //⇒1

【補足】 CSSの場合

期待通りの結果でした(CodePen参照)。

input:enabled {
  border-left-color: red;
}

input:invalid {
  border-right-color: red;
}

input:enabled:invalid {
  border-top-color: red;
}

そもそもやりたかったこと

Enabled/Disabledが切り替わるテキストボックスに対して、入力チェックをしたいです。
そのため、$("input:enabled:invalid")と記述しました。
しかし$("input:invalid")でDisabledのテキストボックスが除外されたので、$("input:invalid")で私のやりたいことは実現できました。

感想

GitHubにIssueを出して、回答をいただきました。
https://github.com/jquery/jquery/issues/4021

Thank you for opening an issue! However, the :invalid selector is not officially supported in jQuery. It works natively, but Sizzle doesn't trust native qSA with :enabled/:disabled due to a certain qSA bug in Chrome. There are a couple workarounds.

そもそもjQueryは:invalidをサポートしていませんでした。
確かに公式サイトに:invalidは掲載されていませんね。
https://api.jquery.com/category/selectors/

  • qSAdocument.querySelectorAllのことだと思います。

$("input").filter(":invalid")でも同様のエラーが発生します。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0