成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

構(gòu)建自己的React:(1)Rendering DOM elements

Turbo / 1233人閱讀

摘要:我們用原生的對(duì)象來(lái)描述我們要渲染的東西,并稱這類對(duì)象為。下一步是將元素及其子元素渲染成。所以,將會(huì)使用來(lái)表示文本節(jié)點(diǎn),并使用來(lái)裝文本值。創(chuàng)建添加事件監(jiān)聽(tīng)設(shè)置屬性遞歸渲染子元素將添加到父內(nèi)我們目前創(chuàng)建了一個(gè)可以渲染元素及其子元素為的方法。

翻譯自這里:https://engineering.hexacta.c...
本系列的目的是創(chuàng)建類似于React的一個(gè)簡(jiǎn)易的工具庫(kù)。

DOM review

開(kāi)始之前,我們先看下我們要用到的DOM API:

// 通過(guò)id查找元素
const domRoot = document.getElementById("root");
// 根據(jù)執(zhí)行標(biāo)簽名創(chuàng)建元素
const domInput = document.createElement("input");
// 設(shè)置元素屬性
domInput["type"] = "text";
domInput["value"] = "Hi world";
domInput["className"] = "my-class";
// 添加事件監(jiān)聽(tīng)
domInput.addEventListener("change", e => alert(e.target.value));
// 創(chuàng)建文本節(jié)點(diǎn)
const domText = document.createTextNode("");
// 設(shè)置節(jié)點(diǎn)內(nèi)容
domText["nodeValue"] = "Foo";
// 往頁(yè)面上添加元素
domRoot.appendChild(domInput);
// 往頁(yè)面上添加文本節(jié)點(diǎn)
domRoot.appendChild(domText);

注意到這里我們給元素設(shè)置了properties而不是attributes,而且只有有效的properties才能被設(shè)置。

Didact Elements

我們用原生的JS對(duì)象來(lái)描述我們要渲染的東西,并稱這類對(duì)象為Didact Elements。這些元素對(duì)應(yīng)的JS對(duì)象都有兩個(gè)必要的屬性:typeprops。type可以是個(gè)字符串也可以是一個(gè)函數(shù),但在我們介紹組件之前我們先只使用字符串。props是一個(gè)可以為空(null)的對(duì)象。props下還可以含有children屬性,children屬性值為一個(gè)裝有Didact Elements的數(shù)組。

我們后面將會(huì)頻繁的使用Didact Elements,所以我們會(huì)用元素稱呼Didact Elements。不要和HTML的元素搞混了,HTML元素會(huì)被稱作DOM元素或者使用命名變量時(shí)干脆就叫dom

舉個(gè)例子,我們會(huì)用下面這個(gè)對(duì)象:

const element = {
  type: "div",
  props: {
    id: "container",
    children: [
      { type: "input", props: { value: "foo", type: "text" } },
      { type: "a", props: { href: "/bar" } },
      { type: "span", props: {} }
    ]
  }
};

來(lái)描述下面這個(gè)dom:

Didact Elements和React Elements很像。但通常情況下你不會(huì)使用JS手動(dòng)去創(chuàng)建一個(gè)React Elements,更多的是使用JSX或者是createElement方法來(lái)創(chuàng)建。在Didact中我們也會(huì)使用相同的方法創(chuàng)建元素,但會(huì)將這部分內(nèi)容放在下一節(jié)。

Render DOM Elements

下一步是將元素及其子元素渲染成dom。我們使用render(類似于ReactDOM.render)方法來(lái)接收一個(gè)元素和一個(gè)dom容器。這個(gè)方法會(huì)將這個(gè)元素描述的dom結(jié)構(gòu)創(chuàng)建出來(lái),并添加到容器內(nèi)。

function render(element, parentDom){
    const { type, props } = element;
    const dom = document.createElement(type);
    const childElements = props.children || [];
    childElements.forEach(childElement => render(childElement, dom));
    parentDom.appendChild(dom);
}

我們現(xiàn)在仍沒(méi)有處理屬性和事件。我們先用Object.keys來(lái)獲取props中的屬性名字,然后循環(huán)將它們?cè)O(shè)定到元素上:

function render(element, parentDom){
    const { type, props } = element;
    const dom = document.createElement(type);
    
    const isListener = name => name.startsWith("on");
    Object.keys(props).filter(isListener).forEach(name => {
        const eventType = name.toLowerCase().substring(2);
        dom.addEventListener(eventType, props[name]);
    })
    
    const isAttribute = name => !isListener(name) && name != "children";
    Object.keys(props).filter(isAttribute).forEach(name => {
        dom[name] = props[name];
    })
    
    const childElements = props.children || [];
    childElements.forEach(childElement => render(childElement, dom));
    parentDom.appendChild(dom);
}
Render DOM Text Nodes

目前render還不支持文本節(jié)點(diǎn)。首先我們要定義文本節(jié)點(diǎn)是什么樣的。在react中,一個(gè)Foo這樣的元素需要這樣描述:

const reactElement = {
  type: "span",
  props: {
    children: ["Foo"]
  }
}

注意到這里的子元素已經(jīng)不是對(duì)象,而只是一個(gè)字符串。這和我們對(duì)Didact Elements的定義有不一樣:children應(yīng)該是裝有Didact Elements的數(shù)組,并且所有元素都有typeprops屬性。如果我們繼續(xù)遵守這個(gè)規(guī)則接下來(lái)我們將較少使用if的次數(shù)。所以,Didact Elements將會(huì)使用type="TEXT_ELEMENT"來(lái)表示文本節(jié)點(diǎn),并使用nodeValue來(lái)裝文本值。例如下面這樣:

const textElement = {
  type: "span",
  props: {
    children: [
      {
        type: "TEXT_ELEMENT",
        props: { nodeValue: "Foo" }
      }
    ]
  }
};

現(xiàn)在我們已經(jīng)定義好了能夠渲染的文本節(jié)點(diǎn)。和其他節(jié)點(diǎn)不同的是,文本節(jié)點(diǎn)需要使用createTextNode來(lái)創(chuàng)建而不是createElement,而nodeValue會(huì)通過(guò)相同方法來(lái)設(shè)置。

function render(element, parentDom) {
  const { type, props } = element;

  // 創(chuàng)建DOM
  const isTextElement = type === "TEXT_ELEMENT";
  const dom = isTextElement
    ? document.createTextNode("")
    : document.createElement(type);

  // 添加事件監(jiān)聽(tīng)
  const isListener = name => name.startsWith("on");
  Object.keys(props).filter(isListener).forEach(name => {
    const eventType = name.toLowerCase().substring(2);
    dom.addEventListener(eventType, props[name]);
  });

  // 設(shè)置屬性
  const isAttribute = name => !isListener(name) && name != "children";
  Object.keys(props).filter(isAttribute).forEach(name => {
    dom[name] = props[name];
  });

  // 遞歸渲染子元素
  const childElements = props.children || [];
  childElements.forEach(childElement => render(childElement, dom));

  // 將dom添加到父dom內(nèi)
  parentDom.appendChild(dom);
}
Summary

我們目前創(chuàng)建了一個(gè)可以渲染元素及其子元素為DOM的render方法。下一步我們需要一個(gè)快速簡(jiǎn)單的方法來(lái)創(chuàng)建元素。下一節(jié)我們將在Didact中使用JSX。

下一節(jié):

https://engineering.hexacta.c...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/99669.html

相關(guān)文章

  • React之渲染元素

    摘要:渲染元素開(kāi)場(chǎng)白接著上一節(jié)的講解后我們大概清楚了以下幾個(gè)事兒知道是個(gè)什么東東為什么要推薦使用以及的一些基本語(yǔ)法。本篇文章談一下是怎么渲染元素的。更新已渲染的元素元素是不可變的,一旦你創(chuàng)建了一個(gè)元素,就不能再修改其子元素或任何屬性。 React-渲染元素 開(kāi)場(chǎng)白 接著上一節(jié)JSX的講解后:我們大概清楚了以下幾個(gè)事兒: 知道JSX是個(gè)什么東東 為什么React要推薦使用JSX 以及JSX...

    Jenny_Tong 評(píng)論0 收藏0
  • React diff算法

    摘要:傳統(tǒng)算法通過(guò)循環(huán)遞歸對(duì)節(jié)點(diǎn)進(jìn)行依次對(duì)比,效率低下,算法復(fù)雜度達(dá)到,其中是樹(shù)中節(jié)點(diǎn)的總數(shù)。對(duì)于同一層級(jí)的一組子節(jié)點(diǎn),它們可以通過(guò)唯一進(jìn)行區(qū)分。當(dāng)發(fā)現(xiàn)節(jié)點(diǎn)已經(jīng)不存在,則該節(jié)點(diǎn)及其子節(jié)點(diǎn)會(huì)被完全刪除掉,不會(huì)用于進(jìn)一步的比較。 https://zhuanlan.zhihu.com/p/... React diff 會(huì)幫助我們計(jì)算出 Virtual DOM 中真正變化的部分,并只針對(duì)該部分進(jìn)行實(shí)...

    caozhijian 評(píng)論0 收藏0
  • React官網(wǎng)RECENT POSTS閱讀

    摘要:事件行為在瀏覽器中保持一次,并且符合標(biāo)準(zhǔn)。主要是進(jìn)行修復(fù)。事件已經(jīng)在移動(dòng)上支持。阻止已經(jīng)在上存在的事件錯(cuò)誤處理。然后對(duì)應(yīng)的將會(huì)被打包送往客戶端。在中棄用,現(xiàn)在正式刪除。是運(yùn)行于一個(gè)嚴(yán)格的安全策略下成為可能。增加警告提示非生產(chǎn)環(huán)境。 ??寫(xiě)在開(kāi)頭 閱讀React官網(wǎng)的 RECENT POSTS的個(gè)人翻譯/摘要(部分)。 英文片段為官網(wǎng)原文片段。 原文地址 ??為什么要使用React ...

    Sike 評(píng)論0 收藏0
  • 【譯】渲染Elements

    摘要:注不做翻譯是中最小的構(gòu)建部件。在里渲染讓我們看一下在下面有在你文件中無(wú)處不在的標(biāo)簽我們會(huì)把這元素成為元素因?yàn)榈乃袞|西都會(huì)放在這個(gè)元素里面。通過(guò)方法,我們能吧渲染到我們根節(jié)點(diǎn)上。更新被渲染的是不可變的。 下面是react官方文檔的個(gè)人翻譯,如有翻譯錯(cuò)誤,請(qǐng)多多指出原文地址:https://facebook.github.io/re...特別感謝Hevaen,同時(shí)也向豪大React群所有...

    LoftySoul 評(píng)論0 收藏0
  • 【譯】介紹JSX

    摘要:介紹我們來(lái)看一下下面的變量聲明這是有意思的標(biāo)記語(yǔ)法既不是字符串又不是。也是一個(gè)表達(dá)式編譯后表達(dá)式成為常規(guī)的對(duì)象。防止注入攻擊中直接嵌套用戶在表單表單中輸入的值是安全的。這有助于防止攻擊跨站腳本。讀取這些對(duì)象并使用它們構(gòu)造并保持更新。 下面是react官方文檔的個(gè)人翻譯,如有翻譯錯(cuò)誤,請(qǐng)多多指出原文地址:https://facebook.github.io/re...特別感謝Hevaen...

    ymyang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<