const tagAreaOffsetTop = tagArea.current?.offsetTop; //태그 영역 위 높이
    const topAreaClientHeight = topArea.current?.clientHeight; // 보이는 영역 높이
    const topAreaScrollTop = topArea.current?.scrollTop; // 현재 스크롤 높이

 

 

https://ko.javascript.info/size-and-scroll

 

 

 

 

색상 정의

 

styles > theme.ts

import { DefaultTheme } from 'styled-components';

/**
 * @name 기본색상 선언
 */
const colors = {
  black: '#000',
  white: '#fff',
};

export type ColorsTypes = typeof colors;

export const theme: DefaultTheme = {
  colors,
};

 

 

index.tsx

import { ThemeProvider } from 'styled-components';
import { theme } from './styles/theme';

root.render(
  <ThemeProvider theme={theme}>
    <App />
  </ThemeProvider>
);

'기본 > html&css' 카테고리의 다른 글

autoFill custom하기  (0) 2024.08.23
transition(고급 css)  (0) 2022.11.16
variable (Custom Property) - 나만의 색 변수로 저장하기  (0) 2022.11.16
focus-within  (0) 2022.11.16
Pseudo selectors & Attribute selectors & Combinators  (0) 2022.11.16

설명

history API는 브라우저의 세션 기록을 조작할 수 있는 메소드를 담고 있는 객체입니다. 기본적으로 뒤로가기, 앞으로 가기, 페이지 이동 등을 조작할 수 있으며 SPA와 관련하여 html5에서 새롭게 추가된 메소드를 알아보도록 하겠습니다.

 

1. history.back()

해당 메소드는 브라우저에서 뒤로가기 버튼을 클릭 한 것과 같은 기능입니다.

history.back()

 

2.history.forward()

뒤로 갈 수 있다면 앞으로도 갈 수 있어야겠죠? 앞으로 가기 버튼과 같은 기능입니다.

history.forward()

 

 

3. history.go()

해당 메소드는 원하는 위치로 페이지를 이동 시킬 수가 있습니다. 인자값으로는 이동 할만큼 숫자를 넣어주면 됩니다. 페이지가 이동 되는 기준은 현재페이지 부터 양수를 넣으면 앞으로 음수를 넣으면 뒤로 페이지가 이동됩니다.

// 인자값이 없거나 0을 넣으면 페이지가 새로고침 됩니다.
history.go()
history.go(0)

// 뒤로 가기
history.go(-1)

// 앞으로 가기
history.go(1)

 

 

 

이제부터 html5에 새로 추가된 url 변경 메소드입니다.

istory.pushState({데이터 객체}, 페이지 제목 변경, 바꿀 주소)
history.replaceState(동일)

 

해당 메소드를 사용하면 현재 페이지의 url을 변경할 수 있으며 페이지가 갱신되지는 않지만 실제로 페이지 이동으로 인식됩니다.

 

1. history.pushState()

history.pushState의 경우 새로운 주소목록을 추가 하기 때문에 이전 url의 주소가 남아있어 브라우저의 뒤로가기 버튼이 활성화 됩니다.

// 현재 url이 test라고 가정 했을 때 
// 이전 url은 test, 현재 url은 test/pushpage로 변경된다.
history.pushState({ data: 'testData1' }, null, '/pushpage')

2. history.replaceState()

history.replaceState는 동일한 기능을 하지만 주소목록에 추가하지 않기 때문에

뒤로가기 버튼이 활성화 되지 않습니다.

// 현재 주소목록만 바뀌기 때문에 test에서 test/replacepage로 바뀌고
// 이전 url인 test은 남지 않는다.
history.replaceState({ data: 'testData2' }, null, '/replacepage')

 

메소드의 파라미터에 대해 설명하면

첫번째 인자는 데이터 객체를 전달 가능하며 history.state에 저장되어 사용할 수 있습니다.

두번째 인자는 해당 페이지의 제목 변경이 가능한데 브라우저에서 기능이 구현되어 있지 않아 null을 전달하면 됩니다.

세번째 인자는 변경할 url 주소를 넣어주면 됩니다. 단순한 경로 이동도 가능하고 querystring도 추가할 수 있기 때문에 유용하게 사용가능 합니다.

history API 메소드를 사용하여 페이지 이동을 한후 기존 데이터를 활용하여 무언가를 하고 싶다면 popstate 이벤트로 확인이 가능합니다. 이벤트는 기존 window.addEventListener로 연결하면 됩니다.

메소드가 실행 할때는 동작하지 않고 브라우저가 뒤로가기, 앞으로 가기를 했을 때 발생합니다. 하지만 history.state에 이전 state가 저장되어 있기 때문에 이전 페이지의 데이터를 다시 활용할 수 있습니다!

 

https://velog.io/@function_dh/HTML5-history-API-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EC%9D%B4%EB%8F%99

React 에서 페이지 전환할때 사용하는 react-router  history.push  통해 마치 SSR 처럼 브라우저 주소를 바꿔주고

동시에 Root 엘리먼트의 내용물도 바꿔준다. 이걸 순수 JS  구현하고자 한다면 history.pushState  사용하면 된다.

 

History.pushState  페이지 이동 없이 주소만 바꿔준다. (브라우저의 뒤로가가 버튼이 활성화 된다.)

브라우저 페이지를 이동하게 되면 window.onpopstate 라는 이벤트가 발생하게 되는데, pushState  했을때는 popstate 이벤트가 발생하지않고,  / 앞으로 가기를 클릭 했을때 popstate 이벤트가 발생하게 된다.

즉, pushState 와 popstate 둘을 이용하여 SPA 의 페이지 전환을 구현할 수 있다.

 

구문

history.pushState(state, title[, url]);

 

state

브라우저 이동 시 넘겨줄 데이터(popstate 에서 받아서 원하는 처리 가능)

 

title

변경할 브라우저 타이틀

 

url

변경할 브라우저 주소

 

 

아래와 같이 함수를 호출하는 버튼이 있습니다.

<button type="button" onclick="testPPP">push 테스트</button>

 

testPPP Function

let testPPP = function() {
	console.log('aaaaaaaaaa');
	history.pushstate({data: 'aaa', page: 'aaaaaa'}), '타이틀이다 우하하하하', 'test/page');
}

 

window.onpopstate Function
* 뒤로가기, 앞으로가기 이벤트를 감지하는 onpopstate 이벤트

window.onpopstate = function(e) { 
    console.log(`${JSON.stringify(e.state)} | ${location.origin} | ${location.pathname}`);
}

 

push 테스트 버튼을 클릭 했을 때 testPPP 함수에서 history.pushState 가 실행된다.

실행된 후 URL 주소를 보면 history.pushState 에 의해 /test/page 로 바뀐다. (localhost:8082/test/page)

같은 페이지이지만 URL 주소만 바뀐걸 확인할 수 있다.

 

뒤로가기 버튼을 클릭해보자

앞으로 가기 버튼도 활성화되며 같은 페이지에서 pushState 하기 전 URL 주소로 돌아간걸 확인할 수 있다. 

(localhost:8082/이전주소url)

 

 

사용하는 이유

사용자가 A 페이지에서 B 화면으로 이동하기 위해선 a 태그 등 여러가지의 방법을 통해

페이지를 이동합니다. URL에 데이터를 저장하기 위해서는 가장 간단한 방법인

document.location.hash 를 사용한 해시태그 사용입니다.

 

해시태그(#) 뒤에 데이터 값을 사용하여 URL에 저장할 수 있습니다.

하지만 # 뒤에 값을 변경하면 히스토리도 같이 변경됩니다.

 

이런 이유로 HTML5에 추가된 history.pushState, history.replaceState 를 이용해

보다 편리하게 history를 관리할 수 있습니다.

document.getElementById('input').addEventListener('change', (e) => {
      const fileReader = new FileReader(); // File 을 읽기 위한 FileReader 객체 생성
      fileReader.readAsDataURL(e.target.files[0]); // Blob -> base64 data로 변환
 
      // 파일 읽기가 완료되었을 때 실행되는 이벤트 핸들러
      fileReader.onload = (e) => {
        let base64data = fileReader.result;
        document.getElementById('previewImg').src = base64data;
      }
    }
)

 

실제 img File의 img를 읽기위해서는 js에서 제공하는 FileReader 라는 객체를 이용해야 하므로 FileReader 객체를 생성하고

readAsDataURL 이라는 메서드를 통해 img File의 data를 base64로 형태로 인코딩하여 읽는다.

해당 작업이 완료되면 fileReader.onload 가 실행되고 base64data 에 img data를 할당하고 base64data를 <img id="previewImg"> 의 src 속성에 넣어주면 된다.

 

여기서 말하는 Base64 인코딩은 아스키코드에서 사용되는 문자64개로 Data를 표현한다고 이해하면 된다. 어떻게 Byte(8bit) 단위의 img Binary data를 나타나는지 궁금했었는데 3개의 byte를 4개의 6bit로 쪼개서 표현한다고 한다.  

문자 => 아스키 코드 번호

문자.charCodeAt();

 

굳이 사용되는 변수명을 "문자"라고 적은 것은 charCodeAt()이 string 타입에만 가능하기 때문이다.

 

"hello".charCodeAt();  // 104
"bye".charCodeAt();  // 98
"World".charCodeAt();  // 87

가장 앞에 있는 문자만 변환되는 것을 알 수 있다.

 

charCodeAt()에는 인자를 넣을 수 있는데, 이 인자가 바로 문자열의 인덱스 번호를 의미한다.
예시로 살펴보자.

"hello".charCodeAt(0);  // 104
"hello".charCodeAt(1);  // 101
"hello".charCodeAt(4);  // 111
"hello".charCodeAt(5);  // NaN
"hello".charCodeAt(-1);  // NaN

인덱스 번호를 인자로 넣어주니, 문자열 내 해당 인덱스에 존재하는 문자가 변환되는 것이 확인된다.
물론, 문자열이 가지고 있는 인덱스 범위를 넘어가면 NaN이 반환된다.

Binary Data

    • 바이너리 데이터는 0과 1로 이루어진 데이터를 말하며, 일반적으로 텍스트 에디터로는 읽을 수 없다.
    • 이러한 데이터는 주로 이미지, 오디오, 비디오, 실행 가능 파일 등에 사용된다.
    • 바이너리 데이터는 문자열로 표현되지 않기 때문에, 통신이나 저장 시 특별한 인코딩 방법이 필요할 수 있다.
    • ex) Base64 인코딩은 바이너리 데이터를 ASCIII 문자열로 변환하는 방법 중 하나이다.

Binary Data와 "문자열 데이터"의 차이점

  • 표현 방식: 문자열 데이터는 텍스트로 표현되며, 바이너리 데이터는 비트로 표현된다.
  • 읽기 가능성: 문자열 데이터는 사람이 읽을 수 있으며, 바이너리 데이터는 일반적으로 사람이 읽을 수 없다.
  • 용도: 문자열 데이터는 주로 텍스트 정보를 저장하거나 전송하는데 사용되며, 바이너리 데이터는 다양한 형태의 미디어나 파일을 저장하거나 전송하는데 사용된다.

 

ASCII 문자 집합

소스 문자 집합은 소스 파일에 나타날 수 있는 올바른 문자 집합입니다.

 

  •  

 

Base64

바이너리 데이터를 64진법 표현으로 변환하여 정해진 ASCII 문자 집합으로 표현하는 바이너리-텍스트 인코딩 체계입니다. 이는 일반적으로 바이너리 데이터를 전송할 수 없는 미디어에서 전송 작업을 할 수 있도록 바이너리 데이터를 문자열로 인코딩하는데 사용됩니다. Base64는 전송 중에 이진 데이터가 손실되지 않도록 합니다.

 

Base64는 암호화나 압축하는 체계가 아닙니다. 그저 네트워크를 통해 난독화된 문자열을 전송할 수 있도록 바이너리 데이터를 ASCII 문자 집합으로 변환합니다. 예를 들면 텍스트 데이터를 받는 이메일 서버에 이미지나 파일을 보내는 경우가 있습니다. 이 때 파일을 텍스트 형식으로 인코딩해야 합니다.


이 글에서는 JavaScript에서 Base64 문자열을 인코딩 및 디코딩 하는 방법을 설명합니다. 원시 바이너리 데이터를 Base64 문자열로 인코딩 및 디코딩하기 위해 JavaScript에서는 두 가지 내장 함수를 지원합니다.

 

 

 

atob() - Base64 Decoding

atob() 메소드(ascii to binary의 약자)는 Base64로 인코딩된 문자열을 일반 문자열로 디코딩합니다. 다음은 atob() 메소드로 Base64 문자열을 디코딩하는 예제입니다.

const encodedStr = "SmF2YVNjcmlwdCBpcyBmdW4hIQ==";

// decode the string
const str = atob(encodedStr);

// print decoded string
console.log(str);

// output: JavaScript is fun!!

 

atob() 메소드는 Base64 문자열이 순수하게 8비트로 이루어진 문자열일때만 완벽하게 작동합니다. 

인코딩된 입력 값이 16비트 유니코드 문자가 포함되어있다면 다음 예제 처럼 제대로 디코딩되지 않습니다.

Blob, Binary Large Object

Blob은 이진 데이터(binary data)를 다룹니다. Blob은 대형 이진 객체(Binary Large Object)를 의미하며 일련의 데이터를 처리하거나 간접 참조하는 객체입니다
Blob은 대개 바이트의 크기를 알아내거나 해당 MIME 타입이 무엇인지 요청하며, 데이터를 작은 Blob으로 잘게 나누는 등의 작업에 사용됩니다

 

"즉, 데이터 자체라기보다는 데이터를 간접적으로 접근하기 위한 객체인 것입니다"

 

Blob은 웹에서 사용되는 데이터 형식으로, 이진 데이터를 나타내며, 텍스트, 이미지, 오디오, 비디오 등 다양한 형식을 지원합니다예를 들면, 이미지나 동영상 같은 큰 파일들을 메모리에 효율적으로 저장하고 전송할 수 있게 해주는 역할을 합니다.

주로 파일 업로드, 이미지 프로세싱, 미디어 처리 등에서 사용됩니다.

 

  • Blob 객체는 읽기 전용입니다.
  • 속성과 메서드를 제공하여, 파일에 대한 작업을 수행할 수 있습니다.
메서드 설명
Blob.slice() Blob의 일부를 잘라내어 새로운 Blob을 생성
Blob.arrayBuffer() Blob을 ArrayBuffer 형식으로 비동기적으로 변환
Blob.text() Blob을 텍스트로 비동기적으로 변환
Blob.stream() Blob을  ReadableStream 형태로 변환
Blob.stream().getReader() ReadableStream으로부터 데이터를 읽을 Reader 객체를 반환

 


arrayBuffer

arrayBuffer는 ArrayBuffer객체를 반환하는 Promise를 반환하는 비동기적인 메서드입니다.

 

 

고정된 길이의 이진 데이터 버퍼

  • ArrayBuffer는 고정된 길이의 이진 데이터 버퍼를 나타내는 JavaScript의 내장 객체입니다.
  • ArrayBuffer의 크기(고정된 길이)는 생성할 때 지정됩니다.
    크기는 바이트 단위로 지정되며, 0 이상의 정수로 설정할 수 있습니다.
    예를 들어, 
    new ArrayBuffer(16)은 16바이트 크기의 ArrayBuffer를 생성합니다.

 

이진 데이터 버퍼

  • 이진 데이터 버퍼는 컴퓨터에서 이진 데이터를 저장하는 메모리의 일부분입니다.
    이진 데이터는 0과 1로 구성된 비트(bit)의 나열로 표현되는 데이터를 말합니다.
  • 컴퓨터에서는 모든 데이터가 이진 형태로 저장되며, 숫자, 문자, 이미지, 오디오, 비디오 등 모든 유형의 데이터가 이진 데이터로 표현됩니다.

사용하는 이유

  1. ArrayBuffer는 일반적으로 이진 데이터를 효율적으로 다루기 위해 사용됩니다.
    • 예를 들어, 이미지, 오디오, 비디오, 파일 등과 같은 바이너리 데이터는 ArrayBuffer를 사용하여 메모리에 할당된 버퍼에 저장됩니다.
      이를 통해 JavaScript는 바이너리 데이터를 처리하고 조작할 수 있습니다.
  2. 파일이나 네트워크 요청 등에서 데이터를 비동기적으로 읽을 때 사용됩니다.
    • 일반적으로 FileReader와 함께 사용되며, 파일을 비동기적으로 읽은 후 ArrayBuffer로 변환하여 다양한 작업을 수행할 수 있습니다. 
      • 이진 데이터:
        • 저장과 처리 목적을 위해 이진 형식으로 인코딩 된 데이터 파일입니다.
        • 숫자, 문자, 이미지, 오디오, 비디오 등 모든 종류의 데이터를 포함할 수 있습니다.
        raw 파일:
        • 특정 파일 형식의 헤더나 압축 등의 처리를 거치지 않고 그대로 저장한 순수한 이진 데이터 파일입니다.
        • 주로 이미지, 오디오, 비디오 등의 바이너리 데이터를 저장하기 위해 사용됩니다.

 

Blob.arrayBuffer()

arrayBuffer는 ArrayBuffer 객체를 반환하는 Promise를 반환합니다.

const buffer = await file.arrayBuffer();

다만 비동기로 받은 ArrayBuffer는 콘솔에서는 확인할 수 없습니다.

 

console에서 arrayBuffer를 확인할 수 없는 이유

콘솔에서 arrayBuffer를 직접 출력하면 예상한 결과가 표시되지 않는 이유는 arrayBuffer가 바이너리 데이터를 포함하는 특수한 형식이기 때문입니다. arrayBuffer는 일련의 바이트로 이루어진 버퍼로서 텍스트로 직접 해석하기 어렵거나 의미가 없는 이진 데이터를 포함할 수 있습니다.

  • reader가 onload된 후, JSON.stringify를 통해 확인할 수 있습니다.
console.log("Buffer Stringify: ", JSON.stringify(unit8Buffer, null, 2));

 


 

Unit8Array

이유 A. 효율적인 메모리 사용

Uint8Array는 8비트 부호 없는 정수 값을 저장하기 위해 1바이트를 사용합니다.
본문 상단에서 정리했던 것과 같이, 다른 TypedArray는 더 큰 크기의 데이터를 저장하기 위해 더 많은 바이트를 사용하는 경우가 있습니다.
따라서, Uint8Array로 메모리 사용을 더 효율적으로 관리할 수 있습니다.

이유 B. 이미지 파일의 픽셀 데이터 표현

대부분의 이미지 파일은 8비트 픽셀 데이터로 구성되어 있습니다.

  • Uint8Array는 8비트 부호 없는 정수를 다루는 TypedArray로서, 이미지 파일의 픽셀 데이터를 표현하기에 적합합니다.
  • 이미지 파일은 픽셀 값들의 배열로 구성되어 있으며, 각 픽셀은 RGB 값(각 색상이 0~255) 또는 RGBA 값으로 표현됩니다.
    Uint8Array는 0부터 255까지의 값을 표현할 수 있기 때문에 픽셀 데이터를 정확하게 표현할 수 있습니다.

 

 

https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-Base64-Blob-ArrayBuffer-File-%EB%8B%A4%EB%A3%A8%EA%B8%B0-%EC%A0%95%EB%A7%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-%EC%89%BD%EA%B2%8C-%EC%84%A4%EB%AA%85#

 

📁 Base64 / Blob / ArrayBuffer / File 다루기 총정리

웹 개발을 진행하다 보면 이진 데이터를 다루어야 할 때를 간혹 마주칠 수 있다. 브라우저에선 주로 파일 생성, 업로드, 다운로드 또는 이미지 처리와 관련이 깊고, 서버 사이드인 node.js 에선 파

inpa.tistory.com

 

+ Recent posts