2023년 6월 11일 일요일

잘알려지지 않은 유용한 JS API

 1. Page Visibility API

    사용자가 창을 최소화하거나 최대화하거나 탭을 전환하는지 여부에 관계없이 페이지의

    표시 상태가 변경될 때마다 이벤트를 발생

    * 활용

    사용자가 페이지에서 벗어날 때 비디오, 이미지 회전 또는 애니메이션을 일시 중지

    페이지에 API의 실시간 데이터가 표시되는 경우 사용자가 떠날 때 실시간 표시 동작을

    일시적으로 중지 등

document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
// page is visible
} else {
// page is hidden
}
});


2. Web Share API

운영 체제의 기본 공유 메커니즘에 액세스할 수 있으며, 이는 모바일 사용자에게 특히 유용합니다. 이 API를 사용하면 자체 공유 메커니즘을 만들거나 타사 공유 메커니즘을 사용하지 않고도 텍스트, 링크 및 파일을 공유

<div id="app">
<video controls id="video">
<source src="./yoshi.mp4" />
</video>
<div id="quote"></div>
<button type="button" id="share-button">Share Quote</button>
</div>
const shareButton = document.querySelector("#share-button");
const shareQuote = async (shareData) => {
try {
await navigator.share(shareData);
} catch (error) {
console.error(error);
}
};
const shareButton = document.querySelector("#share-button");
const shareQuote = async (shareData) => {
try {
await navigator.share(shareData);
} catch (error) {
console.error(error);
}
};
shareButton.addEventListener("click", () => {
let shareData = {
title: "A Beautiful Quote",
text: quote.textContent,
url: location.href,
};
shareQuote(shareData);
});


3. Broadcast Channel API

브라우저 컨텍스트는 서로 기본 데이터를 주고받을 수 있습니다. 브라우저 컨텍스트는 탭, 창 또는 페이지를 표시할 수 있는 모든 위치와 같은 요소를 나타냅니다. 보안상의 이유로 브라우저 컨텍스트 간의 통신은 출처가 같고 사용되지 않는 한 허용되지 않습니다. 동일한 출처의 두 브라우저 컨텍스트의 경우 해당 URL은 동일한 프로토콜(예: ), 도메인(예: ) 및 포트(예: )를 가져야 합니다.

    * 활용

    모든 탭에서 사용자를 로그인하거나 로그아웃합.

    자산이 업로드되는 시기를 감지하고 모든 페이지에 표시


4. Internationalization API

단순히 웹 페이지의 텍스트를 필요한 언어로 번역하는 것만으로는 날짜, 숫자, 단위 등과 같은 것들이 있기 때문에 해당 언어를 사용하는 사람들이 콘텐츠를 사용할 수 있도록 하는 것만으로는 충분하지 않습니다. 국가마다 다르며 변경될 수 있습니다.

const logDate = (locale) => {
const newDate = new Date("2022-10-24"); // YY/MM/DD
const dateTime = new Intl.DateTimeFormat(locale, {timeZone: "UTC"});
const formatedDate = dateTime.format(newDate);
console.log(formatedDate);
};
logDate("en-US"); // 10/24/2022
logDate("de-DE"); // 24.10.2022
logDate("zh-TW"); // 2022/10/24

5. Intersection Observer API

The Intersection Observer API is an API provided by modern browsers for monitoring the intersection state of DOM elements. Intersection Observer API, we can easily determine whether an element is entering or leaving the visible area, thus enabling various interactive effects and lazy loading, etc.

* Image lazy loading — where images are loaded only when they are scrolled to visibility.

* Infinite scrolling of content — that is, the user scrolls near the bottom of the content and loads more directly without the user having to turn the page, giving the user the illusion that the page can scroll infinitely.

* Detection of ad exposure — in order to calculate ad revenue, it is necessary to know the exposure of ad elements.

* Execute tasks or play animations when the user sees a certain area.

// Target elements
const targetElement = document.querySelector(".target");

// Create Intersection Observer
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
console.log("The target element enters the visible area.");
} else {
console.log("The target element leaves the visible area.");
}
});
},
{
root: null,
rootMargin: "0px",
threshold: 0.5,
}
);
// Start observing the target element
observer.observe(targetElement);

In this example, a target element is first selected using the method. Then an instance of Intersection Observer is created and a callback function is passed in that will be triggered when the target element enters or leaves the visible area.querySelector

Finally, the observation of the target element is started by calling the method. When the target element enters or leaves the visible area, the corresponding code in the callback function will be executed and the corresponding message will be printed to the console.observe


The following is a description of the parameters of the Intersection Observer API:

1.callback

Callback function for specifying an observer that is triggered when a target element enters or leaves an intersection.

The callback function takes one argument, the array, which contains one or more IntersectionObserverEntry objects, each representing the intersection state of a target element.entries

2.options

root: specifies the root element, the ancestor of the target element whose intersection state will be observed, the default is the viewport.

rootMargin: specifies the root element's boundary offset, which is used to expand or reduce the size of the intersection area.

threshold: specifies a threshold or an array of thresholds indicating the percentage of visibility of the target element to be used to trigger the callback function. For example, 0.5 means that the callback is triggered when the target element is at least half visible.

<img data-src="image.jpg" />

<script>
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll("img").forEach((img) => {
observer.observe(img);
});
</script>

In this example, we add a attribute to the image element to store the image's real address. Then a new IntersectionObserver instance is created to watch all the image elements. When an image element enters the visible area, we assign the attribute to the attribute, thus enabling lazy loading of images.data-srcdata-srcsrc


Infinite scrolling is a common UI design that allows users to load infinitely more content as they scroll. We can achieve infinite scrolling by listening to whether the last element enters the visible area or not.

<div id="content">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<!-- ... -->
<div class="item">Item N</div>
</div>

<script>
const content = document.getElementById("content");
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting && entry.target === content.lastElementChild) {
// Load more content
}
});
},
{
root: null,
rootMargin: "0px",
threshold: 1.0,
}
);
observer.observe(content.lastElementChild);
</script>

In the above code, we add an IntersectionObserver instance to the last element, so that we can trigger the load more content action when the last element enters the visible area.


By listening to whether an element enters or leaves the viewable area, we can achieve some interesting effects, such as following the navigation bar.

<header>
<!-- Navigation bar -->
</header>
<section class="content">
<!-- Page content -->
</section>
<script>
const header = document.querySelector("header");
const content = document.querySelector(".content");
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
header.classList.add("fixed");
} else {
header.classList.remove("fixed");
}
});
},
{
root: null,
rootMargin: "-100px",
threshold: 0,
}
);
observer.observe(content);
</script>

In this example, we create an instance of IntersectionObserver to observe the page content elements. When the page content element enters the viewable area, we have the navigation bar fixed at the top of the page. When the page content element leaves the viewable area, we let the navigation bar resume its original position.


Pros and Cons

The benefits of Intersection Observer API include:

Ability to implement various kinds of interactive effects and lazy loading and other functions to improve user experience.

Ability to optimize page performance and avoid unnecessary network requests and calculations.

Disadvantages of Intersection Observer API include:

Poor compatibility, need to use polyfill for compatibility.

May affect page performance and cause browsers to trigger callback functions frequently if too many target elements are listened to.



Enhance Your Mobile Web Pages with 12 JavaScript APIs


Blob API

Blob API는 이진 데이터를 처리하는 데 사용되며 데이터를 Blob 개체로 쉽게 변환하거나 Blob 개체에서 데이터를 읽을 수 있습니다.

// Create a Blob object
const myBlob = new Blob(["Hello, world!"], { type: "text/plain" });
// Read the data of the Blob object
const reader = new FileReader();
reader. addEventListener("loadend", () => {
console.log(reader.result);
});
reader.readAsText(myBlob);


WeakSet

WeakSet은 Set과 비슷하지만 약하게 참조된 개체를 저장할 수 있습니다. 즉, 개체를 가리키는 다른 참조가 없는 경우 WeakSet에서 수동으로 제거할 필요 없이 가비지 수집기에서 개체를 회수할 수 있습니다.

const myWeakSet = new WeakSet();
const obj1 = {};
const obj2 = {};
myWeakSet.add(obj1);
myWeakSet.add(obj2);
console.log(myWeakSet.has(obj1)); // true
obj1 = null;
console.log(myWeakSet.has(obj1)); // false

사용 시나리오: 경우에 따라 일부 임시 개체를 저장해야 할 수 있지만 이러한 개체가 너무 많은 메모리를 차지하지 않도록 합니다. 이러한 개체는 WeakSet을 사용하여 쉽게 관리할 수 있습니다.


TextEncoder 및 TextDecoder

TextEncoder 및 TextDecoder는 문자열과 바이트 시퀀스 간의 변환을 처리하는 데 사용됩니다. 문자열을 바이트 시퀀스로 인코딩하거나 바이트 시퀀스를 문자열로 디코딩하는 데 편리합니다.

const encoder = new TextEncoder();
const decoder = new TextDecoder();
const myString = "Hello, world!";
const myBuffer = encoder.encode(myString);
console.log(myBuffer); // Uint8Array(13) [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]
const decodedString = decoder.decode(myBuffer);
console.log(decodedString); // "Hello, world!"

사용 시나리오: 웹 응용 프로그램에서는 문자열을 이진 데이터로 변환하거나 이진 데이터를 문자열로 변환해야 할 수 있습니다. 이러한 변환은 TextEncoder 및 TextDecoder를 사용하여 편리하게 수행됩니다.


Proxy API

프록시 API를 사용하여 개체 속성 읽기 및 할당과 같은 작업을 가로챌 수 있는 프록시 개체를 만들 수 있습니다. 이 함수는 메타프로그래밍 및 데이터 하이재킹과 같은 기능을 구현하는 데 사용할 수 있습니다.

const myObject = {
name: "John",
age: 30,
};
const myProxy = new Proxy(myObject, {
get(target, property) {
console.log(`Getting property ${property}`);
return target[property];
},
set(target, property, value) {
console.log(`Setting property ${property} to ${value}`);
target[property] = value;
},
});
console.log(myProxy.name); // "John"
myProxy.age = 31; // Setting property age to 31

사용 시나리오: 경우에 따라 고급 기능을 달성하기 위해 개체 속성 읽기 및 할당과 같은 작업을 가로채야 할 수 있습니다. 이러한 기능은 프록시 API를 사용하여 쉽게 구현할 수 있습니다.


Object.entries() 및 Object.values()

Object.entries()는 객체의 열거 가능한 속성 및 값의 배열을 가져오는 데 사용되며 Object.values()는 객체의 열거 가능한 속성 값의 배열을 가져오는 데 사용됩니다.

const myObject = {
name: "John",
age: 30,
};
console.log(Object.entries(myObject)); // [["name", "John"], ["age", 30]]
console.log(Object.values(myObject)); // ["John", 30]

사용 시나리오: 경우에 따라 개체의 열거 가능한 속성 또는 속성 값을 가져와야 할 수 있습니다. 이러한 함수는 Object.entries() 및 Object.values()를 사용하여 쉽게 구현할 수 있습니다.


IntersectionObserver (교차 관찰자)

IntersectionObserver는 요소가 뷰포트에 들어오는지 여부를 감지하는 데 사용할 수 있으며 무한 스크롤 및 지연 로드와 같은 기능을 구현하는 데 사용할 수 있습니다.

Observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
console.log(`${entry.target.id} is now visible`);
observer.unobserve(entry.target);
}
});
});
const myElement = document.getElementById("myElement");
myObserver.observe(myElement);

사용 시나리오: 웹 응용 프로그램에서는 무한 스크롤 및 지연 로딩과 같은 기능을 구현해야 할 수 있으며 이러한 기능은 IntersectionObserver를 사용하여 쉽게 실현할 수 있습니다.


Symbol

Symbol은 고유 식별자를 만드는 데 사용할 수 있으며 개체의 개인 속성 또는 메서드를 정의하는 데 사용할 수 있습니다.

const mySymbol = Symbol("mySymbol");
const myObject = {
[mySymbol]: "This is a private property",
publicProperty: "This is a public property",
};
console.log(myObject[mySymbol]); // "This is a private property"
console.log(myObject.publicProperty); // "This is a public property"

사용 시나리오: 경우에 따라 개체의 개인 속성 또는 메서드를 정의해야 할 수 있으며, 이는 Symbol을 사용하여 쉽게 실현할 수 있습니다.


Reflect 

Reflect API는 동적으로 메서드 또는 객체 생성자를 호출하는 것과 같은 메타 프로그래밍을 구현하는 데 사용할 수 있습니다.

class MyClass {
constructor(value) {
this.value = value;
}
getValue() {
return this.value;
}
}
const myObject = Reflect.construct(MyClass, ["Hello, world!"]);
const myMethod = Reflect.get(myObject, "getValue");
const myValue = myMethod.call(myObject);
console.log(myValue); // "Hello, world!"

사용 시나리오: 경우에 따라 개체의 메서드 또는 생성자를 동적으로 호출해야 할 수 있으며, 이는 Reflect API를 사용하여 쉽게 실현할 수 있습니다.


 Generator API

생성기 API는 비동기 작업 또는 지연 계산을 구현하는 데 사용할 수 있는 반복자를 생성하는 데 사용할 수 있습니다.

function* myGenerator() {
yield "Hello";
yield "world";
yield "!";
}
const myIterator = myGenerator();
console.log(myIterator.next().value); // "Hello"
console.log(myIterator.next().value); // "world"
console.log(myIterator.next().value); // "!"

사용 시나리오: 경우에 따라 비동기 작업 또는 지연 계산을 구현해야 할 수 있으며 이러한 함수는 생성기 API를 사용하여 쉽게 구현할 수 있습니다.


Web Workers

웹 작업자는 백그라운드 스레드에서 JavaScript 코드를 실행하는 데 사용할 수 있으며, 이를 사용하여 성능을 향상시키거나 복잡한 계산을 구현할 수 있습니다.


// main.js
const myWorker = new Worker("worker.js");
myWorker.postMessage("Hello, worker!");
myWorker.onmessage = (event) => {
console.log(`Message received from worker: ${event.data}`);
};
// worker.js
onmessage = (event) => {
console.log(`Message received in worker: ${event.data}`);
postMessage("Hello, main!");
};

사용 시나리오: 웹 응용 프로그램에서는 계산 집약적인 작업을 많이 처리하거나 장기 실행 작업을 수행해야 할 수 있습니다. 웹 작업자를 사용하면 성능이 향상되거나 사용자 인터페이스 차단을 방지할 수 있습니다.


AudioContext

AudioContext는 오디오를 처리하는 데 사용할 수 있으며 오디오 재생 및 음향 효과 처리와 같은 함수를 구현하는 데 사용할 수 있습니다.

const audioContext = new AudioContext();
fetch("https://example.com/audio.mp3")
.then((response) => response.arrayBuffer())
.then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer))
.then((audioBuffer) => {
const source = audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioContext.destination);
source.start();
});

사용 시나리오: 웹 응용 프로그램에서는 오디오 재생 및 음향 효과 처리와 같은 기능을 구현해야 할 수 있으며 이러한 기능은 AudioContext를 사용하여 쉽게 실현할 수 있습니다.