9 web development tips and tricks out of the blue
Armel
Posted on December 16, 2019
In this article, I gathered 9 tips and tricks for web developers that I used recently. Even though the content is more oriented toward beginners, I hope it can still be a good reminder for more advanced developers.
1. Get the current timestamp
This is a little shorthand I found interesting, especially to understand what's going on behind the scene:
const ts = + new Date(); // Same as (new Date()).getTime()
console.log(ts);
// 1576178666126
Demo: https://codepen.io/armelpingault/pen/eYmBzEG
According to the documentation:
The
valueOf()
method returns the primitive value of the specified object. The shorthand notation is prefixing the variable with a plus sign.
and in case you need a reminder about what exactly is a primitive value:
In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 7 primitive data types: string, number, bigint, boolean, null, undefined, and symbol.
2. Detect a long press
I have a button that should trigger 2 different actions depending on the user interaction: one action on a normal click and another action on a long press on the button:
const btn = document.querySelector('button');
let timer;
btn.addEventListener('mousedown', (e) => {
timer = + new Date();
});
btn.addEventListener('mouseup', (e) => {
if (+ new Date() - timer < 500) {
console.log('click');
} else {
console.log('long press');
};
});
Demo: https://codepen.io/armelpingault/pen/rNaLpLE
3. Sort an array of objects
This one is a classic, we often need to sort an array of objects according to the value of one property of the objects.
const arr = [
{name: 'Jacques', age: 32},
{name: 'Paul', age: 45},
{name: 'Pierre', age: 20}
];
arr.sort((firstEl, secondEl) => firstEl.age - secondEl.age);
// [{name: 'Pierre', age: 20}, {name: 'Jacques', age: 32}, {name: 'Paul', age: 45}]
// And if you want to sort in descending order:
arr.sort((firstEl, secondEl) => secondEl.age - firstEl.age);
// [{name: 'Paul', age: 45}, {name: 'Jacques', age: 32}, {name: 'Paul', age: 20}]
Demo: https://codepen.io/armelpingault/pen/zYxoBPW
Also note that using the sort() function, the array is sorted in place, and no copy is made.
4. Communicate between components
When I need 2 of my Javascript components to communicate with each other, I sometimes end up implementing a Custom Event:
const el = document.createElement('div');
const btn = document.querySelector('button');
const event = new CustomEvent('sort', {
detail: {
by: 'name'
}
});
btn.addEventListener('click', () => {
el.dispatchEvent(event);
});
el.addEventListener('sort', (e) => {
console.log('Sort by', e.detail.by);
});
Demo: https://codepen.io/armelpingault/pen/gObLazb
5. Deep and shallow copy of an array of objects
This topic deserves a whole article by itself, you will find thousands of articles covering it, but I thought I put another reminder here after a discussion I had a couple of days ago with one of my colleagues.
When you need to create a copy of an array of object, it's tempting to
do:
const arr1 = [{a: 1, b: 2}, {c: 3, d: 4}];
const arr2 = arr1;
However, this is just going copy the reference to the original object and if you modify arr1
, then arr2
will be modified too.
const arr1 = [{a: 1, b: 2}, {c: 3, d: 4}];
const arr2 = arr1;
arr1[1].c = 9;
console.log(arr2);
// [{a: 1, b: 2}, {c: 9, d: 4}];
Demo: https://codepen.io/armelpingault/pen/OJPbXEy
Using the spread operator can help you create a shallow copy of your array. This will create a new array, but it will keep a reference to the objects inside the array.
const arr1 = [{a: 1, b: 2}, {c: 3, d: 4}];
const arr2 = [...arr1];
arr1.push({e: 5, f: 6});
arr1[0].a = 8;
console.log(arr2);
// [{a: 8, b: 2}, {c: 3, d: 4}];
Demo: https://codepen.io/armelpingault/pen/GRgNqBg
As you can see, adding a new element to arr1
is not changing arr2
. However, if I modify an object inside arr1
, then we will also see the changes inside arr2
.
Now if I want to make a deep copy of the array, I can do like this:
const arr1 = [{a: 1, b: 2}, {c: 3, d: 4}];
const arr2 = JSON.parse(JSON.stringify(arr1));
arr[1].d = 6;
console.log(arr1);
// [{a: 1, b: 2}, {c: 3, d: 6}];
console.log(arr2);
// [{a: 1, b: 2}, {c: 3, d: 4}];
Demo: https://codepen.io/armelpingault/pen/BayQzOK
In this case, I can see that whatever I change in arr1
, it won't have any impact on arr2
.
Note that with JSON.stringify, object instances (including Map, Set, WeakMap, and WeakSet) will have only their enumerable properties serialized.
6. Copy to clipboard
This is a little snippet I use to copy the content of a <textarea>
into the clipboard:
const textarea = document.querySelector('textarea');
const copy = () => {
textarea.select();
document.execCommand('copy');
alert('Content popied to clipboard!');
};
textarea.addEventListener('click', copy);
Demo: https://codepen.io/armelpingault/pen/jOEVrQw
There is also the Clipboard API that is offering more options to manipulate the clipboard. However, it's still an experimental feature and the browser support is still pretty low.
7. One npm command to rule them all
I am a very big fan of projects where the deployment command is just one simple line, whether it's for development or production.
While working on a project recently, I realized that we needed two commands to start our development environment, one from our server folder and one from our client folder. Well, we definitely needed to merge those two commands into one command we could run from the root folder.
Projects
|
|-- client
| package.json
|
|-- server
| package.json
|
package.json
Thanks to the npm package concurrently which is allowing us to run several npm commands at the same time.
// After installing the npm package
npm install --save-dev concurrently
// You should now see it in your package.json
"devDependencies": {
"concurrently": "^5.0.0"
}
// Then add the "master" command to the root package.json
"scripts": {
"start": "concurrently \"npm start --prefix ./client\" \"npm start --prefix ./server\"",
}
The --prefix
option will run any npm command inside the sub-folder of your choice:
npm run build --prefix ./client
8. Optimize SVG file
We work a lot with SVG icons on a daily basis, and those icons are usually provided by web design agencies or by the clients' web design department.
A lot of them are actually created and generated with software like Adobe Illustrator. Even though they are great tools to create graphic designs, they unfortunately also create a lot of extra useless markup in your SVG files if you don't pay attention to your export settings.
In order to optimize my SVG files, I use SVG Optimizer, which is pretty simple to integrate in your project:
// Install SVGO globally
npm install -g svgo
// Optimize all SVG file from -f "folder" to -o "folder"
svgo -f assets/src/svg -o assets/dist/svg
Last time I ran it, I was able to measure an average gain of around ~30% of the size of all the files... not bad!
9. Inspect WebSocket messages in Chrome
For the last tip of this article, I am re-posting an answer I wrote on StackOverflow that I needed while working on the development of a real-time web application.
- Open Chrome Developer Tools.
- Click on the Network tab.
- Click on the filter WS (for WebSockets).
- Reload the page to make sure you see your connection in the Name column.
- Click on Messages.
Now you should see all your communications with your WebSockets, with 3 columns: Data, Length and Time.
Any other web development tips and tricks you would like to share with the community, feel free to add them in the comment section ;)
Posted on December 16, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.