Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.

Commit 8f28358

Browse files
committed
Fixed missing link 🚀
1 parent d551009 commit 8f28358

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

_posts/2019-11-16-pull-to-refresh-web.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ authors: [fabrizio_duroni]
1616

1717
---
1818

19-
Some months ago I [transformed my website into a Progressive Web App]() (yes, the one you're reading now). By leveraging the power of service workers (and other some cool tricks that I will discuss in other posts :stuck_out_tongue_winking_eye:) my website page load time is below 50 milliseconds :open_mouth:. But with "the great power of service workers comes also great responsibility" (you remember [uncle Ben quote](https://www.google.com/search?q=from+great+power+comes+great+responsibility), right?), and one of this responsibility is let the user be able to refresh all the content whenever it wants (to check new/update stuff). Which is a mechanism/UX pattern that every user in the world already know for this kind of functionality? The [pull to refresh](https://en.wikipedia.org/wiki/Pull-to-refresh). The choice of this pattern is also a natural consequence of the fact that, as [I already told you previously in another post](), Progressive Web App are the technology that fill the gap between web and mobile native app. Unfortunately in the web development world there's not yet a standard component for pull to refresh. This is way in this post I will show you how to implement it from scratch without any JavaScript library/framework. I will only use vanilla JavaScript, HTML, CSS and the service worker *message* capabilities in combination with the `MessageChannel` class. The pull to refresh described in this article is available on this site in all the blog pages (including this one, try it now!!! :smirk:)
19+
Some months ago I [transformed my website into a Progressive Web App](https://www.fabrizioduroni.it/2019/03/03/github-pages-progressive-web-app.html "pwa") (yes, the one you're reading now). By leveraging the power of service workers (and other some cool tricks that I will discuss in other posts :stuck_out_tongue_winking_eye:) my website page load time is below 50 milliseconds :open_mouth:. But with "the great power of service workers comes also great responsibility" (you remember [uncle Ben quote](https://www.google.com/search?q=from+great+power+comes+great+responsibility), right?), and one of this responsibility is let the user be able to refresh all the content whenever it wants (to check new/update stuff). Which is a mechanism/UX pattern that every user in the world already know for this kind of functionality? The [pull to refresh](https://en.wikipedia.org/wiki/Pull-to-refresh). The choice of this pattern is also a natural consequence of the fact that, as [I already told you previously in another post](), Progressive Web App are the technology that fill the gap between web and mobile native app. Unfortunately in the web development world there's not yet a standard component for pull to refresh. This is way in this post I will show you how to implement it from scratch without any JavaScript library/framework. I will only use vanilla JavaScript, HTML, CSS and the service worker *message* capabilities in combination with the `MessageChannel` class. The pull to refresh described in this article is available on this site in all the blog pages (including this one, try it now!!! :smirk:).
2020
Let's start from the implementation of the UI (HTML and CSS)
2121

2222
#### UI: HTML and CSS
@@ -40,7 +40,7 @@ Below you can find the entire html code snippet.
4040
</div>
4141
```
4242

43-
Let's see what I did on the CSS side. The code reported below here is written in [SASS](https://en.wikipedia.org/wiki/Sass_(stylesheet_language)) (the preprocessor scripting language that is interpreted or compiled into Cascading Style Sheets (CSS)), but you can easily transform it in plain CSS if you need. First of I used a new CSS property in the `html` rule: `overscroll-behavior-y`. This property let the developers change the browser behaviour when the user researches the edge of the page with a scroll gesture. This is a property supported by Chrome, Firefox and Opera (fuck you Safari!!! :rage:). By setting it's value to `contains`, we can for example disable the native browser pull to refresh on Chrome and avoid the page bounce effect when the user starts to overflow the borders while dragging. Then I defined a property `pullable-content` that I used on the entire content of the page that I want to move in parallel with the pull to refresh. The next class is `pull-to-refresh` and contains all the styles needed to layout the pull to refresh in all its states. As you can see I defined all the animation I needed for this UI component here except for the translation applied while dragging that will be computed on the JavaScript side (because this are simple animation and [CSS is performant enough for this kind of animations](https://medium.com/outsystems-experts/how-to-achieve-60-fps-animations-with-css3-db7b98610108)). Last but not least I defined 2 classes to reset the pull to refresh layout status when the pull to refresh is started or has reached the end and starts the refresh of the content (they will be applied, like other contained here, with JavaScript DOM API).
43+
Let's see what I did on the CSS side. The code reported below here is written in [SASS](https://en.wikipedia.org/wiki/Sass_(stylesheet_language)) (the preprocessor scripting language that is interpreted or compiled into Cascading Style Sheets (CSS)), but you can easily transform it in plain CSS if you need. First of all I used a new CSS property in the `html` rule: `overscroll-behavior-y`. This property let the developers change the browser behaviour when the user researches the edge of the page with a scroll gesture. This is a property supported by Chrome, Firefox and Opera (fuck you Safari!!! :rage:). By setting it's value to `contains`, we can for example disable the native browser pull to refresh on Chrome and avoid the page bounce effect when the user starts to overflow the borders while dragging. Then I defined a property `pullable-content` that I used on the entire content of the page that I want to move in parallel with the pull to refresh. The next class is `pull-to-refresh` and contains all the styles needed to layout the pull to refresh in all its states. As you can see I defined all the animation I needed for this UI component here except for the translation applied while dragging that will be computed on the JavaScript side (because this are simple animation and [CSS is performant enough for this kind of animations](https://medium.com/outsystems-experts/how-to-achieve-60-fps-animations-with-css3-db7b98610108)). Last but not least I defined 2 classes to reset the pull to refresh layout status when the pull to refresh is started or has reached the end and starts the refresh of the content (they will be applied, like other contained here, with JavaScript DOM API).
4444

4545
```scss
4646
html {
@@ -322,7 +322,7 @@ const sendMessageToServiceWorker = (message) => {
322322
}
323323
```
324324

325-
Then In the service worker I added a new `message` listener that receive all the messages sent with the function above. At the moment I have only the `refresh` message. This is why all the code to manage this message is contained inside it (just to explain the reason to the [clean code fluffy evangelist](https://twitter.com/dan_abramov/status/1190762799338790913) :sweat_smile:). In the listener I check for the correctnes of the event label, and then I start to clean up the cache from all the assets and pages of the blog with (this is why for example the `createDeleteOperationsForImages` checks that the url contains the `posts` path, in order to avoid the deletion of home images). This delete cache function are all execute in a `Promise.all` call. When this function completes the execution of all the delete operation, I call `sendRefreshCompletedMessageToClient()` to warn the original JavaScript code (the `port1.onmessage` listener we saw above) that the refresh operation has been completed.
325+
Then In the service worker I added a new `message` listener that receive all the messages sent with the function above. At the moment I have only the `refresh` message. This is why all the code to manage this message is contained inside it (just to explain the reason to the [clean code fluffy evangelist](https://twitter.com/dan_abramov/status/1190762799338790913) :sweat_smile:). In the listener I check for the correctness of the event label, and then I start to clean up the cache from all the assets and pages of the blog with (this is why for example the `createDeleteOperationsForImages` checks that the url contains the `posts` path, in order to avoid the deletion of home images). This delete cache function are all execute in a `Promise.all` call. When this function completes the execution of all the delete operation, I call `sendRefreshCompletedMessageToClient()` to warn the original JavaScript code (the `port1.onmessage` listener we saw above) that the refresh operation has been completed.
326326

327327
```javascript
328328
//...other service worker code...

0 commit comments

Comments
 (0)