TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

TinyJS – Shorten JavaScript QuerySelect with $ and $$

102 点作者 synergy207 个月前

25 条评论

akira25017 个月前
I&#x27;ve been using this for years:<p><pre><code> const $id = new Proxy({}, { &#x2F;&#x2F; get element from cache, or from DOM get: (tgt, k, r) =&gt; (tgt[k] || ((r = document.getElementById(k)) &amp;&amp; (tgt[k] = r))), &#x2F;&#x2F; prevent programming errors set: () =&gt; $throw(`Attempt to overwrite id cache key!`) }); </code></pre> It&#x27;s nice to be able to refer to elements by property name, so:<p><pre><code> &lt;div id=&quot;thing&quot;&gt;&lt;&#x2F;div&gt; </code></pre> Is reachable with:<p><pre><code> $id.thing </code></pre> And, since the underlying structure is just an object, you can still enumerate it with Object.keys, which can sometimes be a useful debugging aid and general catalog of accessed elements.<p>Anyways.. Proxy is a wildly underappreciated and used class in JavaScript.
评论 #41725527 未加载
评论 #41725223 未加载
评论 #41725481 未加载
评论 #41725207 未加载
评论 #41725650 未加载
评论 #41726369 未加载
评论 #41725591 未加载
tomp7 个月前
Why would this make any sense?<p><pre><code> const myDiv = div( {id: &#x27;container&#x27;, className: &#x27;my-class&#x27;}, h1(&#x27;Hello World&#x27;), p(&#x27;This is a dynamically generated paragraph.&#x27;) ); document.body.appendChild(myDiv); </code></pre> That&#x27;s completely unnecessary these days with template strings. It&#x27;s gonna be much faster as well to use browser&#x27;s native parsing.<p><pre><code> const div = document.createElement(&#x27;div&#x27;); let text = &#x27;This is a dynamically generated paragraph&#x27;; div.innerHTML = ` &lt;div id=&quot;container&quot; class=&quot;my-class&quot;&gt; &lt;h1&gt;Hello world&lt;&#x2F;h1&gt; &lt;p&gt;${text}&lt;&#x2F;p&gt; &lt;&#x2F;div&gt; `; document.body.append(...div.children); </code></pre> Keep it simple!
评论 #41724867 未加载
评论 #41724730 未加载
评论 #41724562 未加载
评论 #41724739 未加载
评论 #41724809 未加载
评论 #41724612 未加载
评论 #41724614 未加载
评论 #41725947 未加载
评论 #41725231 未加载
emmanueloga_7 个月前
I use this:<p><pre><code> export const $ = document.querySelector.bind(document); export const $$ = document.querySelectorAll.bind(document); </code></pre> When using TypeScript the types for querySelectorAll are a bit hairy to map but by defining the consts like above the types &quot;just work&quot;.<p><pre><code> for (const tag of $$&lt;HTMLParagraphElement&gt;(&quot;p&quot;)) ... </code></pre> I don&#x27;t use Array.from in the result of $$ because sometimes creating an Array is not necessary. The NodeList returned can be iterated directly or converted to an array later if really needed:<p><pre><code> [...$$(&quot;p&quot;)].map(p =&gt; ...) </code></pre> Since I use TypeScript I lean on TSX for building HTML. I use preact&#x27;s render-to-string package to convert it to a string [1].<p>---<p>1: <a href="https:&#x2F;&#x2F;github.com&#x2F;preactjs&#x2F;preact-render-to-string">https:&#x2F;&#x2F;github.com&#x2F;preactjs&#x2F;preact-render-to-string</a>
评论 #41725299 未加载
EMM_3867 个月前
I do believe I&#x27;ve seen something like this under another name.<p>Using &quot;$&quot; to shorten JavaScript? That seems a lot like jQuery.<p>&gt; This README was generated by ChatGPT<p>You don&#x27;t need AI to explain this one.
评论 #41724370 未加载
评论 #41724801 未加载
dpweb7 个月前
If ya don&#x27;t want to do includes,<p>` window.$ = document.querySelector.bind(document) window.$$ = document.querySelectorAll.bind(document) `
评论 #41724825 未加载
评论 #41725347 未加载
评论 #41724829 未加载
henriquez7 个月前
You didn’t need a library to do this. Just alias document.querySelector and document.querySelectorAll to something shorter. Polluting the global namespace with functions to document.createElement on every possible html tag is not a good idea.
123yawaworht4567 个月前
may I ask what&#x27;s the point of `const tagNames =`? removing it would make no difference, as far as I can tell - just make sure the previous line ends with a semicolon (or add it at the same line as the opening square bracket)
评论 #41724470 未加载
评论 #41724515 未加载
dang7 个月前
Related:<p><i>Show HN: Tiny JS – A Tiny JavaScript Library for Easy DOM Creation</i> - <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=41462817">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=41462817</a> - Sept 2024 (4 comments)<p><i>Show HN: A better way of writing HTML via JavaScript?</i> - <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=41451559">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=41451559</a> - Sept 2024 (9 comments)
mendyberger7 个月前
Code is actually tiny. Impressive!<p>You could make it even smaller by removing all the element names, and just have it be passed in as an argument. Would also reduce the amount of functions you need to declare, though function count is likely not a problem for modern JS engines.<p>Anyway, great job you did there!
benabus7 个月前
I remember when we would throw this into our utilities.js scripts back in like 2007. We didn&#x27;t have querySelector yet, though. We&#x27;d also walk to school with no shoes, in the snow, uphill, both ways.
gmac7 个月前
Reminds me of some simple tools I used years ago when CoffeeScript was big: <a href="https:&#x2F;&#x2F;github.com&#x2F;jawj&#x2F;affogato&#x2F;blob&#x2F;master&#x2F;functions.coffee">https:&#x2F;&#x2F;github.com&#x2F;jawj&#x2F;affogato&#x2F;blob&#x2F;master&#x2F;functions.coffe...</a><p>Nowadays I tend to use Mithril instead, because immediate-mode UI is so much less hassle than retained-mode: <a href="https:&#x2F;&#x2F;mithril.js.org&#x2F;" rel="nofollow">https:&#x2F;&#x2F;mithril.js.org&#x2F;</a>
1GZ07 个月前
I wrote my first jQuery lite selector clone a bit ago, any feedback would be appreciated, especially since I don&#x27;t see the need to separate out querySelector &amp; querySelectorAll<p>``` const $ = (param) =&gt; { if (typeof param === &quot;string&quot; || param instanceof String) { const elm = document.querySelectorAll(param); return elm.length &gt; 1 ? elm : document.querySelector(param); } else { return [param].length === 1 ? [param][0] : [param]; } }; ```
SahAssar7 个月前
The title (&quot;TinyJS – Shorten JavaScript QuerySelect with $ and $$&quot;) seems to be about these two lines:<p><pre><code> window[&#x27;$&#x27;] = selector =&gt; document.querySelector(selector) window[&#x27;$$&#x27;] = selector =&gt; Array.from(document.querySelectorAll(selector)) </code></pre> The other part is a small &amp; naive (and I mean that in the best way) DOM abstraction.<p>I think the discussion here seems to be about one or the other, not the thing as a whole.
CSSer7 个月前
Calling those $ and $$ selector helper functions new is a bit disingenuous. They’ve been present as Chrome dev tools shortcuts for years. Let alone JQuery, I’ve also spent years seeing little articles about this neat trick on everything from medium to dev.to.<p>I recommend the author remove that or note inspiration from the README to avoid detracting from the rest of the work. I realize there’s more here than the traditional document.querySelector.bind(document) assignment.
yu3zhou47 个月前
Like jQuery but for 2024?
评论 #41724420 未加载
评论 #41724526 未加载
评论 #41724259 未加载
NetOpWibby7 个月前
&gt; This README was generated by ChatGPT<p>Damn good README. Also, good library.
评论 #41724367 未加载
im_nullable7 个月前
Based on the readme this is a subset of jQuery primarily targeted at creating dom nodes.<p>Kind of cool if this is what you need.
gvx7 个月前
With that name I&#x27;d expect a tiny implementation of JavaScript.
评论 #41725393 未加载
atum477 个月前
Hi everyone, author here. Let me know if you have any questions.
sublinear7 个月前
Sheer pollution. Never in anything I deploy to production.
coolThingsFirst7 个月前
Pls no, im tired boss
alexjplant7 个月前
jQuery II: The Quickening!<p>I recently built a toy Golang SSR project using Zepto, a jQuery-like library, and felt like I was 17 again (**EDIT: it&#x27;s unmaintained - don&#x27;t use it). Also of note is that &quot;Highlander II&quot; takes place in the year 2024 [1]. It&#x27;s a sign! Everything old is new again! `$` is immortal!<p>[1] <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Highlander_II:_The_Quickening" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Highlander_II:_The_Quickening</a>
评论 #41724495 未加载
评论 #41724506 未加载
评论 #41724737 未加载
评论 #41724360 未加载
jufitner7 个月前
Someone will fork this with proper ES modules and no window clobbering.
synergy207 个月前
This is the whole code:<p><pre><code> (() =&gt; { const assignDeep = (elm, props) =&gt; Object.entries(props).forEach(([key, value]) =&gt; typeof value === &#x27;object&#x27; ? assignDeep(elm[key], value) : Object.assign(elm, {[key]: value})) const tagNames = [&#x27;a&#x27;, &#x27;abbr&#x27;, &#x27;address&#x27;, &#x27;area&#x27;, &#x27;article&#x27;, &#x27;aside&#x27;, &#x27;audio&#x27;, &#x27;b&#x27;, &#x27;base&#x27;, &#x27;bdi&#x27;, &#x27;bdo&#x27;, &#x27;blockquote&#x27;, &#x27;body&#x27;, &#x27;br&#x27;, &#x27;button&#x27;, &#x27;canvas&#x27;, &#x27;caption&#x27;, &#x27;cite&#x27;, &#x27;code&#x27;, &#x27;col&#x27;, &#x27;colgroup&#x27;, &#x27;data&#x27;, &#x27;datalist&#x27;, &#x27;dd&#x27;, &#x27;del&#x27;, &#x27;details&#x27;, &#x27;dfn&#x27;, &#x27;dialog&#x27;, &#x27;div&#x27;, &#x27;dl&#x27;, &#x27;dt&#x27;, &#x27;em&#x27;, &#x27;embed&#x27;, &#x27;fieldset&#x27;, &#x27;figcaption&#x27;, &#x27;figure&#x27;, &#x27;footer&#x27;, &#x27;form&#x27;, &#x27;h1&#x27;, &#x27;h2&#x27;, &#x27;h3&#x27;, &#x27;h4&#x27;, &#x27;h5&#x27;, &#x27;h6&#x27;, &#x27;head&#x27;, &#x27;header&#x27;, &#x27;hr&#x27;, &#x27;html&#x27;, &#x27;i&#x27;, &#x27;iframe&#x27;, &#x27;img&#x27;, &#x27;input&#x27;, &#x27;ins&#x27;, &#x27;kbd&#x27;, &#x27;label&#x27;, &#x27;legend&#x27;, &#x27;li&#x27;, &#x27;link&#x27;, &#x27;main&#x27;, &#x27;map&#x27;, &#x27;mark&#x27;, &#x27;meta&#x27;, &#x27;meter&#x27;, &#x27;nav&#x27;, &#x27;noscript&#x27;, &#x27;object&#x27;, &#x27;ol&#x27;, &#x27;optgroup&#x27;, &#x27;option&#x27;, &#x27;output&#x27;, &#x27;p&#x27;, &#x27;param&#x27;, &#x27;picture&#x27;, &#x27;pre&#x27;, &#x27;progress&#x27;, &#x27;q&#x27;, &#x27;rp&#x27;, &#x27;rt&#x27;, &#x27;ruby&#x27;, &#x27;s&#x27;, &#x27;samp&#x27;, &#x27;script&#x27;, &#x27;section&#x27;, &#x27;select&#x27;, &#x27;small&#x27;, &#x27;source&#x27;, &#x27;span&#x27;, &#x27;strong&#x27;, &#x27;style&#x27;, &#x27;sub&#x27;, &#x27;summary&#x27;, &#x27;sup&#x27;, &#x27;table&#x27;, &#x27;tbody&#x27;, &#x27;td&#x27;, &#x27;template&#x27;, &#x27;textarea&#x27;, &#x27;tfoot&#x27;, &#x27;th&#x27;, &#x27;thead&#x27;, &#x27;time&#x27;, &#x27;title&#x27;, &#x27;tr&#x27;, &#x27;track&#x27;, &#x27;u&#x27;, &#x27;ul&#x27;, &#x27;var&#x27;, &#x27;video&#x27;, &#x27;wbr&#x27; ].forEach(tag =&gt; window[tag] = function(...args) { const props = typeof args[0] == &#x27;object&#x27; &amp;&amp; !(args[0] instanceof HTMLElement) ? args.shift() : null const elm = document.createElement(tag) props &amp;&amp; assignDeep(elm, props) elm.append(...args.map(a =&gt; typeof a == &#x27;string&#x27; ? document.createTextNode(a) : a)) return elm }) window[&#x27;$&#x27;] = selector =&gt; document.querySelector(selector) window[&#x27;$$&#x27;] = selector =&gt; Array.from(document.querySelectorAll(selector))</code></pre> })()
评论 #41724381 未加载
评论 #41725601 未加载
评论 #41726330 未加载
wackget7 个月前
I&#x27;ll just leave this here: <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Uo3cL4nrGOk" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Uo3cL4nrGOk</a>
评论 #41725459 未加载