LitElement 및 VanillaJS에 트위터 삽입

작업 관점에서 약간의 팔레트 청소가 필요했기 때문에 문제 대기열을 파고들고 내가 생각한 것이 쉬울 것이라고 생각했습니다. Embedding twitter conversations #370

그런 다음 시작하면서 "음.. 이것은 유용한 튜토리얼이 될 것 같습니다."라고 생각하여 사람들이 원하는 내용을 물었습니다.






${this.btoPro}










내가 그것을 어떻게 만들었는지 보여주기 위해 비디오를 만들 예정인 twitter-embed에서 작업하고 있습니다/dev[dot]to에 대한 프로세스 및 포스트를 통해 이야기합니다. 나는 그것을 0에서 끝까지 끝까지 할 생각입니다/그것을하는 다른 방법을 보여주십시오; 답글의 생각


오후 14:43 - 2020년 8월 26일





1

1



다음은 전체 동영상 안내입니다. 아래에 코드와 다루는 내용을 게시하겠습니다.



비디오의 링크


  • NPM:
  • 출처:
  • Iframe 샌드박스: https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
  • Iframe 지연 로드: https://web.dev/iframe-lazy-loading/

  • VanillaJS



    바닐라 버전의 코드는 다음과 같습니다. 100줄입니다.

    class TwitterEmbed extends HTMLElement {
      static get tag() {
        return "twitter-embed";
      }
      /**
       * HTMLElement spec / class based architecture in general
       */
      constructor() {
        super();
        this.dataWidth = this.getAttribute("data-width")
          ? this.getAttribute("data-width")
          : "550px";
        this.dataTheme = this.getAttribute("data-theme")
          ? this.getAttribute("data-theme")
          : "light";
        this.tweet = this.getAttribute("tweet") ? this.getAttribute("tweet") : null;
        this.tweetId = this.getAttribute("tweet-id")
          ? this.getAttribute("tweet-id")
          : null;
        this.allowPopups = this.getAttribute("no-popups") ? "" : "allow-popups";
      }
      /**
       * HTMLElement spec
       */
      static get observedAttributes() {
        return ["tweet", "data-width", "data-theme", "tweet-id", "no-popups"];
      }
      /**
       * HTMLElement spec
       */
      attributeChangedCallback(attr, oldValue, newValue) {
        if (attr == "tweet" && newValue && newValue.includes("twitter.com")) {
          this.tweetId = newValue.split("/").pop();
        }
        if (attr == "no-popups") {
          this.allowPopups =
            newValue == "no-popups" ||
            newValue == "" ||
            !newValue ||
            newValue == null ||
            newValue == "null"
              ? ""
              : "allow-popups";
        }
        if (["no-popups", "tweet-id", "data-width", "data-theme"].includes(attr)) {
          this.innerHTML = this.html;
        }
      }
      get dataWidth() {
        return this.getAttribute("data-width");
      }
      set dataWidth(value) {
        if (value == null || !value) {
          this.removeAttribute("data-width");
        } else {
          this.setAttribute("data-width", value);
        }
      }
      get dataTheme() {
        return this.getAttribute("data-theme");
      }
      set dataTheme(value) {
        if (!value || !["dark", "light"].includes(value)) {
          this.dataTheme = "light";
        } else {
          this.setAttribute("data-theme", value);
        }
      }
      get tweetId() {
        return this.getAttribute("tweet-id");
      }
      set tweetId(value) {
        if (value == null) {
          this.removeAttribute("tweet-id");
        } else {
          this.setAttribute("tweet-id", value);
        }
      }
      get tweet() {
        return this.getAttribute("tweet");
      }
      set tweet(value) {
        if (value == null) {
          this.removeAttribute("tweet");
        } else {
          this.setAttribute("tweet", value);
        }
      }
      /**
       * my own convention, easy to remember
       */
      get html() {
        return `
        <div
          class="twitter-tweet twitter-tweet-rendered"
          style="display: flex; max-width: ${
            this.dataWidth
          }; width: 100%; margin-top: 10px; margin-bottom: 10px;">
          <iframe
            sandbox="allow-same-origin allow-scripts ${this.allowPopups}"
            scrolling="no"
            frameborder="0"
            loading="lazy"
            allowtransparency="true"
            allowfullscreen="true"
            style="position: static; visibility: visible; width: ${
              this.dataWidth
            }; height: 498px; display: block; flex-grow: 1;"
            title="Twitter Tweet"
            src="https://platform.twitter.com/embed/index.html?dnt=true&amp&amp;frame=false&amp;hideCard=false&amp;hideThread=false&amp;id=${
              this.tweetId
            }&amp;lang=en&amp;origin=http%3A%2F%2Flocalhost%3A8000%2Felements%2Ftwitter-embed%2Fdemo%2Findex.html&amp;theme=${
          this.dataTheme
        }&amp;widgetsVersion=223fc1c4%3A1596143124634&amp;width=${this.dataWidth}"
            data-tweet-id="${this.tweetId}">
          </iframe>
        </div>`;
      }
    }
    customElements.define(TwitterEmbed.tag, TwitterEmbed);
    export { TwitterEmbed };
    

    장점


  • 0 종속성
  • 플랫폼 수준 코드만, 모든 유효한 규칙
  • 은 이론적으로 모든 플랫폼
  • 에서 영구적으로 작동해야 합니다.

    단점


  • 예상대로 데이터 바인딩을 얻기 위한 장황함
  • 몇 가지 이상한 생성자 항목/기본 값 항목
  • re-renders are heavy handed

  • 조명 요소



    LitElement는 인기 있는

    import { LitElement, html } from "lit-element/lit-element.js";
    class TwitterEmbedLit extends LitElement {
      static get tag() {
        return "twitter-embed-lit";
      }
      /**
       * HTMLElement spec
       */
      constructor() {
        super();
        this.dataWidth = "550px";
        this.dataTheme = "light";
        this.tweet = null;
        this.tweetId = null;
        this.allowPopups = "allow-popups";
      }
      /**
       * LitElement properties definition
       */
      static get properties() {
        return {
          tweet: {
            type: String
          },
          dataWidth: {
            type: String,
            attribute: "data-width"
          },
          dataTheme: {
            type: String,
            attribute: "data-theme"
          },
          tweetId: {
            type: String,
            attribute: "tweet-id"
          },
          noPopups: {
            type: Boolean,
            attribute: "no-popups"
          },
          allowPopups: {
            type: String
          }
        };
      }
      /**
       * LitElement equivalent of attributeChangedCallback
       */
      updated(changedProperties) {
        changedProperties.forEach((oldValue, propName) => {
          if (propName === "noPopups") {
            if (this[propName]) {
              this.allowPopups = "";
            } else {
              this.allowPopups = "allow-popups";
            }
          }
          if (
            propName === "tweet" &&
            this[propName] &&
            this[propName].includes("twitter.com")
          ) {
            this.tweetId = this[propName].split("/").pop();
          }
        });
      }
      /**
       * Popular convention / LitElement
       */
      render() {
        return html`
          <div
            class="twitter-tweet twitter-tweet-rendered"
            style="display: flex; max-width: ${this
              .dataWidth}; width: 100%; margin-top: 10px; margin-bottom: 10px;"
          >
            <iframe
              sandbox="allow-same-origin allow-scripts ${this.allowPopups}"
              scrolling="no"
              frameborder="0"
              loading="lazy"
              allowtransparency="true"
              allowfullscreen
              style="position: static; visibility: visible; width: ${this
                .dataWidth}; height: 498px; display: block; flex-grow: 1;"
              title="Twitter Tweet"
              src="https://platform.twitter.com/embed/index.html?dnt=true&amp;frame=false&amp;hideCard=false&amp;hideThread=false&amp;id=${this
                .tweetId}&amp;lang=en&amp;origin=http%3A%2F%2Flocalhost%3A8000%2Felements%2Ftwitter-embed%2Fdemo%2Findex.html&amp;theme=${this
                .dataTheme}&amp;widgetsVersion=223fc1c4%3A1596143124634&amp;width=${this
                .dataWidth}"
              data-tweet-id="${this.tweetId}"
            >
            </iframe>
          </div>
        `;
      }
    }
    
    customElements.define(TwitterEmbedLit.tag, TwitterEmbedLit);
    export { TwitterEmbedLit };
    

    단점


  • 종속성 1개
  • 일부 라이브러리 관련 규칙

  • 장점


  • 규칙은 간단합니다
  • lit-html 템플릿 재작성 규칙이 향후 플랫폼 수준 코드가 될 수 있음
  • 깔끔한 코드, 쓰기가 약간 적고 읽기 쉬움
  • 더 빠르게 다시 렌더링하지만 이 예
  • 에서 보기에는 매우 작습니다.

    좋은 웹페이지 즐겨찾기