191 lines
4.9 KiB
Markdown
191 lines
4.9 KiB
Markdown
Extras
|
|
|
|
- event delegation
|
|
to detect events in child elements without need to attach listener to each of them
|
|
```js
|
|
// Assuming ulElement is a reference to your <ul> element
|
|
const ulElement = document.querySelector('ul');
|
|
|
|
// Add a click event listener to the ul element
|
|
ulElement.addEventListener('click', function(event) {
|
|
// Check if the clicked element is an li element
|
|
if (event.target.tagName === 'LI') {
|
|
// Get the text content of the clicked li element
|
|
const clickedText = event.target.textContent;
|
|
|
|
// Do something with the clicked text
|
|
console.log('Clicked li:', clickedText);
|
|
}
|
|
});
|
|
|
|
```
|
|
- generate random string
|
|
```js
|
|
function generateRandomString(length) {
|
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
let result = '';
|
|
const charactersLength = characters.length;
|
|
for (let i = 0; i < length; i++) {
|
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Example usage:
|
|
const randomString = generateRandomString(10); // Generates a random string of length 10
|
|
console.log(randomString);
|
|
|
|
```
|
|
- form data directly through form element
|
|
Note : make sure that input element contains name attribute as its value is the key/field of formdata
|
|
just use
|
|
```js
|
|
<form action="/route/api" method="POST">
|
|
<input type="text" name="city">
|
|
</form>
|
|
|
|
const onSubmit = async (e) => {
|
|
e.preventDefault();
|
|
|
|
const formData = new FormData(e.currentTarget);
|
|
|
|
// Convert FormData to a plain object for logging
|
|
const formDataObj = {};
|
|
formData.forEach((value, key) => {
|
|
formDataObj[key] = value;
|
|
});
|
|
|
|
console.log(formDataObj); // This will log a plain object with form data
|
|
|
|
const response = await fetch("/addschool/api", {
|
|
method: "POST",
|
|
body: formData,
|
|
});
|
|
};
|
|
|
|
```
|
|
this will just Formdata which is not multipart but of urlencoded and field will be `city`
|
|
|
|
for multipart form data
|
|
|
|
```html
|
|
<form onSubmit={onSubmit}>
|
|
<input type="text" name="city">
|
|
</form>
|
|
```
|
|
- extract query params from url
|
|
```js
|
|
let searchParams = new URLSearchParams(window.location.search);
|
|
const value = searchParams.get('field_name');
|
|
|
|
```
|
|
- form validation methods
|
|
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#the-constraint-validation-api
|
|
- to launch custom events use this
|
|
```js
|
|
const invalidEvent = new Event("invalid", {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
});
|
|
|
|
console.log("invalid event");
|
|
e.target.dispatchEvent(invalidEvent);
|
|
```
|
|
|
|
|
|
|
|
- Creating most apis easily
|
|
To create mock api easily use something like json-server(simple way with less features) or hoverfly(complex way with more features)
|
|
https://github.com/typicode/json-server
|
|
https://github.com/SpectoLabs/hoverfly
|
|
|
|
|
|
regex tip
|
|
- When using parentheis for grouping in js, sometimes we just want to group and not to capture when usng exec method in js so use
|
|
`/^(?:http|ftp):\/\/(.+)/` instead of `/^(http|ftp):\/\/(.+)/` .
|
|
this `?:` signals exec to not capture
|
|
|
|
|
|
conditionally set properties
|
|
```js
|
|
const isAdmin = true;
|
|
|
|
const user = {
|
|
id: 1,
|
|
name: "Alice",
|
|
...(isAdmin && { role: "admin" }) // Spreads { role: "admin" } only if isAdmin is true
|
|
};
|
|
|
|
```
|
|
|
|
to convert intput element itno number easily use this
|
|
```js
|
|
const inputElement = document.getElementById("myInput");
|
|
|
|
// Returns a native JavaScript number directly (or NaN if empty/invalid)
|
|
const num = inputElement.valueAsNumber;
|
|
// const number = parseInt(inputElement.value)
|
|
```
|
|
|
|
|
|
|
|
abort async tasks in between
|
|
```js
|
|
const processController = new AbortController();
|
|
|
|
async function performHeavyTask(signal) {
|
|
try {
|
|
console.log("Step 1 started...");
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
// Check if the event fired while Step 1 was running
|
|
signal.throwIfAborted();
|
|
|
|
console.log("Step 2 started...");
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
// Check again before proceeding
|
|
signal.throwIfAborted();
|
|
|
|
console.log("Task completed perfectly!");
|
|
} catch (error) {
|
|
if (error.name === 'AbortError') {
|
|
console.log("Custom async workflow was stopped safely.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Triggering the stop on a custom event
|
|
window.addEventListener('userLeftPage', () => {
|
|
processController.abort();
|
|
});
|
|
|
|
performHeavyTask(processController.signal);
|
|
|
|
```
|
|
|
|
for video hover and all this
|
|
```js
|
|
|
|
let processController = null;
|
|
|
|
videoEle.addEventListener("mouseenter", () => {
|
|
processController = new AbortController();
|
|
|
|
rotateThumbnails(processController.signal);
|
|
});
|
|
videoEle.addEventListener("mouseleave", () => {
|
|
processController.abort();
|
|
});
|
|
```
|
|
|
|
to get content-type of response use
|
|
|
|
```js
|
|
const response = await fetch('https://example.com');
|
|
|
|
// Get the raw content-type string (e.g., "application/json; charset=utf-8")
|
|
const contentType = response.headers.get('content-type');
|
|
console.log(contentType);
|
|
|
|
```
|