WEB JS

Seung jun Cha·2024년 8월 12일
0

1. window.onload

  • HTML은 인터프리터 언어적 특성을 가지기 때문에 자바스크립트 태그를 문서의 뒤로 옮겨야 하는데, html 코드가 길어지고 자바스크립트가 아래쪽에 놓여있다면 휠을 내리기도 귀찮고 보기에도 안좋다.
  • 자바스크립트가 문서가 준비된 상황 이후에 발동하도록만 한다면 문서 앞에 선언해도 상관 없어지는데, 바로 이런 것을 해주는 것이 window.onload() 메소드 인 것이다.
  • 웹브라우저 자체를 담당하는 window라는 객체가 웹 문서를 불러올때 문서가 사용되는 시점에 실행되는 onload 라는 함수를 내가 다시 재정의 한다는 개념이다.
  • 해당 함수 내의 코드 스크립트는 웹브라우저 내의 모든 요소가 준비가 되어야 실행이 되도록 할수 있다.
<html>
    <body>
        <script>
            window.onload = function() {
                let a = document.getElementById('name');
                a.style.color = "blue"
            }
        </script>
        
        <p id="name">hello</p>
    </body>
</html>

2. window.open (새창 열기)

  • 웹브라우저에서 새창(팝업창)을 열기 위해서 가장 간단히 사용할 수 있는 방법이다.
var popup = window.open(url, name, option);
  • url : 새창(팝업창)에 보여질 주소 다. 선택적인 값으로 비워두면 빈창(about:blank)이 보이게 된다.

  • name :새로 열릴 창의 속성 또는 창의 이름을 지정한다. 다음 속성들을 지정해 넣으면 된다.
    1. _blank : 새 창으로 연다. (기본값)
    2. _parent : 부모 프레임에 열린다.
    3. _self : 현재 페이지를 대체한다.
    4. _top : 로드된 프레임셋을 대체한다.
    5. name(임의의 이름) : 새 창이 열리고 창의 이름을 지정한다. 동일한 이름에 다시 open() 을 하면 기존의 열린창의 내용이 바뀐다. 다른 이름을 사용하면 또다른 새창이 열린다.

  • option

    • fullscreen : 팝업 전체화면 출력 여부 ( IE에서만 작동 )
    • toolbar : 상단 도구창 출력 여부 ( IE, FireFox 에서만 작동 )
    • location : 메뉴 아이콘 출력여부 ( Opera 에서만 작동 )
    • resizeable : 팝업창 리사이즈 가능여부 ( 크롬에서는 작동 안함)
    • scrollbars : 팝업 스크롤바 사용 여부
    • menubar : 메뉴 출력 여부
    • width : 팝업창의 가로 길이 
    • height : 팝업창의 세로 길이
    • top : 창의 화면 위에서부터의 팝업 위치 지정
    • left : 창의 화면 왼쪽에서부터의 팝업 위치 지정
//속성 지정하지 않은 기본창
window.open("http://eschyles.mireene.com/", "", "");  

//메뉴바 없는 팝업
window.open("http://eschyles.mireene.com/", "", "menubar=1");  

//풀스크린 방식
window.open("http://eschyles.mireene.com/", "", "fullscreen"); 

//채널모드
window.open("http://eschyles.mireene.com/", "", "channelmode"); 

// 상태표시바 있는 팝업
window.open("http://eschyles.mireene.com/", "", "width=400, height=300, status=1");

//크기 width400 height300 팝업창
window.open("http://eschyles.mireene.com/", "", "width=400, height=300");

//위치 left=500, top=400 에서 열리는 팝업창
window.open("http://eschyles.mireene.com/", "", "width=400, height=300, left=500, top=400");

//스크롤바 있는 팝업
window.open("http://eschyles.mireene.com/", "", "width=400, height=300,  scrollbars=1");

//주소표시줄 있는 팝업
window.open("http://eschyles.mireene.com/", "", "width=400, height=300, left=100, location=1");

// 창 컨트롤 모두 활성 화
window.open("/popup.html", "_blank", "toolbar=yes,scrollbars=yes,resizable=yes,top=500,left=500,width=400,height=400");

2-1 window.open 반환값

var popup = window.open('팝업주소', '팝업창 이름', '팝업창 설정'); 
popup.close(); // 열었던 새창 닫기

2-2 window.open url 주소 유의사항

  • 넘겨줄 url에 GET형식의 변수를 넘겨줄때 유의사항이 있다. url은 [ 나 ] 같은 특수문자는 반드시 인코딩 해야되기 때문이다. 그래야 브라우저 측에서 디코딩하여 사용할 수 있다.
  • :, /, ?, &, = 등은 인코딩하지 않지만,
    공백, #, @, [, ], !, $, ', (, ), *, +, ,, ;, = 등은 인코딩한다
var uri = 'http://localhost:8080/viewer.html?key1=123123&key2=[1][2]';
var res1 = encodeURI(uri); // url문자를 반드시 먼저 인코딩한다.
window.open(res1, '', 'width=900,height=800');

3 DOM(문서 객체 모델) 다루기

DOM(문서 객체 모델) 다루기 문법 💯 총정리

4 브라우저 이벤트 종류 & 사용법 총정리

  • 사용자가 버튼을 누르거나, 클릭했을 때, 이벤트 핸들러가 그에 맞는 반응을 하도록 하는 것이다.
  1. inline 방식 : 인라인 방식은 이벤트를 이벤트 대상의 태그 속성으로 지정하는 것이다.
<input type="button" onclick="alert('Hello world, ' + this.value);" value="button" />
// >> Hello world button
  1. script탭에서 함수를 만들고, 태그에 지정하는 방식도 있다.
<button onclick="myHandler1(); myHandler2();">Click me</button>

<script>
    function myHandler1() {
      alert('myHandler1');
    }
    function myHandler2() {
      alert('myHandler2');
    }
</script>
  1. addEventListener 방식
<input type="button" id="target1" value="button1" />
<input type="button" id="target2" value="button2" />

<script>
    var t1 = document.getElementById('target1');
    var t2 = document.getElementById('target2');
    function btn_listener(event){
        switch(event.target.id){
            case 'target1':
                alert(1);
                break;
            case 'target2':
                alert(2);
                break;
        }
    }
    t1.addEventListener('click', btn_listener); // btn_listener()가 아니다.
    t2.addEventListener('click', "btn_listener()"); // btn_listener()를 쓰려면 문자열로 감싼다.
    btn_listener()로 쓰면 함수자체를 쓰는게 아니라 리턴값을 받게된다.
</script>
  • 이벤트 핸들러는 콜백 함수이지만 이벤트 핸들러 내부의 this는 이벤트 리스너에 바인딩된 요소(currentTarget)를 가리킨다.
<button class="btn">Button</button>

<script>
    const btn = document.querySelector('.btn');

    btn.addEventListener('click', function (e) {
      console.log(this); // <button id="btn">Button</button>
      console.log(e.currentTarget); // <button id="btn">Button</button>
      console.log(this === e.currentTarget); // true
    });
</script>

5 Event 객체

  • event 객체는 이벤트를 발생시킨 요소와 발생한 이벤트에 대한 유용한 정보를 제공한다.
  • 이벤트가 발생하면 event 객체는 동적으로 생성되며 이벤트를 처리할 수 있는 이벤트 핸들러에 인자로 전달된다.
  • event 객체는 이벤트 핸들러에 암묵적으로 전달된다. 그러나 이벤트 핸들러를 선언할 때, event 객체를 전달받을 첫번째 매개변수를 명시적으로 선언하여야 한다.
<!DOCTYPE html>
<html>
<body>
  <p>클릭하세요. 클릭한 곳의 좌표가 표시됩니다.</p>
  <em class="message"></em>
  
  <script>
  function showCoords(e) { // e: event object
    const msg = document.querySelector('.message');
    msg.innerHTML =
      'clientX value: ' + e.clientX + '<br>' +
      'clientY value: ' + e.clientY;
  }
  addEventListener('click', showCoords); // 참조하는게 없으면 기본 window 전역 객체
  </script>
</body>
</html>
  1. 사용자가 페이지를 클릭하면 click 이벤트가 발생하고, 브라우저는 showCoords 함수에 event 객체를 전달합니다.
  2. showCoords 함수는 event 객체(e)를 사용하여 클릭된 위치의 X, Y 좌표를 가져옵니다.
  3. document.querySelector('.message')로 em.message 요소를 찾아, 클릭 위치의 좌표를 그 요소에 출력합니다.

5-1 Event 객체 속성 종류

  1. Event.target : 실제로 이벤트를 발생시킨 요소를 가리킨다.
  2. Event.currentTarget : 이벤트에 바인딩된 DOM 요소를 가리킨다. 즉, addEventListener 앞에 기술된 객체를 가리킨다. 따라서 이벤트 핸들러 함수 내에서 currentTarget과 this는 언제나 일치한다.
<div>
    <button>배경색 변경</button>
</div>
document.querySelector('div').addEventListener('click', function() {

      // this: 이벤트에 바인딩된 DOM 요소(div 요소)
      console.log('this: ', this);
      
      // target: 실제로 이벤트를 발생시킨 요소(button 요소 또는 div 요소)
      console.log('e.target:', e.target);
      
      // currentTarget: 이벤트에 바인딩된 DOM 요소(div 요소)
      console.log('e.currentTarget: ', e.currentTarget);
});

5-2 Event Delegation (이벤트 위임)

  • 모든 li 요소가 클릭 이벤트에 반응하는 처리를 구현하고 싶은 경우, li 요소에 이벤트 핸들러를 바인딩하면 총 6개의 이벤트 핸들러를 바인딩하여야 한다.
<ul id="post-list">
  <li id="post-1">Item 1</li>
  <li id="post-2">Item 2</li>
  <li id="post-3">Item 3</li>
  <li id="post-4">Item 4</li>
  <li id="post-5">Item 5</li>
  <li id="post-6">Item 6</li>
</ul>
function printId() {
  console.log(this.id);
}

document.querySelector('#post-1').addEventListener('click', printId);
document.querySelector('#post-2').addEventListener('click', printId);
document.querySelector('#post-3').addEventListener('click', printId);
document.querySelector('#post-4').addEventListener('click', printId);
document.querySelector('#post-5').addEventListener('click', printId);
document.querySelector('#post-6').addEventListener('click', printId);
  • 이벤트 위임은 다수의 자식 요소에 각각 이벤트 핸들러를 바인딩하는 대신 하나의 부모 요소에 이벤트 핸들러를 바인딩하는 방법이다.
const msg = document.querySelector('.msg');
const list = document.querySelector('ul#post-list')

list.addEventListener('click', function (e) {

  // 이벤트를 발생시킨 요소
  console.log('[target]: ' + e.target);
  // 이벤트를 발생시킨 요소의 nodeName
  console.log('[target.nodeName]: ' + e.target.nodeName);

  // li 요소 이외의 요소에서 발생한 이벤트는 대응하지 않는다.
  if (e.target && e.target.nodeName === 'LI') {
    msg.innerHTML = 'li#' + e.target.id + ' was clicked!';
  }
});

5-3 이벤트 기본 동작 취소

  • 이 방식에서는 이벤트 객체의 e.preventDefault() 메소드를 실행하면 기본 동작이 취소된다.

  • 이 체크박스는 이벤트의 기본 동작을 취소할지를 결정하는 역할을 합니다. 체크박스가 체크되어 있으면 기본 동작이 취소됩니다.

<p>
    <label>prevent event on</label>
    <input id="prevent" type="checkbox" name="eventprevent" value="on" />
    체크박스에서의 value: 체크박스는 사용자가 선택했는지 여부를 나타내며, 
    선택되었을 때만 값을 서버로 전송합니다.
</p>
<p>
    <a href="http://opentutorials.org">opentutorials</a>
</p>
<p>
    <form action="http://opentutorials.org">
        <input type="submit" />
    </form>
</p>
document.querySelector('a').addEventListener('click', function(e){
    if(document.getElementById('prevent').checked) 
        e.preventDefault(); // 링크 동작 금지
});

document.querySelector('form').addEventListener('submit', function(e){
    if(document.getElementById('prevent').checked) 
        e.preventDefault(); // 폼 submit(페이지갱신) 동작 금지
});

브라우저 이벤트 종류 & 사용법 총정리

6 XMLHttpRequest 으로 AJAX 요청하기

  • Ajax는 웹 페이지 전체를 다시 로딩하지 않고도, 웹 페이지의 일부분만을 갱신할 수 있게 해준다. Ajax를 이용하면 백그라운드 영역에서 서버와 통신하여, 그 결과를 웹 페이지의 일부분에만 표시할 수 있다.

7 AJAX

  • AJAX는 비동기 방식으로 데이터를 주고받을 수 있습니다. 즉, 페이지가 로드된 후에도 백그라운드에서 서버와 통신할 수 있습니다. 이로 인해 사용자 인터페이스가 부드럽게 유지됩니다.

  • 전체 페이지를 새로 고치지 않고도 페이지의 일부를 업데이트할 수 있습니다. 예를 들어, 사용자가 버튼을 클릭했을 때 페이지의 일부만 변경될 수 있습니다.

  • AJAX는 서버에 요청을 보내고, 서버로부터 응답을 받아 페이지의 내용을 업데이트합니다. 이때 사용되는 데이터 형식으로는 XML, JSON, HTML, 또는 텍스트 등이 있습니다. JSON은 가장 일반적으로 사용됩니다.

7-1 Fetch API 으로 AJAX 요청하기

  • 정통적으로 XMLHttpRequest() 객체를 생성하여 요청하는 방법이 있지만 문법이 난해하고 가독성도 좋지 않다.
  • fetch API는 Promise 기반으로 구성되어 있어 비동기 처리 프로그래밍 방식에 잘 맞는 형태이다.
fetch("https://jsonplaceholder.typicode.com/posts", option)
   .then(res => res.text())
   .then(text => console.log(text));

/* 'fetch('서버주소')' 는 웹 브라우저에게 '이 서버주소로 요청해줘' 라는 의미이고, 
뒤에 .then이 붙으면 '요청 끝나고나서 이 할일을 해줘!' 라는 것이다. */


7-1-1 fetch - GET Method

  • fetch함수는 디폴트로 GET 방식으로 작동하고, 옵션 인자가 필요 없음.
  • 응답(response) 객체는 json() 메서드를 제공하고, 이 메서드를 호출하면 응답(response) 객체로부터 JSON 형태의 데이터를 자바스크립트 객체로 변환하여 얻을 수 있음.
fetch("https://jsonplaceholder.typicode.com/posts/1") // posts의 id 1인 엘리먼트를 가져옴 
  .then((response) => response.json())
  .then((data) => console.log(data))
{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere optio reprehenderit",
  "body": "quia et iet architecto"
}

7-1-2 fetch - POST Method

  • headers 옵션으로 JSON 포맷 사용한다고 알려줘야 함. body 옵션에는 요청 데이터를 JSON 포맷으로 넣어줌.
fetch("https://jsonplaceholder.typicode.com/posts", {
  method: "POST", // POST
  headers: { // 헤더 조작
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ // 자바스크립트 객체를 json화 한다.
    title: "Test",
    body: "I am testing!",
    userId: 1,
  }),
})
  .then((response) => response.json())
  .then((data) => console.log(data))

7-1-3 fetch - DELETE Method

  • 보낼 데이터가 없기 때문에 headers, body 옵션이 필요없음
fetch("https://jsonplaceholder.typicode.com/posts/1", {
  method: "DELETE",
})
  .then((response) => response.json())
  .then((data) => console.log(data))

7-2 fetch의 response 속성

  • fetch를 통해 요청을 하고 서버로부터 값을 응답 받으면 then을 통해 함수의 인자에 담기게 되는데 이 값은 Response객체로서 여러가지 정보를 담고 있다.
  • 응답 자료 형태 반환 메서드는 한번만 사용 할 수 있다. 만일 response.text()를 사용해 응답을 얻었다면 본문의 콘텐츠는 모두 처리 된 상태이기 때문에 뒤에 또 response.json() 써줘도 동작하지 않게 된다.

7-3 Fetch - async / await 문법

  • fetch의 리턴값 response는 Promise객체이다. async/await는 ES2017에 도입된 문법으로서, Promise 로직을 더 쉽고 간결하게 사용할 수 있게 해준다.
  • function 키워드 앞에 async 만 붙여주면 되고, 비동기로 처리되는 부분 앞에 await 만 붙여주면 된다.
  • async function에서 어떤 값을 리턴하든 무조건 프로미스 객체로 감싸져 반환된다.

7-3-1 await 키워드

  • await 키워드는 promise.then() 보다 좀 더 세련되게 비동기 처리의 결과값을 얻을 수 있도록 해주는 문법이라고 보면 된다.
  • await는 키워드 이름에서 보듯이 Promise 비동기 처리가 완료될때까지 코드 실행을 일시 중지하고 wait 한다라는 뜻으로 보면 된다.
async function getData() {
  const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
  const data = await response.json();
  console.log(data):
}

fetch('https://jsonplaceholder.typicode.com/users/1'); 로 데이터를 가져올 때까지 기다린다.

7-3 async / await 함정과 병렬처리

  • 비동기 프로그래밍은 웹에서 메인 스레드를 차단하지 않고 시간 소모적인 작업을 병렬적으로 수행할 수 있도록 하는 웹 개발의 필수적인 부분이다. 하지만 잘못 사용하면 병렬적으로 멀티로 처리할 수 있는 작업을 억지로 동기적으로 처리하게해서 속도가 더 느려질 수 있다.

  • 사과와 바나나를 출력하는데 순서가 상관없다면 아래의 코드는 비효율적이다.

async function getFruites() {
  let a = await getApple(); // getApple() 비동기 처리를 요청하고, 요청이 처리될때 까지 기다림 (1초 소요)
  let b = await getBanana(); // getBanana() 비동기 처리를 요청하고, 요청이 처리될때 까지 기다림 (1초 소요)
  console.log(`${a} and ${b}`); // 총 2초 소요
}
  • 이런 경우 비동기처리요청과 값을 await 하는 로직을 분리시키면 된다. 두 비동기 작업이 서로 독립적이어야만 병렬로 실행할 수 있다.
async function getFruites(){

  let getApplePromise = getApple(); // async함수를 미리 논블록킹으로 실행한다. 
  let getBananaPromise = getBanana(); // async함수를 미리 논블록킹으로 실행한다. 
  
  // 이렇게 하면 각각 백단에서 독립적으로 거의 동시에 실행되게 된다.
  console.log(getApplePromise)
  console.log(getBananaPromise)
  
  let a = await getApplePromise; // getApple의 결과를 기다림
  let b = await getBananaPromise; // getBanana의 결과를 기다림
  
  console.log(`${a} and ${b}`); // 본래라면 1초+1초 를 기다려야 하는데, 위에서 1초기다리는 함수를 바로 연속으로 비동기로 불려왔기 때문에, 대충 1.01초만 기다리면 처리된다.
})
  • Promise.all 메소드 : 또다른 방법으론 Promise.all() 정적 메서드를 사용하는 방법이 있다. 위와 같이 구성할 경우 비동기 처리 완료 시점을 가늠하기 힘들기 때문에 대부분의 실무에선 Promise.all()로 처리한다.

  • Promise.all() 은 배열 인자의 각 프로미스 비동기 함수들이 resolve가 모두 되야 결과를 리턴 받는다. 배열인자의 각 프로미스 함수들은 제각각 비동기 논블록킹으로 실행되어 시간을 단축 할 수 있다. 리턴값은 각 프로미스 함수의 반환값들이 배열로 담겨져 있다.

  • 모든 프로미스가 성공적으로 완료되었을 때만 Promise.all이 완료된다. 하나라도 실패하면 전체가 실패로 간주되며, 모든 프로미스가 성공적으로 완료되면, 각 프로미스의 결과를 배열 형태로 받을 수 있다.

  • 프로미스가 완료된 순서와 상관없이 제공된 순서대로 결과를 배열로 반환한다.

function getApple() {
  return new Promise(resolve => setTimeout(() => resolve('Apple'), 1000));
}

function getBanana() {
  return new Promise(resolve => setTimeout(() => resolve('Banana'), 1500));
}

function getOrange() {
  return new Promise(resolve => setTimeout(() => resolve('Orange'), 500));
}

async function getFruits() {
  try {
    // 모든 프로미스를 동시에 실행
    const [apple, banana, orange] = await Promise.all([getApple(), getBanana(), getOrange()]);
    console.log(`${apple}, ${banana}, ${orange}`); // "Apple, Banana, Orange"
  } catch (error) {
    console.error('One of the promises failed:', error);
  }
}

getFruits();

7-4 top-level await

  • 기존에는 await 키워드를 사용하기 위해선 무조건 async function를 정의하고 async 함수를 호출하는 식으로 사용해와야 했다.
(async function func1() {
    const res = await fetch(url); // 요청을 기다림
    const data = await res.json(); // 응답을 JSON으로 파싱
    console.log(data);
})();
  • 이러한 한계점 때문에 추가된 Top-level await 란 async 함수나 모듈 외부에서도 await 키워드를 사용할 수 있게 해주는 편의 기능이다. 이 기능은 ES2022에 추가되었으며, 현재 대부분의 최신 브라우저와 Node.js에서 지원된다.
// Top Level에선 async funciton 정의없이 곧바로 await 키워드 사용이 가능하다
const res = await fetch(url); // 요청을 기다림
const data = await res.json(); // 응답을 JSON으로 파싱
console.log(data);

8 focus / blur 메서드

  • focus() : 해당 요소에 포커스를 부여
  • blur() : 해당 요소에 포커스를 잃음

다음 예제는 엔터를 누르면 focus() 메서드가 실행되어 바로 다음 입력창 요소로 포커싱하여서 연달아 바로바로 입력할수 있게 하는 응용법이다.

<FORM>
  [개인정보 입력]<br>
  이름 : <INPUT id=pname type=text size=10 onkeydown='moveFocus("age")'><br>
  나이 : <INPUT id=age type=text size=10 onkeydown='moveFocus("sex")'><br>
  성별 : <INPUT id=sex type=text size=10 onkeydown='moveFocus("confirm")'>
</FORM>

<script>
    function moveFocus(next) {
      if (event.keyCode == 13) { //엔터누를경우
        document.getElementById(next).focus();//아규먼트id 노드로 이동해서 focus한다
      }
    }
</script>

8-1 현재 포커스된 요소 확인

  • 아래의 코드는 해당 html 부분을 클릭하면 작동한다.
<textarea id='textarea1'>textarea1</textarea>
<textarea id='textarea2'>textarea2</textarea>

<script>
    document.addEventListener("mouseup", (showSelected) => {
      alert(`${document.activeElement.id} 클릭 !!`);
    });
</script>

8-2 자동 포커스

  • autofocus라는 HTML 속성을 요소에 부여하면 페이지가 로드된 후 자동으로 포커싱 된다.
<form action="/examples/media/action_target.php" method="get">
    이름 : <input type="text" name="st_name"><br>
    학번 : <input type="text" name="st_id" autofocus><br> 
    <!-- 페이지가 로드될 때 자동으로 포커스 -->
    학과 : <input type="text" name="department"><br>
    <input type="submit">
</form>

9 Cookie

  • 자바스크립트는 document.cookie 속성을 이용하여 쿠키를 create, delete, read 할 수 있다.

  • document.cookie= 는 getter와 setter같이 동작한다고 이해하면 된다.
    setter를 수행할때 모든 쿠키를 덮어쓰지 않고, 명시된 쿠키인 user의 값만 갱신한다.

// Name이 user고, Value가 John인 쿠키 추가
// document.cookie = 했다고 초기화되는게 아니라, setter처럼 작동하게 된다.
// 그래서 = "user=John"하면 전체가 'user=john'이 되는게 아니라 '+= user=john'이 추가되게 된다.
document.cookie = "user=John";
  • 쿠키의 이름과 값엔 특별한 제약이 없기 때문에 모든 글자가 허용된다. 하지만 유효성을 위해 반드시 내장 함수 encodeURIComponent를 사용하여 이름과 값을 이스케이프 처리해 줘야 하는게 좋다.

9-1-1 read

  • document.cookie는 name=value 쌍으로 구성되어있고, 각 쌍은 ;로 구분한다.
    이때, 쌍 하나는 하나의 독립된 쿠키를 나타낸다. ;을 기준으로 document.cookie의 값을 분리하면 원하는 쿠키를 찾을 수 있다.
var x = document.cookie; // cookie1=value1; cookie2=value2;...

9-1-2 write

  • 쿠키가 이미 존재할 경우, 그 값을 변경하거나 새로운 값을 설정하는 동작을 포함한다.
// Name이 user고, Value가 John인 쿠키 추가
// 그리고 속성값으로 path와 expires를 설정해서 추가
// 이 속성값은 쿠키 스트링에 저장되지는 않고 속성정보에 저장된다.
document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"

9-1-3 create

  • 쿠키가 브라우저에 존재하지 않을 때 새로 생성하는 경우를 의미한다.
// document.cookie = "쿠키이름=쿠키값"
document.cookie = "username = 홍길동";


// 만료기간을 넣어서 쿠키가 자동 만료 되도록 제작할 수 있다.(UTC time을 이용)
document.cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC";


// 파라미터를 이용하여 쿠키가 어디 브라우저에 속할 수 있을지 알려줄 수 있다.
document.cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/";

9-1-4 delete

  • 만료 기간을 과거로 바꾸어 버리면 된다. 단, 쿠키 요소를 삭제할때 반드시 path를 맞춰야 한다. 삭제가 안된다면, 개발자도구에서 쿠키 path를 필히 확인 해 볼것
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";

또는 

// max-age 사용

// 1시간 뒤에 쿠키가 삭제됩니다.
document.cookie = "max-age=3600";

// 만료 기간을 0으로 지정하여 쿠키를 바로 삭제함
document.cookie = "max-age=0";

9-1-5 쿠키의 한계

  • encodeURIComponent로 인코딩한 이후의 name=value 쌍은 4KB를 넘을 수 없다. 이 용량을 넘는 정보는 쿠키에 저장할 수 없다.
  • 도메인 하나당 저장할 수 있는 쿠키의 개수는 20여 개 정도로 한정되어 있다. 개수는 브라우저에 따라 조금씩 다르다.

9-2 쿠키 파라미터

9-2-1 Name 속성과 Value 속성

// Name이 user고, Value가 John인 쿠키 추가
document.cookie = "user=John"

9-2-2 Expires 속성 , max-age 속성

  • Expires 속성에는 GMT 형식이나 UTC 형식으로 날짜를 입력해야 한다.
    파기 날짜를 입력하지 않으면 브라우저가 종료될 때 쿠키가 삭제된다.
document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
  • expires 옵션의 대안으로, 쿠키 만료 기간을 설정할 수 있게 해준다.
    초 단위로 설정된다.
// 1시간 뒤에 쿠키가 삭제됩니다.
document.cookie = "user=John; max-age=3600";

// 만료 기간을 0으로 지정하여 쿠키를 바로 삭제함
document.cookie = "user=John; max-age=0";

9-2-3 Secure 속성

  • Secure 속성을 지정하면 해당 쿠키는 SSL을 사용해서만 요청할 수 있다.
document.cookie = "user=John; Secure"

9-2-4 Domain 속성

  • Domain 속성을 입력하지 않으면 현재 도메인의 경로로 자동 입력된다.
  • 페이지 요청과 비교해서 도메인의 경로와 Domain 속성이 일치하지 않으면, 쿠키에 접근하는 것을 막으므로 Domain 속성은 건드리지 않는다.
// naver.com, www.naver.com, blog.naver.com, cafe.naver.com 서브 도메인도 모두 포함
document.cookie = "user=John; Domain=.naver.com"

9-2-5 Path 속성

  1. Path 속성을 입력하지 않으면 현재 도메인의 경로로 자동 입력된다.
  2. Path 속성은 일부러 지정하는 경우가 많은데 특정 경로(폴더명)를 설정한다.
  3. Path 속성은 /폴더/ 로 설정되는데, 이렇게 설정한 Path 속성이 설정되면 현재 폴더 또는 현재 폴더의 하위에서 접근할 수 있다.
  4. Path 속성을 ' / '로 설정하면 도메인 내의 모든 곳에서 접근할 수 있다. (쿠키의 범위를 좁게 잡을 수록 보안에는 좋다.)
document.cookie = "user=John; path=/"

9-2-6 HttpOnly 속성

  • 쿠키는 클라이언트에서 자바스크립트로 조회할 수 있기 때문에 해커들은 자바스크립로 쿠키를 가로채고자 시도한다.

  • HTTP Only Cookie를 설정하면 브라우저에서 해당 쿠키로 접근할 수 없게 되지만, 쿠키에 포함된 정보의 대부분이 브라우저에서 접근할 필요가 없기 때문에 HTTP Only Cookie는 기본적으로 적용하는 것이 좋다.

document.cookie = "user=John; httpOnly"

9-3 쿠키함수 헬퍼

10 LocalStorage / SessionStorage

  • localStorage

    • 로컬에 도메인 별로 지속되는 storage 
    • localStorage는 시간제한(기간설정)이 없고 브라우저가 꺼져도 죽지 않는다.
      ex) 광고 7일 동안 보지않기 (쿠키를 사용한다)
    • 값을 지우려면 직접 지워줘야한다.
  • sessionStorage

    • 세션이(프로세스, 탭, 브라우저) 종료될 때까지 지속되는 storage 
    • 보통 세션의 종료는 일반적으로 브라우저의 종료를 뜻한다. 그러나 sessionStorage에서 의미하는 세션은 가장 작은 단위인 탭단위를 의미한다. 탭마다 sessionStorage는 따로 배정되며 서로의 영역을 공유하지 않는다. 따라서 값을 침범할 수 도 없다. (아주 작은 단위에서 세션이 나뉨)

10-1 LocalStorage 사용법

  • 데이터 저장
localStorage.test = '123'; // 리터럴 방식

localStorage.setItem('test', '123'); // 메소드 방식

  • 데이터 가져오기
localStorage.test; // 리터럴 방식
localStorage.getItem('test'); // 메소드 방식


localStorage.getItem(); // 인자를 안주면, 전체 값 받아오기
localStorage.length // 항목 갯수 반환
localStorage.key(0); // 인자(인덱스)에 해당하는 key의 value값을 받아온다.
  • 데이터 삭제
localStorage.removeItem('test');
// localStorage 객체에서 원하는 값을 지우는 방법

localStorage.clear();
// 한번에 저장된 모든 값을 삭제하는 방법
  • 키 순회하기 : 스토리지 객체는 iterable 객체가 아니다. 대신 배열처럼 다루면 전체 키-값을 얻을 수 있다.
let keys = Object.keys(localStorage);
for(let key of keys) {
  alert(`${key}: ${localStorage.getItem(key)}`);
}
  • value값을 객체로 이용하기 (불가능) : localStorage의 키와 값은 반드시 문자열이어야 한다.
    숫자나 객체 등 다른 자료형을 사용하게 되면 문자열로 자동 변환된다.
localStorage.user = {name: "John"};
alert(localStorage.user); // [object Object]

단 JSON을 사용하면 객체와 배열을 저장할 수 있다.

localStorage.user = JSON.stringify({name: "John"});

let user = JSON.parse( localStorage.user );
alert( user.name ); // John
let arr = [1,2,3,4,5]
localStorage.setItem("data", JSON.stringify(arr));


let output = localStorage.getItem("data");
let arr = JSON.parse(output);
console.log(arr) // [1,2,3,4,5]

10-2 sessionStorage 사용법

  • 기본적인 문법은 로컬스토리지와 크게 차이가 없다.
sessionStorage.setItem("domain", "webisfree.com");
//&nbsp; domain이란 키(key) 값을 사용하여 해당 텍스트를 저장함

sessionStorage.getItem("domain");
// 키에 저장된 값을 반환. 여기서는 webisfree.com 출력됨

sessionStorage.removeItem("domain");
// domain 키와 데이터 모두 삭제

sessionStorage.clear();
// 저장된 모든 값 삭제

10-3 Storage EVENT

11 URL 객체

  • window.location.href를 통해 url문자열을 얻어와 객체를 만들고 간편하게 사용할수 있게 되었다.
// 사이트 주소 얻기
const link = window.location.href;
// "http://testurl.co.kr:8080/path/main.html?param1=1&param2=3#top"

var url = new URL(link);

/* url 객체 정보 */
{
  protocol: "http:" // 프로토콜
  hostname: "testurl.co.kr"  // 도메인, 아이피
  port: "8080" // 포트
  
  host: "testurl.co.kr:8080" // 서버 주소
  origin: "http://testurl.co.kr:8080" // 프로토콜, 서버이름, 포트 포함
  href: "http://testurl.co.kr:8080/path/main.html?param1=1&param2=3#top" // 전체경로
  
  pathname: "/path/main.html" // 서버 자원 위치
  hash: "top" // #해시 위치 
   
  search: "?param1=1&param2=3" // 쿼리스트링
  searchParams: URLSearchParams {} // 쿼리스트링을 메소드를 통해 모듈화
  
  username: "" // HTTP 인증이있는 경우 속성
  password: "" // HTTP 인증이있는 경우 속성
}

11-1 urlSearchParams.get()

  • : urlSearchParams에 .get('parameterName')은 해당 parameterName으로 조회되는 첫번째 값을 return한다.
const urlStr = 'https://gillog/post/1?tag=javascript&like=backend';
const url = new URL(urlStr);

const urlParams = url.searchParams; 
// URLSearchParams 객체를 넣는다. 그러면 메소드를 사용할수 있게 된다.

const tag = urlParams.get('tag'); // 쿼리스트링에 tag라는 키의 값을 가져온다.
console.log(tag); // javascript

const like = urlParams.get('like');
console.log(like) // backend

11-2 urlSearchParams.keys(), values(), entries()

// 쿼리스트링 부분을 URLSearchParams객체에 바로 줘서 사용할 수도 있다.
const urlParams = new URLSearchParams("?gil=test&log=what&gillog=holy");

const keys = urlParams.keys();
// gil
// log
// gillog

const values = urlParams.values();
// test
// what
// holy

const entries = urlParams.entries();
// gil, test
// log, what
// gillog, holy

11-3 urlSearchParams.has()

const urlParams = new URLSearchParams("?gil=123&log=456&gillog=777");

// true
console.log(urlParams.has("gillog"));

// false
console.log(urlParams.has("loggil"));

11-4 urlSearchParams.append()

let urlParams = new URLSearchParams("?gil=test");

urlParams.append("log", "yes");
urlParams.append("log", "no");

// ?gil=test&log=yes&log=no
console.log(urlParams);

11-5 urlSearchParams.set()

  • parameter의 value값을 변경. 만약 존재하지 않는 parameterName이라면 append 된다.
let urlParams = new URLSearchParams("?gil=test&log=yes&log=no");

urlParams.set("gil", "yes");
urlParams.set("log", "wow");
urlParams.set("gillog", "good");

// ?gil=yes&log=wow&gillog=good
console.log(urlParams);

11-6 urlSearchParams.delete()

url.searchParams.delete("param1")

12 Form 검증 API

  • HTML5의 폼 유효성 검사 API는 웹 폼에서 사용자 입력을 검증할 수 있는 다양한 메소드를 제공한다.

12-1 setCustomValidity(message)

  • 빈 문자열을 설정하면 커스텀 유효성 검사가 제거된다.
element.setCustomValidity('Custom error message');

ex)
var password = document.getElementById("password")
  ,confirm_password = document.getElementById("confirm_password");

function validatePassword(){
  if(password.value != confirm_password.value) { // 만일 두 인풋 필드값이 같지 않을 경우
    // setCustomValidity의 값을 지정해 무조건 경고 표시가 나게 하고
    confirm_password.setCustomValidity("Passwords Don't Match"); 
  } 
  else { // 만일 두 인풋 필드값이 같을 경우
    // 오류가 없으면 메시지를 빈 문자열로 설정해야한다. 오류 메시지가 비어 있지 않은 한 양식은 유효성 검사를 통과하지 않고 제출되지 않는다.
    // 따라서 빈값을 주어 submit 처리되게 한다
    confirm_password.setCustomValidity(''); 
  }
}

password.onchange = validatePassword;
confirm_password.onkeyup = validatePassword;

12-2 reportValidity()

  • 이 메소드는 checkValidity()와 유사하지만, 오류 메시지를 사용자에게 즉시 표시한다.
var isValid = element.reportValidity();

12-3 willValidate()

  • willValidate는 입력 필드의 required, minlength, maxlength, pattern, type 속성 등을 고려하여 필드가 유효성 검사를 수행할지 여부를 알려준다. 특정 조건에서 유효성 검사 로직을 동적으로 적용할 때 유용하다.
var willValidate = element.willValidate;


<!DOCTYPE html>
<html>
<head>
  <title>willValidate Example</title>
</head>
<body>
  <form id="myForm">
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required>
    <br>
    <label for="phone">Phone (Optional):</label>
    <input type="tel" id="phone" name="phone">
    <br>
    <button type="submit">Submit</button>
  </form>

  <script>
    var emailField = document.getElementById('email');
    var phoneField = document.getElementById('phone');

    console.log('Email field will validate:', emailField.willValidate); // true, because 'required' is set
    console.log('Phone field will validate:', phoneField.willValidate); // false, because 'required' is not set

    // Adding 'required' to phone field to check willValidate again
    phoneField.required = true;

    console.log('Phone field will validate after adding required:', phoneField.willValidate); // true, because 'required' is now set
  </script>
</body>
</html>

13 image 객체

-참고
https://inpa.tistory.com/ (이 글의 거의 모든 내용)

0개의 댓글