Path: csiph.com!news.mixmin.net!weretis.net!feeder1.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: filter queryselectorall Date: Sat, 06 Aug 2016 08:16:11 +0200 Organization: PointedEars Software (PES) Lines: 73 Message-ID: <1547678.NO00hCYTYS@PointedEars.de> References: Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1470464173 6985 eJwFwQkBgAAIA8BK4mBAHB7pH8E7A4XjSqPa2b3LkPLJhDYLiSbFIx+LWGhWDKqxep936A8GqxCN (6 Aug 2016 06:16:13 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Sat, 6 Aug 2016 06:16:13 +0000 (UTC) User-Agent: KNode/4.14.2 X-User-ID: eJwFwQkBACAIBLBK/GAchaN/BDfX4Oi08DBfX1JaidOnKvsRWq6edAaBZPKhVse8gUtjXcgnN8IwssK+H1MBFfI= X-NNTP-Posting-Host: eJwNxMEBwCAIA8CVQEmAcWg1+4/Q3uOw6XwzCAYEtfLodN2aZcnIOQUs/ttwfEfJ01y3Qw/1ARnvEO8= Xref: csiph.com comp.lang.javascript:31084 Michael Haufe (TNO) wrote: > On Friday, August 5, 2016 at 11:25:40 PM UTC-5, Andrew Poulos wrote: >> var clickables = document.querySelectorAll('[id^="clickable_"]').filter( >> function() { >> return this.id.match(/_\d*$/); >> }); >> >> gives me ...filter is not a function. >> >> How can I get just the elements whose ID that starts with "clickable_" >> and ends with an integer? Your approach would, if it worked verbatim, find elements with IDs “clickable__” and “clickable__2”, too. You have made the integer *optional* with the “*” and you have not excluded consecutive “_”s. “this” does _not_ refer to the current element in an Array.prototype.filter() loop callback, but to the global object in normal mode, and it is “undefined” in strict mode, by default; you can set “this” with the second argument of .filter(), but obviously not to the current element in the loop, too. (AISB:) String.prototype.match() is _not_ the proper method to use if you only want to *test* *if* a string matches a regular expression. In that case, use RegExp.prototype.test() instead; an additional advantage of it is that it converts the argument to String, whereas you have to typecast to String explicitly (or use "".match.call() or "".match.apply()) if you want to call String.prototype.match() on a value that you cannot be sure is a String value. > querySelectorAll does not return an Array. It returns a NodeList. You'll > want to convert it to an array proper first: > > let qsa = (s,ctx=document) => Array.from(ctx.querySelectorAll(s)) > > polyFill as necessary for your target environments, or use a JS compiler > such as Babel or TypeScript That is taking a sledgehammer to crack a nut. Instead: var clickables = [].filter.call( document.querySelectorAll('[id^="clickable_"]'), function (element) { return /_\d+$/.test(element.id); }); Alternatively: var clickables = [].filter.call( document.getElementsByTagName("*"), function (element) { return /^clickable_.*\d+$/.test(element.id); }); To mark and find suitable elements, consider using a “data-clickable” attribute as a marker and to filter on that attribute using the above, instead. Where that is not Valid (e.g. HTML < 5, default XHTML < 5), consider using a “js-clickable” class as a marker and document.getElementsByClassName("js-clickable") instead (the “js-” prefix makes sure your script-related classes do not interfere with classes that you use for styling; it is intended to work like a namespace). Reconsider your search context. Do you really need to search the whole document? If, e.g., this is for a form, consider using form.elements["clickable"] or form.getElementsByName("clickable") [may find more elements than the former] to find all elements with name "clickable" instead. -- PointedEars FAQ: | SVN: Twitter: @PointedEars2 | ES Matrix: Please do not cc me. / Bitte keine Kopien per E-Mail.