44 JSAnimation ,
55} from "animejs" ;
66
7+ // Implementation
78/**
89 * Query Selector
910 *
@@ -13,6 +14,7 @@ import {
1314export function qs < T extends HTMLElement = HTMLElement > (
1415 selector : string ,
1516) : ElementWithUtils < T > | null {
17+ checkUniqueSelector ( selector ) ;
1618 const el = document . querySelector < T > ( selector ) ;
1719 return el ? new ElementWithUtils ( el ) : null ;
1820}
@@ -44,6 +46,7 @@ export function qsa<T extends HTMLElement = HTMLElement>(
4446export function qsr < T extends HTMLElement = HTMLElement > (
4547 selector : string ,
4648) : ElementWithUtils < T > {
49+ checkUniqueSelector ( selector ) ;
4750 const el = document . querySelector < T > ( selector ) ;
4851 if ( el === null ) {
4952 throw new Error ( `Required element not found: ${ selector } ` ) ;
@@ -349,6 +352,7 @@ export class ElementWithUtils<T extends HTMLElement = HTMLElement> {
349352 * Query the element for a child element matching the selector
350353 */
351354 qs < U extends HTMLElement > ( selector : string ) : ElementWithUtils < U > | null {
355+ checkUniqueSelector ( selector , this ) ;
352356 const found = this . native . querySelector < U > ( selector ) ;
353357 return found ? new ElementWithUtils ( found ) : null ;
354358 }
@@ -372,6 +376,7 @@ export class ElementWithUtils<T extends HTMLElement = HTMLElement> {
372376 * @throws Error if the element is not found.
373377 */
374378 qsr < U extends HTMLElement > ( selector : string ) : ElementWithUtils < U > {
379+ checkUniqueSelector ( selector , this ) ;
375380 const found = this . native . querySelector < U > ( selector ) ;
376381 if ( found === null ) {
377382 throw new Error ( `Required element not found: ${ selector } ` ) ;
@@ -691,3 +696,33 @@ export class ElementsWithUtils<
691696 return this ;
692697 }
693698}
699+
700+ function checkUniqueSelector (
701+ selector : string ,
702+ parent ?: ElementWithUtils ,
703+ ) : void {
704+ if ( ! import . meta. env . DEV ) return ;
705+ const elements = parent ? parent . qsa ( selector ) : qsa ( selector ) ;
706+ if ( elements . length > 1 ) {
707+ console . warn (
708+ `Multiple elements found for selector "${ selector } ". Did you mean to use QSA? If not, try making the query more specific.` ,
709+ elements . native ,
710+ ) ;
711+ console . trace ( "Stack trace for qs/qsr call:" ) ;
712+ if ( document . querySelector ( "#domUtilsQsWarning" ) !== null ) return ;
713+
714+ const bannerCenter = document . querySelector ( "#bannerCenter" ) ;
715+ const warning = document . createElement ( "div" ) ;
716+ warning . classList . add ( "psa" , "bad" , "content-grid" ) ;
717+ warning . id = "domUtilsQsWarning" ;
718+ warning . innerHTML = `
719+ <div class="container">
720+ <div class="icon lefticon"><i class="fas fa-fw fa-exclamation-triangle"></i></div>
721+ <div class="text">
722+ "Warning: qs/qsr detected selector(s) matching multiple elements, check console for details."
723+ </div>
724+ </div>
725+ </div>` ;
726+ bannerCenter ?. appendChild ( warning ) ;
727+ }
728+ }
0 commit comments