Polyfills. - 얘네는 뭐야?

인터넷에는 이상한 용어들이 넘쳐나는데, 이것은 초보자들에게 특히 무섭다.이 박문 뒤에 있는 생각(이렇게 됐으면 좋겠다)🤞 ) 곧 발표될 블로그 글은'화려한'용어를 담백하게 하기 위한 것이다.본문에서 우리는 다각형 충전을 토론할 것이다.

간단한 영어로.
Polyfills는 이러한 기능이 지원되지 않거나 지원되지 않는 브라우저(또는 일반적인 JS 환경)에서 새로운 기능을 사용할 수 있도록 하는 코드입니다.두 가지를 기억해라.
  • 모든 특징이 다 채울 수 있는 것은 아니다(예를 들어 spread syntax(...).
  • polyfill은 기능이 부족할 때만 실행됩니다.그렇지 않으면, 그것은 반드시 본 기계로 실현해야 한다.

  • 약사
    polyfill이라는 단어는 처음에 Remy Sharp가 2009년에 도입한 것이다.이 단어 자체는 Polyfilla에서 유래한 영국 제품으로 벽의 균열과 구멍을 메우는 데 쓰인다.

    Polyfilla is a UK product known as Spackling Paste in the US. With that in mind: think of the browsers as a wall with cracks in it. These polyfills help smooth out the cracks and give us a nice smooth wall of browsers to work with.

    -- Remy Sharp


    충분한 역사.내가 짧게 말했잖아!

    Polyfills vs Transpiler
    깊이 파헤치기 전에 Polyfill과 Transpiler라는 두 용어 사이의 차이를 먼저 알아봅시다.
    내가 새로운 js 문법을 채울 방법이 없다고 말한 거 기억나?transpiler (transformer + 컴파일러) 는 이렇게 하는 것이다.
    새 구문을 기존 브라우저에서 지원하는 동일 구문으로 변환합니다.따라서polyfill과 달리 작성한 코드는 예비 코드로 변환되어 브라우저에서 실행됩니다.
    바벨과 같은transpiler는 목표 브라우저에 따라 엔진 뚜껑에polyfills를 사용하여 새로운 기능을 지원한다는 것을 기억하십시오.
    만약 당신이 여전히 둘 사이의 차이를 확정하지 못한다면, 여기에 SO의 답장이 있으니, 더욱 상세하게 소개할 수 있습니다.

    우리만의 polyfill을 쓰래요.
    그래, 우리 시작하자.앞서 언급한 바와 같이polyfill은 일부 기능을 모든 브라우저에서 사용할 수 있도록 하는 코드일 뿐입니다.일반적으로 양호한 다각형 채우기는 브라우저에서 대상 기능이 지원되는지 확인합니다.그렇다면 아무것도 하지 마, 아빠!그렇지 않으면 사용 가능한 API를 사용하여 이 새 기능의 동작을 시뮬레이션합니다.

    JS:Element.closest(selectorList)근거 MDN:

    The closest() method traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string. Will return itself or the matching ancestor. If no such element exists, it returns null.


    따라서 기본적으로 HTML 요소를 지정하고 closest() 방법은 요소 트리에서 가장 가까운 요소를 되돌려줍니다. 이 요소는 최소한selectorList의 선택기와 일치합니다.
    다음과 같은 HTML DOM이 있다고 가정합니다.
    ...
    <div class="level-1">
        <div class="level-2">
            <p class="level-3"> Polyfills are awesome 🎉 </p>
        </div>
    </div>
    ...
    
    const paragraph = document.querySelector('p');
    paragraph.closest('.level-1'); // Returns <div class="level-1">...</div>
    paragraph.closest('.level-1, .level-2'); // Returns <div class="level-2">...</div>
    paragraph.closest('.level-3'); // Returns paragrah itself
    paragraph.closest('.level-bla'); // Returns null
    
    그래!이제 우리는 이 함수가 어떻게 작동하는지 알게 되었고, 우리는 실현하기 시작할 수 있다.
    👋 초보자 힌트: 지금은 codepen를 열고 실험을 시작하기에 좋은 시기입니다.
    우리 이 문제를 한번 고려해 봅시다.필요한 사항:
  • DOM을 위로 통과하는 방법.
  • 요소가 선택기 목록과 일치하는지 확인합니다.
  • 이제 솔루션에 대해 살펴보겠습니다.
  • DOM을 위로 누비는 방법*=>while 순환과 .parentElement 아이템을 사용합니다.
  • 요소가 selectorList=>와 일치하는지 확인하려면 .matches() 방법을 사용하십시오.
  • const closest = (element, selectorList) => {
        while(element && !element.matches(selectorList)) {
            element = element.parentElement;
        }
        return element;
    };
    
    위의 코드 세션에서 우리는 두 개의 인자가 있는 함수를 정의했다. elementselectorList.그리고 우리는 두 가지 일 중 하나가 발생할 때까지 순환했다.
  • element는null이기 때문에 우리는 이미 뿌리 원소에 도달했다.
  • element.matches(selectorList)true로 되돌아오기 때문에 selectorList와 일치하는 최근 요소를 찾았습니다.
  • 우리는 이것이 우리의 이전 테스트 집합과 같다는 것을 검사할 수 있다.
    ...
    const paragraph = document.querySelector('p');
    closest(paragraph, '.level-1'); // Returns <div class="level-1">...</div>
    closest(paragraph,'.level-1, .level-2'); // Returns <div class="level-2">...</div>
    closest(paragraph,'.level-3'); // Returns paragrah itself
    closest(paragraph,'.level-bla'); // Returns null
    
    마지막 단계에서는 함수 prototype 를 요소Element에 추가하여 객체의 모든 인스턴스에서 사용할 수 있도록 합니다.
    Element.prototype.closest = (selectorList) => {
        let element = this;
        while(element && !element.matches(selectorList)) {
            element = element.parentElement;
        }
        return element;
    };
    
    마지막 세부 사항은polyfill이 브라우저가 지원하지 않는 상황에서 어떤 방식으로 이 기능을 원형에 추가하기를 바란다는 것입니다.다시 말하면, 만약 가능하다면, 우리는 차라리 브라우저의 본체를 사용하여 실현하기를 원한다.간단한if 하나면 돼요!
    if(!Element.prototype.closest) {
        Element.prototype.closest = (selectorList) => {
            let element = this;
            while(element && !element.matches(selectorList)) {
                element = element.parentElement;
            }
            return element;
        };
    }
    
    ✨ 주: 이것은 결코 생산할 수 있는 중합물 충전물이 아니다.간단하게 보기 위해서 나는 많은 일을 가설했다.생산된polyfill은 .matches()가 존재하지 않을 수도 있다는 사실을 설명할 수 있고 서로 다른 브라우저 공급업체의 접두사를 검사할 수 있다.더 완전한 버전here을 찾을 수 있습니다.

    CSS::blank본문을 작성할 때:blank 위류는 매우low의 지지를 받았다.이 섹션에서는 polyfill CSS 기능의 아이디어를 보여주기 위해 대략적인 polyfill (어쨌든 완전하지 않음) 을 작성해 보겠습니다.
    나는 MDN의 정의를 다시 인용할 것이다. (사람들이 일반적으로 하는 것처럼!)

    The :blank CSS pseudo-class selects empty user input elements (e.g. <input> or <textarea>).


    따라서 사용:blank위류는 이렇게 보인다
    input:blank{
      background: red;
    }
    textarea:blank{
      color: green;
    }
    
    
    ✨ 주1: 이것은 textarea:blank를 사용하는 CSS의 문법 속성이기 때문에 CSS 해석기는 무효 선택기로 사용할 가능성을 배제합니다.따라서 우리는 textarea[blank]을 사용할 것이다.본문의 나머지 부분에서 나는 :blank[blank]를 번갈아 사용할 것이라는 것을 기억해 주십시오.
    ✨ 주2: 이것은 실제로PostCSS 엔진 뚜껑 아래의 작용이다.그것은 모든 출현:blank[blank]로 교체한다.
    이 점을 어떻게 실현할 것인가에 대해 생각해 봅시다.필요한 사항:
    1. 우리의 스타일시트에 접근하는 몇 가지 방법.
    2. 검측표의 선택기selector[blank].
    3. 선택한 요소에 공백 위조 클래스를 연결합니다.
    4. 입력 값을 변경할 때 스타일을 업데이트합니다.
    👋 초보자 힌트: 지금은 codepen를 열고 실험을 시작하기에 좋은 시기입니다.
    이것은 우리의 요구다.모든 사람에게 어떻게 대처해야 하는지 이야기해 봅시다.
    1. 스타일시트 => CCSOM 에 액세스하는 방법
    2. Detect:blank 함수 => 정규 표현식 사용
    3. 선택한 요소에 빈 위조 클래스 바인딩=>선택한 입력에 속성 추가
    4. JS=>listen for input event 를 통해 값을 변경할 경우 입력 상태의 값을 업데이트합니다.

    1. 스타일시트에 액세스
    먼저 CSS 스타일시트에 액세스해야 합니다.우리는 CCSOM을 사용하여 이 점을 실현하는데 특히 문서에 있는 styleSheets 도구를 방문한다.
    for(let  styleSheet  of  document.styleSheets) {
      for(let  cssRule  of  styleSheet.cssRules) {
        console.log(cssRule.cssText); // Prints each css rule in our stylesheets
      }
    }
    
    추가 정보 CSSRule

    2. :blank 위조 포지셔닝 선택기 사용
    현재 우리는 모든 CSS 규칙에 접근할 수 있으며, 그 중 :blank 위류가 있는지 확인할 수 있습니다.
    const blankRegex = /(.*)\[blank\]/;
    for(let  styleSheet  of  document.styleSheets) {
      for(let  cssRule  of  styleSheet.cssRules) {
        const match = cssRule.selectorText.match(blankRegex);
        if(match) {console.log(match[1]);} // Prints matched selector name i.e input, textarea without the [blank]
      }
    }
    
    🛑 재구축 둘레길
    코드가 혼란스럽지 않도록 재구성해 봅시다.
    함수를 정의하는 것부터 시작합시다. 이 함수는 선택기 그룹을 되돌려줍니다.
    const extractBlankSelectors = () => {
          const blankRegex = /(.*)\[blank\]/;
          // Returns an array of of all CSSRules
          const cssRules = 
            [...document.styleSheets]
              .map(styleSheet => [...styleSheet.cssRules])
              .flat();
    
          // Returns an array with our desired selectors
          const blankSelectors = 
            cssRules.map(cssRule => cssRule.selectorText)
                    .reduce((acc, curr) => acc.concat(curr.split(",")), [])
                    .map(selectorText => selectorText.match(blankRegex) ? selectorText.match(blankRegex)[1] : null)
                    .filter(selector => !!selector);
    
          return blankSelectors;
        };
    
    여기에서, 나는 함수 방법을 사용했다. 예전처럼 for 순환을 사용하지 않았지만, for 순환을 끼워 넣는 것을 통해 같은 효과를 실현할 수 있다.만약 이 일이 이상하거나 곤혹스럽다고 생각한다면, 괜찮은 article 토론을 해 보세요.논평 부분에서 자유롭게 질문할 수도 있다.
    🛑재구성해서 길을 돌아서 가다

    3,4. 공백 위조류를 선택한 요소에 귀속시키고 변경 사항을 관찰합니다!
    현재 우리는 extractBlankSelectors를 통해 필요한 선택기에 접근할 수 있으며 목표 요소에 속성을 쉽게 선택하고 추가할 수 있다.
    ....
        const bindBlankElements = () => {
          // Select all elements from DOM that match our SelectorList
          const elements = document.querySelectorAll(extractBlankSelectors().join(','));
          elements.forEach(element => {
            // Add blank attribute if value is empty
            if(element.value === '') {
              element.setAttribute('blank', '');
            }
            // Attach an input event listener
            element.addEventListener('input', (ev) => {
              element.value === '' ? element.setAttribute('blank', '') : element.removeAttribute('blank', '');
            });
          });
        };
    
    처음에 우리는 extractBlankSelectors에서 되돌아오는 모든 요소를 선택했다.그리고 각각:
  • 값이 비어 있으면 공백 속성을 추가합니다.
  • 에 입력 이벤트 탐지기를 추가합니다.
    eah 입력에서 입력 값이 비어 있는지 확인하고 blank 속성을 적용합니다.
  • 다음은 현장에서 시험적으로 사용하는 코드 펜입니다.
    봐라!우리 다 망했어!

    결론
    보시다시피polyfills는 웹의 발전을 돕고 개발자가 호환성을 파괴하지 않고 새로운 기능을 사용할 수 있도록 도와주는 매우 중요한 개념입니다.만약 당신이 이렇게 읽는 것을 좋아한다면, 공유하거나 댓글을 남겨라.피드백을 환영합니다!
    오래오래 살다🖖

    유용한 링크
  • A List of cross browser polyfills
  • Remy Sharp's original post about polyfills
  • A third link
  • 좋은 웹페이지 즐겨찾기