약 200줄 코드로 개 그림 브라우저를 작성하다

개는 훌륭하고 위대한 사람이다.며칠 전, 내가 만났을 때, 나는 그것으로 뭔가를 해야만 했다.그래서 해냈어.내가 너에게 개 브라우저를 줄게.
Dog.ceo API of free dog images sorted by breed
그림을 누르면 무작위 개 그림을 얻거나 상자에 입력하여 개 종류를 선택하고 결과를 필터할 수 있습니다.



source on GitHub 을 확인할 수 있습니다.
다음은 제가 뭐라고 그랬는지...

혼자 놀아요. 데이터 가져오기


API 문서를 보고 사용할 세 가지 끝점을 찾았습니다.

  • - 랜덤 개 이미지 얻기(좋은 시작)

  • https://dog.ceo/api/breeds/image/random - 어떤 품종의 랜덤 이미지 획득, f.e.https://dog.ceo/api/breed/${breed}/${sub}/images/random 랜덤으로 카드 가능 개 한 마리
  • 획득

  • https://dog.ceo/api/breed/spaniel/cocker/images/random 모든 품목의 목록 얻기
  • 데이터는 JSON 형식으로 매우 간단하며 상태와 메시지 속성을 가진 대상이다.이미지 찾기의 경우 메시지는 이미지의 URL입니다.모든 품목 찾기의 경우 모든 이름을 키와 일련의 가능한 하위 품목의 대상으로 지정합니다.괴로운 것은 이 품종들이 모두 소문자라는 것이다.

    https://dog.ceo/api/breeds/list/all HTML 계획


    개의 품종을 표시하고 사용자가 품종에 따라 필터를 할 수 있도록 하는 방법을 원합니다.
    버튼은 키보드와 마우스를 통해 접근할 수 있기 때문에 매우 좋다.다른 HTML 요소도 포함할 수 있습니다.이미지를 표시하기 위해 다음 옵션을 선택했습니다.
    <button class="loading">
      <h2></h2>
      <img src="" alt="Good boy/girl">
      <p>Click for more dogs!</p>
    </button> 
    
    이것은 사람들로 하여금 다음 그림의 인기 구역을 가능한 한 크게 선택하게 한다.
    품종을 선택할 때 나는 품종 목록이 매우 방대하고 하위 품종이 존재할 수 있다는 문제에 부딪혔다.처음에 나는 사용 가능한 하위 품종이 있을 때 두 번째 선택 상자를 표시하는 선택 상자를 생각했다.사용하기는 번거롭고 개발하기도 번거롭다.그래서 나는 에 연결된 입력 요소를 선택했다.이것은 HTML5의 자동 완성입니다.
    <form>
      <label for="breed">Dog breed:</label>
      <input list="allbreeds" id="breed"></input>
      <datalist id="allbreeds"></datalist> 
    </form>
    

    데이터 목록 인터페이스 스타일 설정


    너는 그것의 모든 영광을 위해 treats.css 할 수 있지만, 나는 흥미를 느낄 수 있는 기교를 사용했다.
    button {
      max-width: 90vw;
      min-height: 50vh;
      width: 100%;
      cursor: pointer;
      position: relative;
      /* … More … */
    }
    
    나는 화면 절반의 최소 높이를 단추로 눌러 창의 90퍼센트로 제한했다.나는 사람들에게 클릭을 알려주기 위해 그것cursorpointer을 하나 주었다.나는 잠시 후에 교묘한 메시지 불러오는 방식을 허용하기 위해 그것에 대해 상대적인 위치를 정했다.
    button img {
      border-radius: 10px;
      margin: 0 auto;
      object-fit: contain;
      max-height: 60vh;
      min-height: 200px;
      max-width: 90%;
    }
    
    나는 그림에 maxmin의 높이와 max의 넓이를 주고 숨을 돌릴 공간을 주었다.object-fit: contain 이미지가 늘어나지 않도록 합니다.
    button.loading img {
      opacity: 0;
    }
    
    불러오는 과정에서 나의 숨겨진 그림은 마치 좋은 소유와 같다.마운트하려면 [마운트] 덮어쓰기를 만드는 간단한 방법이 있습니다.
    button.loading:after {
      border-radius: 10px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      content: 'Loading...';
      background: rgba(0,0,0,.8);
      color: white;
      position: absolute;
      top: 0; left: 0; 
      right: 0; bottom: 0;
    }
    
    단추positionrelative이기 때문에 CSS에서 생성한 내용을 사용하여 덮어쓰기를 만들 수 있습니다.우리는 그것을 절대적으로 포지셔닝하고 top, left, rightbottom0 로 설정합니다.이것은 사용자가 이미지를 불러올 때 다시 누르지 않도록 전체 단추를 덮어씁니다.flex "로드..."설정정보의 중심은 폭발이다.
    button.error:before {
      content: '⚠️ Oh no! No dogs found, try another breed!';
      color: firebrick;
      display: block;
      margin: 5px;
      border: 2px solid darkred;
    }
    
    또한 CSS 생성 컨텐트를 error 상태에 사용합니다.
    마지막으로 미디어 조회는 작은 장치에 충분한 공간이나 더 큰 공간이 있을 때 단추 옆에 폼을 표시합니다.
    @media (min-width:600px) {
      section {display: flex;}
    }
    

    CSS 소스 코드 보기 JavaScript 사용


    나는 장래에 이 코드를 변경할 수 있으니, 수시로 변경할 것을 확보해 주십시오 walkies.js. 그러나 우리는 시작했습니다.
    const breed = document.querySelector('#breed');
    const imagecontainer = document.querySelector('button img');
    const breedinfo = document.querySelector('h2');
    const button = document.querySelector('button');
    const datalist = document.querySelector('#allbreeds');
    
    let url = 'https://dog.ceo/api/breeds/image/random';
    
    스크립트가 접촉할 모든 HTML 요소에 대한 참조를 저장합니다.이것은 나중에 HTML을 변경할 수 있다는 것을 의미하기 때문에 나는 이렇게 하는 것을 좋아한다.
    나는 url 너에게 무작위 개 그림을 주는 것으로 정의할 것이다.
    const getbreeds = breeds => {
     fetch('https://dog.ceo/api/breeds/list/all')
      .then(response => response.json())
      .then(data => {
         seedbreedsform(data.message);
       })
    };
    
    getbreeds 함수는 API를 사용하여 사용 가능한 개 종의 모든 이름을 가져옵니다.나는 (자연스럽게) JSON을 불러와서 해석하고 결과를 fetch() 함수에 보내서 이 데이터를 폼 피드로 한다.
    const ucfirst = str => {
      return str.charAt(0).toUpperCase() + str.slice(1);
    }
    
    seedbreedsform()의 괴로운 점은 스타일링을 할 수 없다는 것이다.개의 품종은 API에서 모두 소문자이기 때문에 나는 작은 함수를 사용하여 대문자 품종과 자 품종을 사용했다.드롭다운 메뉴가 있습니다. 이것은 CSS에서 완성할 수 있습니다. 언젠가는 우리가 실현할 수 있기를 바랍니다.
    const seedbreedsform = breeds => {
      let out = '';
      Object.keys(breeds).forEach(b => {
        out += `<option value="${ucfirst(b)}"/>`;
        breeds[b].forEach(s => {
          out += `<option value="${ucfirst(b)} - ${ucfirst(s)}"/>`;
        });
      });
      datalist.innerHTML = out;
      breed.addEventListener('change', findbreed);
    };
    
    API가 반환하는 객체의 모든 키를 누른 후 datalist 각 키에 대해 breeds 를 만듭니다.열쇠는 품종의 이름이다.만약 하위 품종이 있다면, 그것들의 가치는 일련의 더 많은 품종이다.나는 이 수조를 순환해서'번식-자 번식'이라는 값을 만드는 옵션을 만들었다.모든 옵션이 존재하면 optiondatalist 을 결과 문자열로 설정합니다.이것은 사용자에게 모든 사용 가능한 품종의 자동 완성을 효과적으로 제공하였다.
    이벤트 탐지기 호출 innerHTML 을 추가했습니다. 사용자가 자동 완성에서 품목을 선택할 때.
    const findbreed = _ => {
      let name = breed.value;
      name = name.replace(' - ', '/').toLowerCase();
      url = `https://dog.ceo/api/breed/${name}/images/random`
      getdog(); 
    };
    
    입력 요소의 datalist 는 데이터의 읽을 수 있는 버전이기 때문에 취소해야 합니다."-"를 슬래시로 대체하고 전체 문자열을 소문자로 만들고 URL을 조립하여 API에서 이미지를 가져옵니다.나는 findbreed() 을 이 더 구체적인 함수로 바꾸고 value 함수를 호출할 것이다.
    button.addEventListener('click', getdog);  
    imagecontainer.addEventListener('load', e => {
      button.classList.remove('loading');
    });
    
    url 기능은 이미지를 로드하고 버튼 요소에 추가하는 주요 기능입니다.내가 다시 단추를 눌렀을 때, 나는 다른 그림을 원했다.따라서, 나는 단추에 이벤트 처리 프로그램을 추가해서 그것을 호출해야 한다.getdog() 함수는 이미지 용기의 getdog 속성을 변경하여 이미지를 불러옵니다.이것이 바로 내가 마운트에서 완료로 상태를 바꾸기 위해 이미지의 getdog 이벤트 처리 프로그램이 필요한 이유입니다.
    const getdog = _ => {
      button.classList.remove('error');
      button.classList.add('loading');
      fetch(url)
      .then(response => {
        if (response.ok) {
          return response.json();
        } else {
          button.classList.remove('loading');
          button.classList.add('error');
        }
      })
      .then((data) => {
        imagecontainer.src = `${data.message}`;
        let bits = data.message.split('/');
        bits = bits[bits.length-2]
               .split('-')
               .map(b => ucfirst(b))
               .join(' - ');
        breedinfo.innerText = bits;
      })
    };
    
    버튼에 적용될 수 있는 CSS 클래스src를 삭제하고 클래스load를 추가했습니다.그리고 나는 error 호출 API를 사용한다.
    응답이 좋지 않으면 loading 클래스를 삭제하고 fetch() 클래스를 추가합니다.
    응답이 "ok"이면 버튼의 이미지loading를 API에서 되돌아오는 메시지(이미지의 URL)로 설정합니다.그리고 나는 현재의 품종, 무작위 개의 그림을 표시하기 위해 약간의 변환을 해야 한다.
    다음은 작업 원리입니다.
    URL은 단품종 개나 자품종 개의 혼합일 수 있다.하위 품종이 있는 사람들은 하이픈이 있다.예:
    check the source on GitHub
    https://images.dog.ceo/breeds/cockapoo/Scout.jpg
    나는 사선에서 URL을 분리하여 마지막 이전의 URL을 얻었다. 이 예에서'cockapoo'또는'spanielcocker'이다.나는 하이픈에서 이 부분을 분할하여 각 부분을 error 대문자로 보냈다.그런 다음 "-"로 다시 연결하고 결과 문자열을 표시합니다.
    마지막으로 해야 할 일은 폼 제출의 오류가 페이지를 다시 불러오지 않도록 하는 것이다.
    document.querySelector('form').addEventListener('submit', e => {
      e.preventDefault();
    });
    
    첫 번째 개 그림을 불러와 품종 목록을 얻습니다.
    getdog();
    getbreeds();
    

    https://images.dog.ceo/breeds/spaniel-cocker/n02102318_5690.jpg 웹 표준의 즐거움


    여기 있습니다.여러 줄의 CSS와 JavaScript로 구성된 개 브라우저는 의존 관계가 없습니다(물론 개 API 제외).나는 이것이 많이 개선될 수 있을 것이라고 확신하지만, 나는 매우 기쁘게 했고, 인터넷이 상자를 열면 바로 사용할 수 있다는 것을 보고 매우 기뻤다.

    좋은 웹페이지 즐겨찾기