11 ms·
Lesser-known JavaScript APIs
- rareitem 4y agoI was wondering how reddit accessed my native device share functionality when you pressed the “share” button on a post, turns out it was a JS API
- dspillett 4y agoLooking a bit deeper there is the reverse option if you have you code registered as an installed PWA, allowing you app to be a share target without being a native app. Could be useful for a couple if things I might tinker with at some point.
- tiagod 4y agoI thought I was familiar with the APIs in the article, but I didn't know that! Thanks, going to check it out.
- jeroenhd 4y agoThis would be great for web apps like photopea!
- djbusby 4y agoI made one of these web-based Android share target things. I found the JS API a little tough but now all of my on-phone apps can share into my custom thing (a personal KB) Edit: it's cool and fun, nice weekend project.
- s4i 4y agoI used this to more easily share links to HN when I'm on the phone (only works on Android for now though). [1] [1] https://samulisuomi.github.io/share-to-hn-pwa/ https://samulisuomi.github.io/share-to-hn-pwa/
- thrdbndndn 4y agoSemi-funny story: I was still using Win7 at the time and the share button from a browser extension crashes itself due to not handling non-support system properly. This is how I learnt that even desktop operating system (Win10 in this case) nowadays has share feature.
- thex10 4y agoAwesome, didn't know about the Page Visibility API but now I'd like to explore it as a way to stop/start subscribing to streaming data.
- ghayes 4y agoI just tend to wrap my timer callbacks in a requestAnimationFrame, which should delay processing when the page isn’t visible. I guess this is a hack, but it’s been with me for so long now.
- alwayslikethis 4y agoI use an extension to disable/spoof it by default as a way to counteract those annoying websites that wants you to watch things in their entirety.
- notatoad 4y agoif applications are using it for non-nefarious reasons, the fallback behaviour for people like you who block it is to use more of your bandwidth or battery power to render non-visible elements. it's an optimization for most people, so it's still worth implementing even if some clients block the API.
- majestic5762 4y agoWhoever is a js/fe dev, used these already
- kupopuffs 4y agoIntl API is new to me!
- panzi 4y agoBroadcastChannel was the only thing new to me. I only knew the LocalStorage based hack (listening to the storage event and exchanging messages via the LocalStorage).
- Chris_Newton 4y agoIntl.Collator is a web UI superpower but apparently a well-kept secret: it gives you string sorting that takes into account local conventions for things like accented characters and even sorts strings containing numerical parts into natural rather than lexicographical order (that is, it correctly sorts “Item 1” before “Item 2” before “Item 10”).
- unsupp0rted 4y agoThis alone is worthy of its own post!
- jamesfinlayson 4y agoOh wow - lexicographical sorting built in to the browser!
- masklinn 4y agoIntl.DateTimeFormat is also really nicely done, because it limits the developer to "skeletons": you say what fields you want / need, and the browser will render what it has with at least those. Meaning the OS / user can override your whims if that's better or more readable. There's also formatRange which can provide localised range notations. Although later on formatToParts was added which allows the developer to ignore the settings and really only use the bits they wanted anyway.
- uzername 4y agoPage Visibility API is used in tools like react query, where it will show the page with the existing cached data, but refetch in the background upon a page visibility event. It feels natural for some apps to have this update-on-focus behavior, and it's nicer than polling with set interval. Intl API is great, but I feel it's somewhat hamstrung because Node doesn't have matching APIs.
- alwayslikethis 4y agoPage Visibility is also often abused to force you to watch videos/ads in their entirely without switching to another page. If any one here suffers from something like this, be sure to check out extensions like "Always active window" on Firefox, which would spoof it to make it look like you are on the page the entire time.
- keanebean86 4y agoYears ago I used this on my web application to work around a bug/leak. There was an auto update feature that ran on a regular basis. I made a mistake somewhere when replacing page elements that slowly increased memory usage. While developing I would close everything at the end of the day but my users would leave the page up for days. Eventually the small leak would crash the tab. I "fixed" it by shutting off auto update on page blur then immediately doing an update on focus.
- cgijoe 4y ago> Intl API is great, but I feel it's somewhat hamstrung because Node doesn't have matching APIs. Are you sure? It seems to be very well supported in Node.js: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#browser_compatibility https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- Waterluvian 4y agoMaybe not an “API” and maybe not lesser known but every developer should be aware of Proxy. Don’t abuse it. But be aware it exists. It’s a beautiful escape hatch for things when you need advanced capabilities but still need to fit an existing object shape.
- newhotelowner 4y agoProxy? How does it work?
- Waterluvian 4y agohttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... Imagine an Object where you control _all_ the getting and setting.
- wruza 4y agoAnd it is also slow as hell, so yeah, don’t abuse it for regular programming or in hot loops.
- no_way 4y agoIt was very slow before, but browsers improved performance a lot, multiple frameworks use proxies for their reactive primitives under the hood, Vue, Mobx and so on. SolidJS is one of the fastests frameworks out there and is built mainly on proxies, so proxies themselves can't be that slow. Granted in very very tight loop regular object get/set will be faster, but performance is more than good enough today. If you have an use case for it, use it.
- Waterluvian 4y agoImmer relies completely on it and is wicked fast. It did improve by a lot in recent times.
- 4y ago
- cratermoon 4y ago> In general, we want to use the Page Visibility API to stop unnecessary processes when the user doesn’t see the page or, on the other hand, to perform background actions. Hahahaha no. That's going to be put to use for surveillance and watching when people switch back and forth to the page to maximize ad revenue. I can imagine Twitch using it to determine if the viewer is really looking at the page of if they have gone off to another window, and using that to gauge "engagement" or some other "monetization" metric.
- peaBerberian 4y agoI don't know about twitch but I work for a streaming company and we're using the page visibility API mainly to lower video quality when the user is not actively watching the corresponding tab for more than a minute. This allows to keep audio while lowering bandwidth, CPU and memory usage. So yes it may be used for nefarious purposes but it also provides very nice features in a media streaming case.
- batesy 4y agoThat's pretty cool.
- cratermoon 4y agoI have no doubt there are good uses. Of course, that kind of screws people who have say, two monitors, with the video open in one while they are in another window. You could certainly argue they are not actively watching the tab, but they could be watching a show while they work or chat with family. Also, how long before the video streaming services use the api to adjust streamer compensation rates based on active/not active watchers?
- peaBerberian 4y agoAs far as I know, it shouldn't be triggered when you lose focus due to not being the active monitor, though I cannot really test it right now as I've only one monitor at home. > Also, how long before the video streaming services use the api to adjust streamer compensation rates based on active/not active watchers? Good remark, that wouldn't surprise me that they don't already do this on such services by the way, though I'm not at all familiar with stream compensation rules. You made me want to check if they collected it server-side on twitch by curiosity and they do seem to send regularly some engagement-related metrics (others than what I would assume would be useful to monitor if the player is doing a good job, such as bitrate and frame-drop-related matters). For example a base64-encoded JSON with properties such as "minutes_logged" (which I guess are the minutes since I logged in), a "chat_visible" boolean and more interesting here "time_spent_hidden" seems to be POSTed at intervals. That whole object is also conveniently associated to an "event" name called "minute-watched". What's strange though is that the URL makes it look like they're requesting an usual ".ts" media segment though it is a POST request, it returns an HTTP 204 No Content and more importantly, the request is not performed by their usual media player script but by another mysterious p.js script, which makes it seem that this is not at all actually loading a media segment. Maybe this camouflage is here to prevent people from messing with it, as wrong data would probably mess with their internal logic, but I guess that it indicates that they do collect that data on their servers, though I don't know what they do with it. Moreover, they already have features to influence users so they stay active on the tab (for example the bonus points you win by clicking regularly on the treasure chest on the bottom of the chat), so that's not that surprising that they monitor this.
- alwayslikethis 4y agoI feel like Page Visibility API should be locked behind a permission toggle, which would ask whenever the website tries to listen to any of those events, and will not trigger the events until the user agrees to give the permission (whether or not the user grants the permission should not be revealed to the website). The ability for a website to see when you click on things outside of the page itself (either by changing active window or tab) is quite unexpected from an end-user perspective, and its use in various "ed tech" websites to detect alleged cheating[1] is frightening, to say the least. Other than that, it's also used in many other anti-user implementations of ads or other content in order to force you to watch them in their entirety. Edit: If you want to protect yourself from such abuse, try an extension that spoofs the API. You can try: "Always active window" on Firefox or "Don't make me watch" on Chrome. Test it with this website (not mine): https://testdrive-archive.azurewebsites.net/Performance/PageVisibility/Default.html https://testdrive-archive.azurewebsites.net/Performance/Page... 1. https://prioritylearn.com/teachers-canvas-tabs/ https://prioritylearn.com/teachers-canvas-tabs/
- bobbylarrybobby 4y agoThere's also StopTheMadness which can prevent pages from using the visibility API and also removes a whole host of annoying behaviors from “modern” websites.
- alwayslikethis 4y agoI know I probably already have most of those mitigations done, but, anything similar for non apple users?
- bobbylarrybobby 4y agoI believe it has chrome and Firefox extensions as well
- matheusmoreira 4y agoI agree. I've used Firefox extensions to override these APIs and stop sites like YouTube from pausing playback. The cheating detection thing in proctoring software is pretty disgusting as well. These web sites are getting way too abusive with the powerful APIs we've given them. It's time to reassert control.
- russellbeattie 4y agoI'm obsessed with stripping out dependencies so when I'm working on a new project I try to figure out which APIs are commonly supported and use them when I can. What amazes me is when I run into something that seems new to me, only to discover it has been around since Chrome 1.0 or earlier. The JavaScript and DOM APIs are decades old and obscenely huge at this point and you never use all of them on every project, and it's too easy to just go back to what you already familiar with. Case in point: Element.insertAdjacentHTML(). Not sure how I missed this pretty basic method, but there it is, helping turn a mess of code I had into a one liner. Itemscope and itemprop attributes as well. Wow, where did those come from? Oh, like 1999? Did I just forget they were there? Maybe. Or maybe I just never noticed. That doesn't even count the continuous new APIs being added during each Chromium release, which are now pretty much everywhere. Mind boggling.
- jamesfinlayson 4y agoinsertAdjacentHTML must be what jQuery's before and after use under the hood - I had no idea that they mapped to actual browser functionality though.
- est 4y agoSome fun formats: new Number(1234567890).toLocaleString('en-US-u-nu-fullwide', {useGrouping:false}); you can replace "fullwide" with "mathbold", "mathdbl", "mathmono", "mathsanb", "mathsans", etc. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#parameters https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- longnguyen 4y agoIn previous startup, we develop a virtual deal room where each prospect has their own private deal page. We use Page Visibility API to gauge how focus/interest the prospect is about a particular deal package.
- divbzero 4y agoThe article characterizes the Web Share API as “Poorly supported” but it’s actually not that far behind the others in terms of % global usage: Page Visibility API 98% Web Share API 90% Broadcast Channel API 93% Internationalization API 98%
- masklinn 4y agoThe difference is in breadth: - Page Visiblility is fully supported by all browsers except Opera Mini, and has been for a while - Same with Intl (aditionally except KaiOS) - Broadcast is supported by everyone but Opera Mini and Internet Explorer - Web Share is only fully supported by Safari, Edge, and some Android browsers (Chrome, Samsung, Firefox, Opera Mobile), Chrome only has partial support because only Windows and ChromeOS That means you can use the first 3 rather reliably, while Web Share is a lot more of a crapshoot.
- benkaiser 4y agoRegarding the web sharing API, I went down the rabbit hole of trying to share images with it and ended up writing a post about it: https://benkaiser.dev/sharing-images-using-the-web-share-api/ https://benkaiser.dev/sharing-images-using-the-web-share-api... Pretty awesome when combined with converting the DOM to a canvas and then sharing that.
- benknight87 4y agoThese aren't JavaScript APIs, they're Web Platform APIs.
- pibi 4y agoIntl could be considered a JS API, honestly. But yeah, it's ridiculous still conflating the two after all these years of full-stack Javascript developments.
- dmitriid 4y agoYou can only access them through Javascript running in the browser though. So it might not be that big of a distinction.
- chrismorgan 4y agoIntl is the ECMAScript Internationalization API (ECMA-402). Browsers are not the only JS implementations that include it. Node.js does, Deno does, probably others do too.
- tobyhinloopen 4y agoI used broadcast to (visually) sign out people put from all tabs when they sign out at one! Otherwise left-open tabs appear to be functional until the user does something.
- low_tech_punk 4y agoMy personal favorite is the Intl.Segmenter It's a basic tokenizer you can use for NLP pre-processing. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- esskay 4y agoI wonder how many terrabytes of storage would be saved by people realising these exist and not relying on thousands of tiny npm packages to do their own implementation of what some of these API's do.
- unsupp0rted 4y agoThere could be some NPM packages where the readme is “Don’t use this. This is an empty lib that only outputs this sentence. Use the XYZ api to do this instead, with docs found at: https:// https:// …”
- ehnto 4y agoI cleared 4gb out of my npm package cache the other day. Never in any version of the history of software was I expecting to end up with gigabytes of javascript on my machine, but here we are.
- WorldMaker 4y agoNode itself needs to better enable some of these. Off hand, I am aware that much of Intl was still flaky in Node into much too recently despite being rock solid in browsers for a lot longer. This is an area where Deno competition seems to be helping. Also, related to Intl replacing tons of code, Moment.js has this disclaimer up top of its README and npmjs.org listing today: > Moment.js is a legacy project, now in maintenance mode. But this is not big or bold enough and it is amazing how many projects still rely on a legacy package like this, which is huge because it bundles its own Intl replacement because it predates Intl. (Please use Luxon or date-fns or Intl.DateTimeFormat directly in 2022 rather Moment.js.)
- incrudible 4y agoDid anyone else notice that the profile picture of the author appears to be AI-generated?
- jrpelkonen 4y agoHow can you tell that?
- yencabulator 4y agoFor what it's worth, Page Visibility doesn't detect switching windows under the Sway Wayland compositor. It does detect switching tabs within the same window. https://github.com/swaywm/sway https://github.com/swaywm/sway
- WorldMaker 4y agoSome protips on Intl APIs (to simplify the examples in the article): 1) They default to the user's locale as set in their Browser settings and you don't ever need to look up navigator.language yourself. The trick to using an options object to something like Intl.DateTimeFormat where the options object is after the locale name is to pass `undefined` as the locale to opt in to the default behavior. (I wish they had swapped the order in constructors to make this easier/more obvious.) In the article's case can save a line and: const dateFormatter = new Intl.DateTimeFormat(undefined, { timeZone: 'UTC' }) Also, constructing a formatter like this is for better reuse of the formatter with saved options (ie, moving this up and out of the function defined in the articles instead of building a new one every function call). 2) There's one more important way to shrink this article's example down, many built-in JS types including `Date` as all these examples show now include a function directly to format using the appropriate Intl formatter called `toLocaleString`. In this case: Date.prototype.toLocaleString(locale, options) takes all the same options. You can replace the article's formatDate function entirely with toLocaleString: const parsedQuote = ` <q>${content}</q> <br> <p>- ${author}</p><br> <p>Added on ${dateAdded.toLocaleString(undefined, { timeZone: 'UTC' })}</p>`