Key Sequence Detection

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Key Detection</title>
  <script type="text/javascript" src="http://www.cornify.com/js/cornify.js"></script>
</head>
<body>
<script>
</script>
</body>
</html>

목표

누른 키가 콘솔창에 뜨도록 배열로 연결되어 뜨도록 하고, 비밀 키를 입력하면 유니콘이 나오도록 설정

과정

  1. 상수 설정
  2. 이벤트 리스너 생성 및 효과 설정

코드 분석

  1. 상수 설정

     const pressed = [];
     const secretCode = 'wesbos';
    

    빈 배열 pressed와 비밀코드가 담긴 secret을 만든다

  2. 이벤트 리스너 생성 및 효과 설정

     window.addEventListener('keyup', (e) => {
       console.log(e.key);
       pressed.push(e.key);
       pressed.splice(-secretCode.length - 1, pressed.length - secretCode.length);
       if (pressed.join('').includes(secretCode)) {
         console.log('DING DING!');
         cornify_add();
       }
       console.log(pressed);
     });
    

    우선 키를 누르면 콘솔창에 누른 키가 뜨면서 배열 pressed에 추가된다.
    배열의 길이를 항상 6으로 정하기 위해 splice를 사용했고, 새로 입력 시 뒤에서 부터 채워진다
    만약 w,e,s,b,o,s를 입력하면 조건문의 내용과 같이 콘솔창에 알림과 유니콘사진이 생긴다(cornify_add())

찾아본 내용, 알게된 내용들

splice() - 첫번째 매개변수 > 시작 위치, 두번째 매개변수 > 제거할 요소의 수

'개발 > JavaScript30' 카테고리의 다른 글

14. JavaScript Reference VS Copying  (0) 2017.04.12
13. Slide in on scroll  (0) 2017.04.12
12. Key Sequence Detection  (0) 2017.04.11
11. Custom Video Player  (0) 2017.04.10
10. Hold Shift and Check Checkboxes  (0) 2017.04.10
9. Dev Tools Domination  (0) 2017.04.09

Custom Video Player

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>HTML Video Player</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

   <div class="player">
     <video class="player__video viewer" src="https://player.vimeo.com/external/194837908.sd.mp4?s=c350076905b78c67f74d7ee39fdb4fef01d12420&profile_id=164"></video>

     <div class="player__controls">
       <div class="progress">
        <div class="progress__filled"></div>
       </div>
       <button class="player__button toggle" title="Toggle Play">►</button>
       <input type="range" name="volume" class="player__slider" min="0" max="1" step="0.05" value="1">
       <input type="range" name="playbackRate" class="player__slider" min="0.5" max="2" step="0.1" value="1">
       <button data-skip="-10" class="player__button">« 10s</button>
       <button data-skip="25" class="player__button">25s »</button>
     </div>
   </div>

  <script src="scripts.js"></script>
</body>
</html>

목표

동영상 플레이어의 각종 기능을 자바스크립트로 구현

과정

  1. 상수 생성
  2. 함수 생성

코드 분석

  1. 상수 생성

    /* Get Our Elements */
    const player = document.querySelector('.player');
    const video = player.querySelector('.viewer');
    const progress = player.querySelector('.progress');
    const progressBar = player.querySelector('.progress__filled');
    const toggle = player.querySelector('.toggle');
    const skipButtons = player.querySelectorAll('[data-skip]');
    const ranges = player.querySelectorAll('.player__slider');
    
  2. 함수 생성

    function togglePlay() {
    const method = video.paused ? 'play' : 'pause';
    video[method]();
    }
    video.addEventListener('click', togglePlay);
    

    video가 멈춰있으면 play, 실행중이면 pause를 입력하는 상수를 만들어
    video() 메소드에 삽입하는 togglePlay() 함수 생성 후
    video의 뷰포트 클릭시 togglePlay함수가 실행되도록 이벤트리스너 생성

    function updateButton() {
    const icon = this.paused ? '►' : '❚ ❚';
    console.log(icon);
    toggle.textContent = icon;
    video.addEventListener('play', updateButton);
    video.addEventListener('pause', updateButton);
    }
    

    updateButton 함수에 재생버튼과 일시정지버튼을 토글할수 있도록 icon을 만들고
    play,pause 할 때 updateButton이 실행되도록 이벤트리스너 생성

    function skip() {
    video.currentTime += parseFloat(this.dataset.skip);
    }
    skipButtons.forEach(button => button.addEventListener('click', skip));
    

    HTML에서 만든 버튼으로 앞뒤로 스킵할 수 있도록 함수를 만들어줌

    function handleRangeUpdate() {
    video[this.name] = this.value;
    }
    ranges.forEach(range => range.addEventListener('click'), handleRangeUpadate);
    ranges.forEach(range => range.addEventListener('change'), handleRangeUpadate);
    

    볼륨과 재생속도를 조절할 수 있는 range-bar가 작동하도록 함수 생성 및 이벤트리스너 생성

    function handleProgress() {
    const percent = (video.currentTime / video.duration) * 100;
    progressBar.style.flexBasis = `${percent}%`;
    }
    video.addEventListener('timeupdate', handleProgress);
    

    현재 재생 시간에 따라 재생바의 위치를 설정해 주는 함수 생성 및 이벤트리스너 생성

    function scrub(e) {
    const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
    video.currentTime = scrubTime;
    }
    let mousedown = false;
    progress.addEventListener('click', scrub);
    progress.addEventListener('mousemove', (e) => mousedown && scrub(e));
    progress.addEventListener('mousedown', () => mousedown = true);
    progress.addEventListener('mouseup', () => mousedown = false);
    

    직접 재생바에서 원하는 시간으로 이동할 수 있게 해주는 함수 생성 및 이벤트리스너 생성

찾아본 내용, 알게된 내용들

parseFloat - 문자를 실수로 변환

'개발 > JavaScript30' 카테고리의 다른 글

13. Slide in on scroll  (0) 2017.04.12
12. Key Sequence Detection  (0) 2017.04.11
11. Custom Video Player  (0) 2017.04.10
10. Hold Shift and Check Checkboxes  (0) 2017.04.10
9. Dev Tools Domination  (0) 2017.04.09
8. Fun with HTML Canvas  (0) 2017.04.07

Hold Shift and Check Checkboxes

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Hold Shift to Check Multiple Checkboxes</title>
</head>
<body>
  <style>

    html {
      font-family: sans-serif;
      background:#ffc600;
    }

    .inbox {
      max-width:400px;
      margin:50px auto;
      background:white;
      border-radius:5px;
      box-shadow:10px 10px 0 rgba(0,0,0,0.1);
    }

    .item {
      display:flex;
      align-items:center;
      border-bottom: 1px solid #F1F1F1;
    }

    .item:last-child {
      border-bottom:0;
    }


    input:checked + p {
      background:#F9F9F9;
      text-decoration: line-through;
    }

    input[type="checkbox"] {
      margin:20px;
    }

    p {
      margin:0;
      padding:20px;
      transition:background 0.2s;
      flex:1;
      font-family:'helvetica neue';
      font-size: 20px;
      font-weight: 200;
      border-left: 1px solid #D1E2FF;
    }


  </style>
   <!--
   The following is a common layout you would see in an email client.

   When a user clicks a checkbox, holds Shift, and then clicks another checkbox a few rows down, all the checkboxes inbetween those two checkboxes should be checked.

  -->
  <div class="inbox">
    <div class="item">
      <input type="checkbox">
      <p>This is an inbox layout.</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Check one item</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Hold down your Shift key</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Check a lower item</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Everything inbetween should also be set to checked</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Try do it with out any libraries</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Just regular JavaScript</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Good Luck!</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Don't forget to tweet your result!</p>
    </div>
  </div>
<script>
</script>
</body>
</html>

목표

shift키로 체크박스를 동시에 체크 할 수 있는 기능을 추가하는 것

과정

  1. 함수 작성에 필요한 변수, 상수 작성
  2. 함수 생성
  3. 함수 호출

코드 분석

  1. 함수작성에 필요한 변수, 상수 작성

     const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');
    
     let lastChecked;
    

    checkboxesinbox클래스 하위의 체크박스 요소들을 담고 빈 변수 lastChecked를 선언

  2. 함수 생성

     function handleCheck(e) {
       let inBetween = false;
       if (e.shiftKey && this.checked) {
         checkboxes.forEach(checkbox => {
           console.log(checkbox);
           if (checkbox === this || checkbox === lastChecked) {
                 inBetween = !inBetween;
                 console.log('Starting to check them inbetween!');
           }
           if (inBetween) {
                 checkbox.checked = true;
           }
         });
       }
       lastChecked = this;
     }
    

    inBetween에 false를 할당해놓고 만약 쉬프트키를 누르고, 누른것이 체크가 되어있다면 조건문을 실행
    처음 버튼을 누를 때 쉬프트를 누르고 클릭하면 하위의 모든 내용 체크,
    두번째 버튼을 쉬프트 누르고 클릭하면 사이의 모든 내용 체크하는 내용을 3중 조건문으로 표현.

  3. 함수 호출

     checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck));
    

    체크박스를 클릭시 위에 작성한 함수를 호출

찾아본 내용, 알게된 내용들

코드 자체는 어렵지 않지만, 삼중 조건문을 이해하기가 어려웠음

'개발 > JavaScript30' 카테고리의 다른 글

12. Key Sequence Detection  (0) 2017.04.11
11. Custom Video Player  (0) 2017.04.10
10. Hold Shift and Check Checkboxes  (0) 2017.04.10
9. Dev Tools Domination  (0) 2017.04.09
8. Fun with HTML Canvas  (0) 2017.04.07
7. Array Cardio Day 2  (0) 2017.04.07

Dev Tools Domination

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Console Tricks!</title>
</head>
<body>

  <p onClick="makeGreen()">×BREAK×DOWN×</p>

  <script>
    const dogs = [{ name: 'Snickers', age: 2 }, { name: 'hugo', age: 8 }];

    function makeGreen() {
      const p = document.querySelector('p');
      p.style.color = '#BADA55';
      p.style.fontSize = '50px';
    }
  </script>
</body>
</html>

목표

콘솔창에 각종 연산 및 효과를 넣는 방법들을 익힘

과정

  1. Regular, Interpolated, Styled
  2. Warining, Error, Info
  3. Testing, clearing, Viewing DOM Elements
  4. Grouping together, counting, timing

코드 분석

  1. Regular, Interpolated, Styled

     // Regular
     console.log('hello');
    

    기본 콘솔 출력

     // Interpolated 
     console.log('Hello I am a %s string!', '💩');
    

    %s 자리에 ,뒤의 값이 들어감

     // Styled
     console.log('%c I am some great text', 'font-size:50px; background:red; text-shadow: 10px 10px 0 blue')
    

    %c 뒤에 ,뒤의 스타일 값들이 적용됨

  2. Warining, Error, Info

     // warning!
     console.warn('OH NOOO');
    

    warn - 경고창이 노란색으로 표시

     // Error
     console.error('Shit!');
    

    error - 에러창이 빨간색으로 표시

     // Info
     console.info('Crocodiles eat 3-4 people per year');
    

    info - 파란 느낌표로 정보 표시

  3. Testing, clearing, Viewing DOM Elements

     // Testing
     const p = document.querySelector('p');
    
     console.assert(p.classList.contains('ouch'), 'That is wrong!');
    

    assert - 첫번째 인자가 false일 때 로그 메세지를 출력

     // clearing
     console.clear();
    

    clear - 콘솔의 내용을 전부 지운다

     // Viewing DOM Elements
     console.log(p);
     console.dir(p);
    
     console.clear();
    

    log - 괄호 안의 해당 엘리먼트를 보여줌
    dir - 괄호 안의 해당 엘리먼트의 모든 속성을 보여줌

  4. Grouping together, counting, timing

     // Grouping together
     dogs.forEach(dog => {
         console.groupCollapsed(`${dog.name}`);
         console.log(`This is ${dog.name}`);
         console.log(`${dog.name} is ${dog.age} years old`);
         console.log(`${dog.name} is ${dog.age * 7} dog years old`);
         console.groupEnd(`${dog.name}`);
     });
    

    groupCollapsedgroupEnd 사이에 새 그룹 로깅을 작성

     // counting
     console.count('Wes');
     console.count('Wes');
     console.count('Steve');
     console.count('Steve');
     console.count('Wes');
     console.count('Steve');
     console.count('Wes');
     console.count('Steve');
     console.count('Steve');
     console.count('Steve');
     console.count('Steve');
     console.count('Steve');
    

    count는 같은 인자의 개수를 셈

     // timing
     console.time('fetching data');
     fetch('https://api.github.com/users/wesbos')
         .then(data => data.json())
         .then(data => {
             console.timeEnd('fetching data');
             console.log(data);
         });
    
     console.table(dogs);
    

    timetimeEnd 사이에 데이터를 받아와 타이머를 작동

찾아본 내용, 알게된 내용들

assert - 평가 된 식이 false면 콘솔에 오류 기록
dir - 저장된 객체의 자바스크립트 표현을 출력, HTML 요소일 경우 DOM 표현의 속성 출력
console.group(), console.groupEnd() - 선택적 제목을 사용하여 새로운 로깅 그룹을 시작, console.group() 후와 console.groupEnd() 전에 발생하는 모든 콘솔 출력은 시각적으로 그룹화된다.

'개발 > JavaScript30' 카테고리의 다른 글

11. Custom Video Player  (0) 2017.04.10
10. Hold Shift and Check Checkboxes  (0) 2017.04.10
9. Dev Tools Domination  (0) 2017.04.09
8. Fun with HTML Canvas  (0) 2017.04.07
7. Array Cardio Day 2  (0) 2017.04.07
6. Type Ahead  (0) 2017.04.06

Fun with HTML5 Canvas

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>HTML5 Canvas</title>
</head>
<body>
    <canvas id="draw" width="800" height="800"></canvas>
<script>
</script>
<style>
  html, body {
    margin:0;
  }
</style>
</body>
</html>

목표

제목 그대로 HTML에 캔버스를 만들어 각종 효과를 넣어보는 연습

과정

  1. 그리기 효과를 사용하기 위한 기본 설정
  2. 그리기 효과를 실시간으로 변경하기 위한 변수 설정
  3. 그리기 효과를 실시간으로 변경하기 위한 함수 작성
  4. 그리기 효과를 실시간으로 바꾸는 함수 실행

코드 분석

  1. 그리기 효과를 사용하기 위한 기본 설정

     const canvas = document.querySelector('#draw');
     const ctx = canvas.getContext('2d');
     canvas.width = window.innerWidth;
     canvas.height = window.innerHeight;
     ctx.strokeStyle = '#BADA55';
     ctx.lineJoin = 'round';
     ctx.lineCap = 'round';
     ctx.lineWidth = 100;
    

    canvas에 id가 draw인 요소들을 담고, ctxcanvas의 그리기 대상이 되는 context를 얻음
    widthheight를 브라우저에 표현되도록 뷰포트 폭을 받고서
    strokeStyle - 윤곽선의 색깔, lineJoin - 두 선이 만나는 지점의 모양,
    lineCap - 선의 끝 모양, lineWidth - 선의 두께 설정

  2. 그리기 효과를 실시간으로 변경하기 위한 변수 설정

     let isDrawing = false;
     let lastX = 0;
     let lastY = 0;
     let hue = 0;
     let direction = true;
    

    isDrawing - 현재 그림을 그리고 있는지 없는지 여부를 나타내며 기본값은 false,
    lastX - 시작지점의 x좌표 0,lastY - 시작 지점의 y좌표 0,
    hue - 기본 색상을 처음에 0으로 설정, direction - 굵기를 정하는 방향을 true,false로해서 기본값 true로 설정

  3. 그리기 효과를 실시간으로 변경하기 위한 함수 작성

     function draw(e) {
         if (!isDrawing) return; // stop the fn from running when they are not moused down
    
         ctx.strokeStyle = `hsl(${hue}, 100%, 50%)`;
         ctx.beginPath();
         // start from
         ctx.moveTo(lastX, lastY);
         // go to
         ctx.lineTo(e.offsetX, e.offsetY);
         ctx.stroke();
         [lastX, lastY] = [e.offsetX, e.offsetY];
    
         hue++;
         if (hue >= 360) {
             hue = 0;
         }
         if (ctx.lineWidth >= 100 || ctx.lineWidth <= 1) {
             direction = !direction;
         }
    
         if (direction) {
             ctx.lineWidth++;
         } else {
             ctx.lineWidth--;
         }
     }
    

    data()라는 함수에 e(event) 인자를 주고,
    첫 줄은 만약 그리기가 이루어지지 않을 때 return;을 반환해 다음 코드가 실행되지 않도록 함
    strokeStyle로 윤곽선의 색상을 설정해주는데 이때 hue라는 변수로 값을 계속 바꿔줌
    beginPath()로 선의 시작점, moveTo(lastX, lastY)로 그리기 시작할 좌표,
    lineTo(e.offsetX, e.offsetY)로 그리기 종료 지점 좌표를 지정해주고
    stroke()로 시작점부터 종료 지점까지를 이어준다.
    여기서 hue++은 이벤트가 한번 일어날때 마다 hue값이 1씩 증가하는다는 뜻이고
    hue가 360이상이 되면 0으로 초기화를 시켜줘서 계속 반복되도록 한다.
    즉 색상이 그림을 그려 움직일때마다 계속 바뀐다
    아래는 선의 굵기가 100이상 또는 1이하일때 direction을 true, false로 변경해
    조건문으로 direction이 true이면 굵기가 두꺼워지고, false이면 굵기가 얇아지게 해준다

  4. 그리기 효과를 실시간으로 바꾸는 함수를 실행

    canvas.addEventListener('mousedown', (e) => {
        isDrawing = true;
        [lastX, lastY] = [e.offsetX, e.offsetY];
    });
    
    canvas.addEventListener('mousemove', draw);
    canvas.addEventListener('mouseup', () => isDrawing = false);
    canvas.addEventListener('mouseout', () => isDrawing = false);
    

    마우스를 누르면(mousedown) isDrawing이 True, 즉 그리기 효과가 시작된다
    마우스가 움직이면(mousemove) draw 함수가 실행
    마우스를 떼거나(mouseup),마우스가 뷰포트를 떠나면(mouseout) isDrawing이 False, 즉 그리기 효과가 끝난다.

찾아본 내용, 알게된 내용들

canvas.getContext('2d') - canvas에 그리기 대상을 찾는 함수
innerWidth - 뷰포트의 폭을 받는 메소드, height는 높이를 받는 메소드
moveto(),lineto() - 그리기 효과를 시작하는 점과 종료하는 점의 좌표를 작성
각종 마우스 효과들

끝! 이번껀 코드가 길어서 어려웠음

'개발 > JavaScript30' 카테고리의 다른 글

10. Hold Shift and Check Checkboxes  (0) 2017.04.10
9. Dev Tools Domination  (0) 2017.04.09
8. Fun with HTML Canvas  (0) 2017.04.07
7. Array Cardio Day 2  (0) 2017.04.07
6. Type Ahead  (0) 2017.04.06
5. Flex Panel Gallery  (0) 2017.04.05

Array Cardio Day 2

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Array Cardio 💪💪</title>
</head>
<body>
  <p><em>Psst: have a look at the JavaScript Console</em> 💁</p>
  <script>
    // ## Array Cardio Day 2

    const people = [
      { name: 'Wes', year: 1988 },
      { name: 'Kait', year: 1986 },
      { name: 'Irv', year: 1970 },
      { name: 'Lux', year: 2015 }
    ];

    const comments = [
      { text: 'Love this!', id: 523423 },
      { text: 'Super good', id: 823423 },
      { text: 'You are the best', id: 2039842 },
      { text: 'Ramen is my fav food ever', id: 123523 },
      { text: 'Nice Nice Nice!', id: 542328 }
    ];


    // Array.prototype.find()
    // Find is like filter, but instead returns just the one you are looking for
    // find the comment with the ID of 823423

    // Array.prototype.findIndex()
    // Find the comment with this ID
    // delete the comment with the ID of 823423

  </script>
</body>
</html>

목표

Array Cardio Day1에 이어 각종 자바스크립트 메소드를 익혀봄

과정

  1. some()
  2. every()
  3. find()
  4. findIndex(), slice()

코드 분석

  1. some()

     // Array.prototype.some() // is at least one person 19 or older?
     const isAdult = people.some(person => ((new Date()).getFullYear()) - person.year >= 19);
    
     console.log({isAdult});
    

    기본 코드에서 선언한 people에 19살 이상이 한명 이상 있는지 알아보기 위한 코드를 작성
    some()은 앞의 배열의 내용 중 조건에 맞는것이 있다면 true 없다면 false를 반환하는 메소드.
    괄호 안의 내용은 현재 시간에서 네자리로 현재 연도를 얻어 낸 뒤 태어난 년도를 뺐을 때 19 이상이 있는지
    확인하는 코드, 콘솔을 통해 결고 확인

  2. every()

     // Array.prototype.every() // is everyone 19?
     const allAdults = people.every(person => ((new Date()).getFullYear()) - person.year >= 19);
     console.log({allAdults});
    

    기본 코드에서 선언한 people에 모두 19살 이상인지 알아보기 위한 코드를 작성
    every()는 앞의 배열의 내용이 모두 조건에 맞다면 true 없다면 false를 반환하는 메소드
    괄호 안의 내용은 위와 동일, 콘솔을 통해 결과 확인

  3. find()

     // Array.prototype.find()
     // Find is like filter, but instead returns just the one you are looking for
     // find the comment with the ID of 823423
    
     const comment = comments.find(comment => comment.id === 823423);
    
     console.log(comment);
    

    기본 코드에서 선언한 comment에서 ID가 823423인 값이 있는지 찾기 위해 사용
    부연설명이 따로 필요 없이 코드 그자체로 이해가 가능, 콘솔창에 결과 출력

  4. findIndex(), slice()

    // Array.prototype.findIndex()
     // Find the comment with this ID
     // delete the comment with the ID of 823423
     const index = comments.findIndex(comment => comment.id === 823423);
     console.log(index);
    
     // comments.splice(index, 1);
     const newComments = [
         ...comments.slice(0, index),
         ...comments.slice(index + 1)
     ];
     console.log(newComments);
    

    기본 코드에서 선언한 comment에서 ID가 823423인 값을 찾아 index를 반환할때 사용
    콘솔창에 결과 출력
    배열안에 ...을 사용해 새로운 배열 newComments안에 id가 823423인 값을 뺀 나머지를 넣는 코드,
    주석과 아래의 코드가 동일하며 slice()splice()의 차이는 아래에 적어두었음

찾아본 내용, 알게된 내용들

findIndex() - 일치하는 값의 색인을 반환할 때 사용
slice() - 숫자만큼 뒤에서부터 배열을 추출
splice() - 숫자만큼 뒤에서부터 배열을 삭제
... - 전개 연산자(spread operator)/ 식이 여러 인수(함수 호출 용)나 여러 요소(배열 리터럴 용) 또는 여러 변수(비구조화 할당 용)가 예상되는 곳에 확장될 수 있도록 함

'개발 > JavaScript30' 카테고리의 다른 글

9. Dev Tools Domination  (0) 2017.04.09
8. Fun with HTML Canvas  (0) 2017.04.07
7. Array Cardio Day 2  (0) 2017.04.07
6. Type Ahead  (0) 2017.04.06
5. Flex Panel Gallery  (0) 2017.04.05
4. Array Cardio Day 1  (0) 2017.04.04

Type Ahead

웹에서 정보를 받아와 Live Search 기능을 구현

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Type Ahead 👀</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <form class="search-form">
    <input type="text" class="search" placeholder="City or State">
    <ul class="suggestions">
      <li>Filter for a city</li>
      <li>or a state</li>
    </ul>
  </form>

  <script>
    const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
  </script>
</body>
</html>

목표

이번엔 스타일시트가 따로 빠져있는데 자바스크립트를 공부하는 목적이므로 따로 첨부는 하지 않음
우리는 검색창을 만들어서 도시나 주의 이름의 일부를 검색하면 도시, 주, 인구수를 실시간으로 보여주도록 만들 예정

과정

  1. 도시와 주의 이름과 인구수를 받아옴
  2. 검색시 일치하는 값을 찾아내는 함수를 만듦
  3. 위의 함수를 이용해 화면에 보여지게하는 함수를 만듦
  4. 인구수를 보기 편하게 콤마를 삽입하는 함수를 만들어줌
  5. 만든 함수를 통해 실시간으로 브라우저에 출력

코드 분석

  1. 도시와 주의 이름과 인구수를 받아옴

     const cities = [];
    
     fetch(endpoint)
       .then(blob => blob.json())
       .then(data => cities.push(...data));
    

cities라는 빈 배열을 생성하고, fetch()를 사용함
처음보는 함수인데 jQuery의 Ajax와 비슷한 느낌인 것 같다.
쉽게말해 이전에 기본코드에 담겨있던 endpoint json 파일을 파싱할때 JavaScript에서 fetch()를 사용하는 것 같다. 상세한 문법은 다음에 다시볼 때 정리해보도록 해야겠다

  1. 검색시 일치하는 값을 찾아내는 함수를 만듦
     function findMatches(wordToMatch, cities) {
       return cities.filter(place => {
         // here we need to figure out if the city or state matches what was searched
         const regex = new RegExp(wordToMatch, 'gi');
         return place.city.match(regex) || place.state.match(regex)
       });
     }
    
    검색시 단어가 일치하는 도시 또는 주를 반환하는 변수 regex를 만들고
    cities에 필터를 적용해 반환하도록 하는 findMatches 함수를 만든다
    이때 RegExp는 검색할때 패턴을 설정해 줄 수 있는 생성자이고, 'gi'는 전체에서 대소문자를 구분하지 않고 검색한다는 의미이다.
  1. 위의 함수를 이용해 화면에 보여지게하는 함수를 만듦

     function displayMatches() {
       const matchArray = findMatches(this.value, cities);
       const html = matchArray.map(place => {
         const regex = new RegExp(this.value, 'gi');
         const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
         const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
         return `
           <li>
             <span class="name">${cityName}, ${stateName}</span>
             <span class="population">${numberWithCommas(place.population)}</span>
           </li>
         `;
       }).join('');
       suggestions.innerHTML = html;
    }
    

    matchArray에 일치하는 값을 담고, html에 검색 후에 배열에서 일치하는 내용을 찾아
    cityName, stateName에 새로운 검색값이 들어간 html태그로 대체하도록 하고,
    새로운 리스트 태그를 반환하고 공백으로 서로를 연결하게 해서
    suggestions에 html내용을 스크립트로 삽입하는 이 모든과정을 displayMatches()함수에 담는다

  2. 인구수를 보기 편하게 콤마를 삽입하는 함수를 만들어줌

     function numberWithCommas(x) {
       return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
     }
    

    따로 알아볼 필요없이 킹갓Stackoverflow에서 가져온 코드

  3. 만든 함수를 통해 실시간으로 브라우저에 출력

     const searchInput = document.querySelector('.search');
     const suggestions = document.querySelector('.suggestions');
    
     searchInput.addEventListener('change', displayMatches);
     searchInput.addEventListener('keyup', displayMatches);
    

    searchInputsearch 클래스를 포함하는 요소들을 담고,
    suggestions에는 suggestions 클래스를 포함하는 요소들을 담는다.
    searchInputchange이벤트와 keyup이벤트가 실행될 때 displayMatches함수를 실행

    찾아본 내용, 알게된 내용들

fetch() - JavaScript의 Ajax와 비슷한 개념
... - ES6 문법으로 검색예정/잘모르겠다..주륵
match()

RegExp -생성자의 종류로, 특정 패턴에 맞는 텍스트를 위한 일반적인 표현식을 만들어 낸다.
사용법은 RegExp(pattern[, flags]) 로 사용하며 flags 종류는
g(전체에서 일치하는 모든문자 검색)
i(대소문자 구별하지 않음)
m(다중행에 적용)

끝!

'개발 > JavaScript30' 카테고리의 다른 글

8. Fun with HTML Canvas  (0) 2017.04.07
7. Array Cardio Day 2  (0) 2017.04.07
6. Type Ahead  (0) 2017.04.06
5. Flex Panel Gallery  (0) 2017.04.05
4. Array Cardio Day 1  (0) 2017.04.04
3. CSS Variables  (0) 2017.04.03


다음 계획

  • JavaScript30 완료 (끝!)
  • Vue 공부하며 예제 만들어보기
  • Vue 심화 자료 포스팅
  • Nuxt 공부


'개발 > Vue.js' 카테고리의 다른 글

Nuxt 토이 프로젝트(포트폴리오 페이지)  (0) 2017.05.08
Vue.js 정리  (0) 2017.04.25
Vue 기본자료 포스팅 완료!  (0) 2017.04.06
10. 컴포넌트  (0) 2017.04.06
9. 폼 입력 바인딩  (0) 2017.03.31
8. 이벤트 핸들링(v-on)  (0) 2017.03.31

+ Recent posts