精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

React + TypeScript:如何處理常見事件?

開發(fā) 前端
在 React 中是不支持直接定義 onResize 事件的。可以使用瀏覽器原生支持的 window.resize 事件,當(dāng)瀏覽器窗口發(fā)生變化時(shí)會(huì)觸發(fā)改事件。

大家好,我是 CUGGZ。之前分享過一篇《使用 TypeScript 編寫 React 的最佳實(shí)踐!》,文中介紹了 React 和 TypeScript 搭配使用的一些常見用法。其中第四部分介紹了在React的事件處理中如何定義事件類型,下面來(lái)通過一些簡(jiǎn)單的 Demo (每個(gè) Demo 后面都有 CodeSandBox 的在線體驗(yàn)地址)看看如何在 React + TypeScrip 中處理常見的事件!

目錄:

  1. onClick
  2. onChange
  3. onScroll
  4. onSubmit
  5. onCopy、onCut、onPaste
  6. onMouseOver、onMouseOut
  7. onLoad、onError
  8. onkeydown、onkeypress、onkeyup
  9. onFocus、onBlur
  10. onDragStart、onDrop、onDragOver
  11. window.resize

1. onClick

onClick 是用的最多的事件之一,這里主要列舉兩種類型的 onClick 事件:

  • button按鈕的onClick事件;
  • 任意元素的的onClick事件。

下面先來(lái)看看按鈕的 onClick 事件,當(dāng)點(diǎn)擊按鈕時(shí),在頁(yè)面顯示按鈕的名稱:

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [clickedButton, setClickedButton] = useState("");

  const buttonHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
    event.preventDefault();
    const button: HTMLButtonElement = event.currentTarget;
    setClickedButton(button.name);
  };

  return (
    <div className="container">
      <form>
        <button onClick={buttonHandler} className="button" name="button 1">
          Button 1
        </button>

        <button onClick={buttonHandler} className="button" name="button 2">
          Button 2
        </button>

        <button onClick={buttonHandler} className="button" name="button 3">
          Button 3
        </button>
      </form>
      <h1>
        {clickedButton !== "" ? `點(diǎn)擊了 ${clickedButton}` : "沒有點(diǎn)擊任何按鈕"}
      </h1>
    </div>
  );
};

export default App;

可以看到,onClick 事件的事件處理對(duì)象的類型都定義為了 MouseEvent,其中傳入的參數(shù)為綁定事件的元素的類型。可以通過事件對(duì)象的 currentTarget 屬性來(lái)獲取點(diǎn)擊元素的屬性。

在線體驗(yàn):https://codesandbox.io/s/dawn-feather-8gofq1

再來(lái)看看任意元素的 onClick事件,點(diǎn)擊一個(gè)元素時(shí),在控制臺(tái)打印點(diǎn)擊元素的類型、長(zhǎng)度、寬度:

import React from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  // 當(dāng) container 被點(diǎn)擊時(shí),觸發(fā)該事件
  const divClickedHandler = (event: React.MouseEvent<HTMLDivElement>) => {
    const div = event.currentTarget;
    console.log(
      "ElementName: ", div.tagName,
      "Width: ", div.clientWidth,
      "Height: ", div.clientHeight
    );
  };

  // 當(dāng) h1 被點(diǎn)擊時(shí),觸發(fā)該事件
  const headingClickedHandler = (event: React.MouseEvent<HTMLHeadingElement>) => {
    event.stopPropagation();

    const heading = event.currentTarget;
    console.log(
      "ElementName: ", heading.tagName,
      "Width: ", heading.clientWidth,
      "Height: ", heading.clientHeight
    );
  };

  // 當(dāng)圖片被點(diǎn)擊時(shí),觸發(fā)該事件
  const imgClickedHandler = (event: React.MouseEvent<HTMLImageElement>) => {
    event.stopPropagation();
    
    const img = event.currentTarget;
    console.log(
      "ElementName: ", img.tagName,
      "Width: ", img.clientWidth,
      "Height: ", img.clientHeight
    );
  };

  return (
    <div className="container" onClick={divClickedHandler}>
      <h1 onClick={headingClickedHandler}>Hello World</h1>
      <img
        src="https://resource-1255585089.cos.ap-beijing.myqcloud.com/111.png"
        alt="111"
        onClick={imgClickedHandler}
      />
    </div>
  );
};

export default App;

可以看到,onClick 事件的事件處理對(duì)象的類型都定義為了 MouseEvent,其中傳入的參數(shù)為綁定事件的元素的類型。需要注意,在任意元素上添加點(diǎn)擊事件時(shí),會(huì)觸發(fā)事件冒泡,比如上面的例子,當(dāng)點(diǎn)擊是圖片或者h(yuǎn)1標(biāo)簽時(shí)就會(huì)導(dǎo)致其父元素div的點(diǎn)擊事件觸發(fā)。可以使用下面的代碼來(lái)避免默認(rèn)事件:

event.stopPropagation();

在線體驗(yàn):https://codesandbox.io/s/serverless-glade-g41upi

2. onChange

下面來(lái)看看 onChange 事件,先來(lái)看 select 元素的 onChange 事件的例子,當(dāng)選中元素時(shí),選中元素的值會(huì)顯示在頁(yè)面上:

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [selectedOption, setSelectedOption] = useState<String>();

  const selectChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    const value = event.target.value;
    setSelectedOption(value);
  };

  return (
    <div className="container">
      <select onChange={selectChange} className="select">
        <option selected disabled>
          選擇一個(gè)
        </option>
        <option value="blue">Blue</option>
        <option value="red">Red</option>
        <option value="green">Green</option>
        <option value="yellow">Yellow</option>
      </select>
      {selectedOption && <h2 className="result">{selectedOption}</h2>}
    </div>
  );
};

export default App;

可以看到,select 元素的 onSelect 的事件對(duì)象類型為 ChangeEvent,傳入的參數(shù)為 select 元素的類型。可以通過 target 屬性來(lái)獲取 select選中的值。

在線體驗(yàn):https://codesandbox.io/s/frosty-lichterman-33fpky

input 元素的 onChange 事件的例子,在輸入框中輸入內(nèi)容,點(diǎn)擊搜索按鈕,在頁(yè)面顯示搜索結(jié)果:

import React, { useState } from "react";
import "./styles.css";

interface Item {
  id: number;
  name: string;
  price: number;
}

const PRODUCTS: Item[] = [
  {
    id: 1,
    name: "Apple",
    price: 1
  },
  {
    id: 2,
    name: "Book",
    price: 5
  },
  {
    id: 3,
    name: "Banana",
    price: 0.5
  },
  {
    id: 4,
    name: "Table",
    price: 200
  }
];

const App: React.FunctionComponent = () => {
  const [query, setQuery] = useState("");
  const [result, setResult] = useState<Item[] | undefined>();

  // 當(dāng) input 的內(nèi)容改變時(shí)觸發(fā)
  const inputHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
    const enteredName = event.target.value;
    setQuery(enteredName);
  };

  // 點(diǎn)擊搜索時(shí)觸發(fā)
  const search = () => {
    const foundItems = PRODUCTS.filter((item) =>
      item.name.toLowerCase().includes(query.toLowerCase())
    );
    setResult(foundItems);
  };

  return (
    <div className="container">
      <div className="wrapper">
        <input
          value={query}
          onChange={inputHandler}
          placeholder="輸入要搜索的商品名稱"
          className="input"
        />

        <button onClick={search}>搜索</button>
      </div>

      <div className="search-result">
        {result && result.length > 0 ? (
          result.map((item) => (
            <li key={item.id} className="item">
              <span className="item-id">{item.id}</span>
              <span className="item-name">{item.name}</span>
              <span className="item-price">{item.price}¥</span>
            </li>
          ))
        ) : (
          <h2>沒有找到!</h2>
        )}
      </div>
    </div>
  );
};

export default App;

可以看到,這里input 的事件處理對(duì)象的類型為 ChangeEvent。要想獲取輸入的值需要從事件對(duì)象的 target 屬性中獲取。

在線體驗(yàn):https://codesandbox.io/s/pedantic-murdock-lejmg6

3. onScroll

onScroll 事件在元素的滾動(dòng)條被滾動(dòng)時(shí)觸發(fā)。

下面來(lái)看一個(gè)例子,當(dāng)元素發(fā)生滾動(dòng)時(shí),計(jì)算滾動(dòng)了多少的元素,從而計(jì)算頁(yè)面滾動(dòng)進(jìn)度的百分比值,并顯示在頁(yè)面上:

import React, { useState } from "react";
import "./styles.css";

const DUMMY_DATA = Array.from({ length: 100 }, (x, i) => {
  return {
    id: i,
    title: `Item ${i}`
  };
});

const App: React.FunctionComponent = () => {
  const [progress, setProgress] = useState(0);
  
  // 當(dāng)元素發(fā)生滾動(dòng)時(shí)觸發(fā)該事件
  const scrollHandler = (event: React.UIEvent<HTMLDivElement>) => {
    const containerHeight = event.currentTarget.clientHeight;
    const scrollHeight = event.currentTarget.scrollHeight;
    const scrollTop = event.currentTarget.scrollTop;
    setProgress(((scrollTop + containerHeight) / scrollHeight) * 100);
  };

  return (
    <>
      <div className="container" onScroll={scrollHandler}>
        <div className="list">
          {DUMMY_DATA.map((item) => (
            <div className="item" key={item.id}>
              {item.title}
            </div>
          ))}
        </div>
      </div>

      <div className="progressBar">
        <div className="progressValue" style={{ width: `${progress}%` }}></div>
      </div>
      <p className="text">{progress.toFixed(2)}%</p>
    </>
  );
};

export default App;

可以看到,onScroll 事件的事件對(duì)象類型定義為了:React.UIEvent<HTMLDivElement>,參數(shù)為綁定事件的元素的類型。可以通過事件對(duì)象的 currentTarget 屬性來(lái)獲取頁(yè)面滾動(dòng)的相關(guān)值。

在線體驗(yàn):https://codesandbox.io/s/competent-hellman-qh7non

4. onSubmit

下面來(lái)看看表單的 onSubmit 事件,該事件在表單提交時(shí)觸發(fā):

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [term, setTerm] = useState("");

  const submitForm = (event: React.FormEvent<HTMLFormElement>) => {
    // 防止頁(yè)面重新加載
    event.preventDefault();
    alert(term);
  };

  return (
    <div className="container">
      <form onSubmit={submitForm}>
        <input
          value={term}
          onChange={(e) => setTerm(e.target.value)}
          type="text"
          className="input"
        />
        <button type="submit" className="btn">
          提交
        </button>
      </form>
    </div>
  );
};

export default App;

表單提交事件的時(shí)間對(duì)象類型為 FormEvent。需要注意,為了防止頁(yè)面在表單的 onSubmit事件觸發(fā)時(shí)重新加載,需要調(diào)用:

event.preventDefault();

在線體驗(yàn):https://codesandbox.io/s/condescending-danny-e1eerd

5. onCopy、onCut、onPaste

下面來(lái)看看常見的復(fù)制、剪切、粘貼這三個(gè)時(shí)間:

  • onCopy:在用戶復(fù)制元素或元素的內(nèi)容(如文本、圖像)時(shí)觸發(fā);
  • onPaste:在用戶在元素中粘貼一些內(nèi)容時(shí)觸發(fā);
  • onCut:在用戶剪切元素的內(nèi)容時(shí)發(fā)生,此事件主要用于 input (`type=”text”``) 和 textarea 元素。

下面來(lái)看一個(gè)例子,當(dāng)進(jìn)行復(fù)制、剪切、粘貼時(shí),給操作的元素加上一些樣式:

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [text, setText] = useState("hello world");

  // 復(fù)制:onCopy
  const copyHandler = (event: React.ClipboardEvent<HTMLInputElement>) => {
    event.currentTarget.style.border = "3px solid green";
  };

  // 剪切:onCut
  const cutHandler = (event: React.ClipboardEvent<HTMLInputElement>) => {
    event.currentTarget.style.border = "3px solid orange";
    event.currentTarget.style.backgroundColor = "yellow";
    event.currentTarget.disabled = true;
    setText("內(nèi)容被剪切啦");
  };

  // 粘貼:onPaste
  const pasteHandler = (event: React.ClipboardEvent<HTMLTextAreaElement>) => {
    event.currentTarget.style.border = "5px solid purple";
    event.currentTarget.style.backgroundColor = "orange";
    event.currentTarget.value = event.clipboardData.getData("text").toUpperCase();
    event.preventDefault();
  };

  return (
    <div className="container">
      <input type="text" value={text} onCopy={copyHandler} onCut={cutHandler} />
      <hr />
      <p>在下方粘貼:</p>
      <textarea onPaste={pasteHandler} className="text-area"></textarea>
    </div>
  );
};

export default App;

可以看到,這三個(gè)事件的事件處理對(duì)象的類型都定義為了 ClipboardEvent,其中傳入的參數(shù)為綁定事件的元素的類型。可以通過 currentTarget 屬性來(lái)獲取事件對(duì)象的屬性。

在線體驗(yàn):https://codesandbox.io/s/sleepy-keldysh-w5vemj

6. onMouseOver、onMouseOut

onmouseover 和 onmouseout 是常用的兩個(gè)鼠標(biāo)事件:

  • onmouseover:在鼠標(biāo)指針移動(dòng)到指定的對(duì)象上時(shí)觸發(fā);
  • onmouseout:在鼠標(biāo)指針移出指定的對(duì)象時(shí)觸發(fā)。

下面來(lái)看一個(gè)例子,當(dāng)鼠標(biāo)在元素上和移出元素時(shí)給元素添加不同的樣式:

import React from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  // 當(dāng)鼠標(biāo)指針位于box上時(shí),將觸發(fā)此功能
  const boxMouseOverHandler = (event: React.MouseEvent<HTMLDivElement>) => {
    const box: HTMLDivElement = event.currentTarget;
    box.style.backgroundColor = "lightblue";
  };

  // 當(dāng)鼠標(biāo)指針移出box時(shí),將觸發(fā)此功能
  const boxMouseOutHandler = (event: React.MouseEvent<HTMLDivElement>) => {
    const box: HTMLDivElement = event.currentTarget;
    box.style.backgroundColor = "lightgreen";
  };

  // 當(dāng)鼠標(biāo)指針位于輸入框上時(shí),將觸發(fā)此功能
  const inputMouseOverHandler = (event: React.MouseEvent<HTMLInputElement>) => {
    const input: HTMLInputElement = event.currentTarget;
    input.style.backgroundColor = "lime";
  };

  //當(dāng)鼠標(biāo)指針移出輸入框時(shí),將觸發(fā)此功能
  const inputMouseOutHandler = (event: React.MouseEvent<HTMLInputElement>) => {
    const input: HTMLInputElement = event.currentTarget;
    input.style.backgroundColor = "white";
  };

  //當(dāng)鼠標(biāo)指針位于按鈕上時(shí),將觸發(fā)此功能
  const buttonMouseOverHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
    const btn: HTMLButtonElement = event.currentTarget;
    btn.style.border = "3px solid red";
    btn.style.backgroundColor = "orange";
  };

  // 當(dāng)鼠標(biāo)指針移出按鈕時(shí),將觸發(fā)此功能
  const buttonMouseOutHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
    const btn: HTMLButtonElement = event.currentTarget;
    btn.style.border = "none";
    btn.style.backgroundColor = "yellow";
  };

  return (
    <div
      className="box"
      onMouseOver={boxMouseOverHandler}
      onMouseOut={boxMouseOutHandler}
    >
      <input
        onMouseOver={inputMouseOverHandler}
        onMouseOut={inputMouseOutHandler}
        placeholder="hello world"
      />
      <button
        onMouseOver={buttonMouseOverHandler}
        onMouseOut={buttonMouseOutHandler}
      >
        Button
      </button>
    </div>
  );
};

export default App;

可以看到,這兩個(gè)事件的事件處理對(duì)象的類型都定義為了 MouseEvent,其中傳入的參數(shù)為綁定事件的元素的類型。可以通過事件對(duì)象的 currentTarget 來(lái)獲取事件對(duì)象的屬性。

在線體驗(yàn):https://codesandbox.io/s/nervous-cloud-5r6d6p

7. onLoad、onError

onLoad 和 onError 是頁(yè)面外部資源加載相關(guān)的兩個(gè)相關(guān)事件:

  • onload:資源加載失敗;
  • onerror:資源加載出錯(cuò)。

下面來(lái)看一個(gè)例子, 當(dāng)圖片成功時(shí)給它添加類名 success,加載失敗時(shí)添加類型 error,并更換為備用圖片的URL:

import React from "react";
import "./styles.css";

const IMAGE ="https://resource-1255585089.cos.ap-beijing.myqcloud.com/111.png";
const FALLBACK_IMAGE ="https://resource-1255585089.cos.ap-beijing.myqcloud.com/222.png";

const App: React.FunctionComponent = () => {
  const imageOnLoadHandler = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
    // 圖片加載成功時(shí),打印圖片的地址,并添加類名 success
    console.log(event.currentTarget.src);
    if (event.currentTarget.className !== "error") {
      event.currentTarget.className = "success";
    }
  };

  const imageOnErrorHandler = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
    // 圖片加載失敗時(shí),加載替代的圖片,并添加類名 error
    event.currentTarget.src = FALLBACK_IMAGE;
    event.currentTarget.className = "error";
  };

  return (
    <div className="container">
      <img
        src={IMAGE}
        onLoad={imageOnLoadHandler}
        onError={imageOnErrorHandler}
        alt="111"
      />
    </div>
  );
};

export default App;

可以看到,這兩個(gè)事件的事件處理對(duì)象的類型都定義為了 SyntheticEvent,其中傳入的第一個(gè)參數(shù)為綁定事件的元素的類型。可以通過事件對(duì)象的 currentTarget 屬性來(lái)獲取事件對(duì)象的屬性。

在線體驗(yàn):https://codesandbox.io/s/determined-tamas-rjwjoq

8. onkeydown、onkeypress、onkeyup

下面來(lái)看幾個(gè)常見的鍵盤事件:

  • onKeyDown:在用戶按下一個(gè)鍵盤按鍵時(shí)觸發(fā);
  • onKeyUp:在鍵盤按鍵被松開時(shí)觸發(fā);
  • onKeyPress:在鍵盤按鍵被按下并釋放一個(gè)鍵時(shí)發(fā)生。在所有瀏覽器中 onkeypress 事件只能監(jiān)聽字母和數(shù)字,不能監(jiān)聽一些特殊按鍵(ALT、CTRL、SHIFT、ESC、箭頭等)。監(jiān)聽一個(gè)用戶是否按下按鍵請(qǐng)使用 onkeydown 事件,所有瀏覽器都支持 onkeydown 事件。

這三個(gè)事件的執(zhí)行順序如下:

  1. onkeydown
  2. onkeypress
  3. onkeyup

來(lái)看一個(gè)例子,按下ESC鍵可以清除已經(jīng)輸入的文本,按下Enter鍵可以彈出已經(jīng)輸入的文本:

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [enteredText, setEnteredText] = useState("");

  // onKeyDown 事件處理函數(shù)
  const keyDownHandler = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.code === "Enter") {
      alert(`輸入內(nèi)容:"${enteredText}"`);
    }
  };

  // onKeyUp 事件處理函數(shù)
  const keyUpHandler = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.code === "Escape") {
      const confirm = window.confirm("確定清除文本嗎?");

      if (confirm) {
        setEnteredText("");
      }
    }
  };

  // onKeyPress 事件處理函數(shù)
  const keyPressHandler = (event: React.KeyboardEvent<HTMLInputElement>) => {
    //...
  };

  return (
    <div className="container">
      <input
        onKeyDown={keyDownHandler}
        onKeyUp={keyUpHandler}
        onKeyPress={keyPressHandler}
        type="text"
        className="text-input"
        value={enteredText}
        onChange={(e) => setEnteredText(e.target.value)}
      />
    </div>
  );
};

export default App;

這三個(gè)事件的事件對(duì)象類型都是 KeyboardEvent。可以通過事件對(duì)象的 code屬性獲取按下的鍵盤鍵值。

在線體驗(yàn):https://codesandbox.io/s/prod-sky-txwzgd

再來(lái)看一個(gè)簡(jiǎn)單的例子,通過在鍵盤上按下上下左右鍵使得盒子在頁(yè)面上移動(dòng):

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [left, setLeft] = useState(0);
  const [top, setTop] = useState(0);

  // onKeyDown 事件處理函數(shù)
  const keyDownHandler = (event: React.KeyboardEvent<HTMLDivElement>) => {
    console.log(event.code);
    if (event.code === "ArrowUp") {
      setTop((top) => top - 10);
    }

    if (event.code === "ArrowDown") {
      setTop((top) => top + 10);
    }

    if (event.code === "ArrowLeft") {
      setLeft((left) => left - 10);
    }

    if (event.code === "ArrowRight") {
      setLeft((left) => left + 10);
    }
  };

  return (
    <div className="container" tabIndex={0} onKeyDown={keyDownHandler}>
      <div className="box" style={{ top: top, left: left }}></div>
    </div>
  );
};

export default App;

在線體驗(yàn):https://codesandbox.io/s/hungry-meninsky-zhkbzb

9. onFocus、onBlur

  • onfocus:在元素獲得焦點(diǎn)時(shí)觸發(fā),適用于<input>、<select> 以及<a>標(biāo)簽;
  • onblur:在元素失去焦點(diǎn)時(shí)觸發(fā),常用于表單驗(yàn)證。

下面來(lái)看一個(gè)例子,在輸入框中輸入內(nèi)容,輸入過程中保存輸入的值, 當(dāng)輸入完成,失去輸入焦點(diǎn)時(shí),對(duì)輸入內(nèi)容進(jìn)行校驗(yàn):

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [name, setName] = useState("");
  const [isValid, setIsValid] = useState(false);
  const [isFocus, setIsFocus] = useState(false);
  const [isBlur, setIsBlur] = useState(false);

  // 處理 input 的 onChange事件
  const changeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
    setName(event.target.value);
  };

  // 處理 input 的 onFocus 事件
  const focusHandler = (event: React.FocusEvent<HTMLInputElement>) => {
    setIsFocus(true);
    setIsBlur(false);
    console.log(event);
  };

  // 處理 input 的 onBlur 事件
  const blurHandler = (event: React.FocusEvent<HTMLInputElement>) => {
    setIsFocus(false);
    setIsBlur(true);

    if (name.match(/^[a-z][a-z\s]*$/i)) {
      setIsValid(true);
    } else {
      setIsValid(false);
    }
    console.log(event);
  };

  return (
    <div className="container">
      <input
        type="text"
        onFocus={focusHandler}
        onBlur={blurHandler}
        value={name}
        onChange={changeHandler}
        className="input"
        placeholder="請(qǐng)輸入名字"
      />
      {isFocus && <span className="hint">只能輸入字母和空格</span>}
      {isBlur && !isValid && <p className="error">輸入格式錯(cuò)誤</p>}
      {isBlur && isValid && <p className="success">輸入正確</p>}
    </div>
  );
};

export default App;

這里兩個(gè)事件的事件對(duì)象類型都是 FocusEvent,傳入的參數(shù)是 input 元素的類型。

在線體驗(yàn):https://codesandbox.io/s/spring-moon-roegc5

10. onDragStart、onDrop、onDragOver

拖拽操作在HTML5 是作為標(biāo)準(zhǔn)的一部分。能夠使用HTML5所支持的事件和屬性來(lái)實(shí)現(xiàn)拖拽操作。下面是三個(gè)常用的拖拽事件:

  • onDragStart:開始拖拽時(shí)觸發(fā),事件里利用dataTransfer保存拖拽元素的 class 或 id。
  • onDrop:元素放置時(shí)不斷觸發(fā),事件里利用dataTransfer來(lái)獲取所保存的數(shù)據(jù),并進(jìn)行業(yè)務(wù)處理。
  • onDragOver:在拖拽時(shí)不斷觸發(fā),在其中取消默認(rèn)行為可以保證該標(biāo)簽可以放置拖拽元素。
import React, { useState } from "react";
import "./styles.css";

const PHOTO_URL = "https://resource-1255585089.cos.ap-beijing.myqcloud.com/111.png";

const App: React.FunctionComponent = () => {
  const [content, setContent] = useState<string>("Drop Something Here");

  // 開始拖拽時(shí)觸發(fā)改事件
  const dragStartHandler = (event: React.DragEvent<HTMLDivElement>, data: string) => {
    event.dataTransfer.setData("text", data);
  };

  // 在放置時(shí)觸發(fā)該事件
  const dropHandler = (event: React.DragEvent<HTMLDivElement>) => {
    event.preventDefault();
    const data = event.dataTransfer.getData("text");
    setContent(data);
  };

  // 使得第三個(gè)盒子可以放下
  const allowDrop = (event: React.DragEvent<HTMLDivElement>) => {
    event.preventDefault();
  };

  return (
    <div className="container">
      <div
        className="box1"
        onDragStart={(event) => dragStartHandler(event, PHOTO_URL)}
        draggable={true}
      >
        <img src={PHOTO_URL} alt="111" />
      </div>

      <div
        className="box2"
        onDragStart={(event) => dragStartHandler(event, "黃色卡片")}
        draggable={true}
      ></div>

      <div className="box3" onDragOver={allowDrop} onDrop={dropHandler}>
        {content.endsWith(".png") ? (
          <img src={content} alt="" />
        ) : (
          <h2>{content}</h2>
        )}
      </div>
    </div>
  );
};

export default App;

可以看到,兩個(gè)拖拽事件的事件對(duì)象類型都是 DragEvent。可以通過事件對(duì)象的 dataTransfer 來(lái)獲取事件對(duì)象的屬性。

在線體驗(yàn):https://codesandbox.io/s/crazy-cloud-5jejr1

11. window.resize

在 React 中是不支持直接定義 onResize 事件的。可以使用瀏覽器原生支持的 window.resize 事件,當(dāng)瀏覽器窗口發(fā)生變化時(shí)會(huì)觸發(fā)改事件。

可以使用以下兩種方式之一來(lái)設(shè)置事件處理函數(shù):

window.resize = myHandlerFunction;

window.addEventListener('resize', myHandlerFunction);

在 React 中,要在瀏覽器窗口大小發(fā)生變化時(shí)重新渲染組件,可以使用 useStatehook 來(lái)實(shí)現(xiàn):

useEffect(() => {
  window.onresize = myHandlerFunction;
}, []);

useEffect(() => {
  window.addEventListener('resize', myHandlerFunction);
}, []);

下面來(lái)看一個(gè)例子,在改變?yōu)g覽器窗口的大小時(shí),頁(yè)面實(shí)時(shí)顯示瀏覽器窗口的長(zhǎng)度和寬度,并在不同寬度時(shí)顯示不同的背景色:

import React, { useState, useEffect, FunctionComponent } from "react";
import "./styles.css";

interface Size {
  width: number;
  height: number;
}

const App: FunctionComponent = () => {
  const [size, setSize] = useState<Size>();

  const resizeHanlder = () => {
    const width = window.innerWidth;
    const height = window.innerHeight;

    setSize({
      width: width,
      height: height,
    });
  };

  useEffect(() => {
    window.onresize = resizeHanlder;
  }, []);

  return (
    <div
      className="container"
      style={{
        backgroundColor:
          !size || size.width <= 500
            ? "white"
            : size && size.width <= 700
              ? "green"
              : "orange",
      }}
    >
      {size && (
        <>
          <h2>Width: {size.width}</h2>
          <h2>Height: {size.height}</h2>
        </>
      )}
    </div>
  );
};

export default App;

在線體驗(yàn):https://codesandbox.io/s/async-leaf-m62ixj

12. 備忘錄

常見的 Event 事件對(duì)象如下:

  • 剪切板事件對(duì)象:ClipboardEvent<T = Element>
  • 拖拽事件對(duì)象:DragEvent<T = Element>
  • 焦點(diǎn)事件對(duì)象:FocusEvent<T = Element>
  • 表單事件對(duì)象:FormEvent<T = Element>
  • Change事件對(duì)象:ChangeEvent<T = Element>
  • 鍵盤事件對(duì)象:KeyboardEvent<T = Element>
  • 鼠標(biāo)事件對(duì)象:MouseEvent<T = Element, E = NativeMouseEvent>
  • 觸摸事件對(duì)象:TouchEvent<T = Element>
  • 滾輪事件對(duì)象:WheelEvent<T = Element>
  • 動(dòng)畫事件對(duì)象:AnimationEvent<T = Element>
  • 過渡事件對(duì)象:TransitionEvent<T = Element>

常見的元素類型如下:

  • a: HTMLAnchorElement
  • body: HTMLBodyElement
  • br: HTMLBRElement
  • button: HTMLButtonElement
  • div: HTMLDivElement
  • h1: HTMLHeadingElement
  • h2: HTMLHeadingElement
  • h3: HTMLHeadingElement
  • html: HTMLHtmlElement
  • img: HTMLImageElement
  • input: HTMLInputElement
  • ul: HTMLUListElement
  • li: HTMLLIElement
  • link: HTMLLinkElement
  • p: HTMLParagraphElement
  • span: HTMLSpanElement
  • style: HTMLStyleElement
  • table: HTMLTableElement
  • tbody: HTMLTableSectionElement
  • video: HTMLVideoElement
  • audio: HTMLAudioElement
  • meta: HTMLMetaElement
  • form: HTMLFormElement
責(zé)任編輯:武曉燕 來(lái)源: 前端充電寶
相關(guān)推薦

2022-04-19 09:00:52

ReactTypeScript

2023-01-04 10:01:21

ReactTypeScript元素

2017-01-11 18:44:43

React Nativ觸摸事件Android

2015-10-27 10:48:19

2019-08-15 10:20:19

云計(jì)算技術(shù)安全

2024-11-19 10:21:17

vueselect屬性

2020-02-03 16:33:13

數(shù)據(jù)中心運(yùn)營(yíng)商辦公設(shè)備

2012-12-12 09:49:41

2020-12-29 09:11:33

LinuxLinux內(nèi)核

2017-03-13 13:21:34

Git處理大倉(cāng)庫(kù)

2019-12-23 10:20:12

Web圖片優(yōu)化前端

2017-10-26 08:43:18

JavaScript內(nèi)存處理

2021-03-01 07:31:53

消息支付高可用

2018-11-15 08:43:11

交換機(jī)硬件故障軟件故障

2019-11-25 15:44:13

TS數(shù)據(jù)JavaScrip

2021-05-31 10:47:17

SpringSecuritySession

2024-08-26 10:47:22

2010-05-17 10:04:45

2024-04-16 13:32:57

2011-02-28 14:08:31

網(wǎng)速變慢局域網(wǎng)網(wǎng)速
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

黄色一级片国产| 99视频在线| 中文字幕观看av| www.久久东京| 欧美亚一区二区| 日韩第一页在线观看| 蜜桃视频在线观看www| 日韩电影在线一区| 韩国国内大量揄拍精品视频| 性欧美13一14内谢| 日韩精品亚洲专区在线观看| 懂色av一区二区三区| 在线视频精品一区| 亚洲欧洲国产综合| 国产精品自拍av| 国产精品久久久久久久久久尿| 欧美国产在线看| 成人黄色小视频| 亚洲国产成人久久综合一区| 特黄视频免费观看| 久久久成人av毛片免费观看| 一区二区三区不卡在线观看 | 久久久久久蜜桃一区二区| 欧美女同一区| 中文字幕亚洲区| 另类欧美小说| 亚洲国产精品久久人人爱潘金莲| 奇米四色…亚洲| 日韩av电影手机在线观看| 青青草在线观看视频| 日韩啪啪电影网| 国产视频亚洲精品| 性猛交╳xxx乱大交| 日韩五码电影| 欧美日韩视频第一区| 日韩 欧美 高清| 蜜桃视频在线网站| 亚洲成人手机在线| 91亚洲精品国产| 日韩成人伦理| 一区二区三区四区不卡视频| 亚洲精品美女久久7777777| 少妇一区二区三区四区| 国产成人av电影在线播放| 成人啪啪免费看| 国产尤物视频在线观看| 麻豆专区一区二区三区四区五区| 国产成人精品综合| 无码人妻一区二区三区免费| 亚洲综合不卡| 欧美诱惑福利视频| 五月婷婷激情视频| 亚洲永久视频| 日本三级久久久| 免费黄色av片| 日本aⅴ免费视频一区二区三区| 国产成人精品综合久久久| 日韩精品一区二区亚洲av观看| 久久亚洲视频| 国产精品国产三级国产aⅴ浪潮 | 精品国产乱码久久久久久蜜臀| 日本泡妞xxxx免费视频软件| 亚洲超碰在线观看| 精品日韩一区二区三区| 扒开伸进免费视频| 日韩美女精品| 国产午夜精品视频| 成人免费精品动漫网站| 欧美va天堂在线| 午夜精品视频在线| 国产又大又黄又粗| 琪琪一区二区三区| 亚洲一区免费网站| 狠狠躁夜夜躁av无码中文幕| 久久久天堂av| 亚洲一区二区三区免费看| 久热国产在线| 精品国产成人av| 色综合色综合色综合色综合| 欧美日韩黄色| 亚洲精品小视频在线观看| 免费看的黄色录像| 激情文学一区| 国产精品18久久久久久首页狼| 国产精品伦一区二区三区| 成人网页在线观看| 午夜欧美性电影| 欧美激情成人动漫| 日本道精品一区二区三区 | 久久久久久无码精品大片| 美女视频第一区二区三区免费观看网站| 成人激情视频小说免费下载| 成人毛片在线精品国产| 国产亚洲欧美日韩在线一区| 日本丰满大乳奶| 在线天堂中文资源最新版| 欧美日韩电影一区| 亚洲图片综合网| 欧美黄色大片在线观看| 韩剧1988免费观看全集| 一区二区小视频| 99久久伊人网影院| 少妇高潮流白浆| 三级成人黄色影院| 欧美成人精品福利| 国产精品综合激情| 国产精品视频| 亚洲mm色国产网站| 成人在线免费视频| 香蕉影视欧美成人| 女王人厕视频2ⅴk| 日韩成人免费| 欧美一区二三区| www.久久伊人| 中文字幕一区视频| 麻豆av免费在线| 超碰成人在线免费| 久久成人国产精品| 中文字幕日日夜夜| 国产亚洲一二三区| 日韩中文字幕三区| 超碰在线亚洲| 超碰97人人做人人爱少妇| 小泽玛利亚一区二区三区视频| 97久久久精品综合88久久| 麻豆视频传媒入口| 欧美一级做a| 中文字幕一区日韩电影| 久久精品99北条麻妃| 久久亚洲影视婷婷| 青青草成人免费在线视频| 日韩一级淫片| 久久精品91久久香蕉加勒比| 制服丝袜在线一区| 国产午夜亚洲精品理论片色戒| 精品久久久久久久久久中文字幕| 99re8这里有精品热视频8在线| 久久亚洲精品毛片| 91在线视频国产| 国产精品国产三级国产a| 视频在线观看免费高清| 久久久综合色| 成人免费观看a| 麻豆影院在线| 91精品免费在线观看| 蜜臀av午夜精品久久| 国产一区二区在线看| 强伦女教师2:伦理在线观看| 国产一区二区三区视频在线| 操91在线视频| 黄色一级大片在线免费看国产| 亚洲综合视频在线| 小毛片在线观看| 夜久久久久久| 欧美日韩国产高清视频| 日韩av大片站长工具| 亚洲视频999| 中文字幕日产av| 亚洲色图欧洲色图| 日本女人性视频| 精品69视频一区二区三区Q| 国产伦精品一区二区三区免费视频| 成人福利电影| 亚洲欧美视频在线| 亚洲一区精品在线观看| 亚洲你懂的在线视频| 中文字幕在线播放一区二区| 国产视频一区三区| 日韩欧美一区二区三区久久婷婷| 色综合视频一区二区三区日韩| 欧美成人合集magnet| 黄色小视频免费观看| 色爱区综合激月婷婷| 亚洲视频重口味| 成人激情午夜影院| 免费观看成人网| 亚洲色图欧美| 久久久一本精品99久久精品| 巨大黑人极品videos精品| 美女扒开尿口让男人操亚洲视频网站| 亚洲黄色精品视频| 欧美性色视频在线| 久久久久久久久久97| thepron国产精品| 亚洲国产精品三区| 欧美日韩ab| 欧美亚洲另类在线一区二区三区| 久久亚洲人体| 2019精品视频| 国产在线更新| 亚洲欧美成人网| 国产伦一区二区| 欧美日韩在线观看视频| 国精品人伦一区二区三区蜜桃| www.色精品| 九一精品久久久| 亚洲在线免费| 97超碰在线视| 成人午夜av| 国产在线一区二区三区四区| 日韩久久99| 日韩免费在线播放| 牛牛精品视频在线| 色偷偷av亚洲男人的天堂| 深夜福利在线观看直播| 欧美一区二区三区在线观看| 日韩不卡高清视频| 五月婷婷久久丁香| 手机在线免费看毛片| 久久久久久久久伊人| 美女网站视频在线观看| 久久精品国产第一区二区三区| 日韩av在线第一页| 欧美影院一区| 亚洲美女自拍偷拍| 日韩精品永久网址| 欧美久久久久久久| 国产调教精品| 99一区二区三区| 国产成年精品| 成人黄色片在线| 日韩一区二区三区免费| 2020国产精品视频| av毛片午夜不卡高**水| 欧美裸体男粗大视频在线观看 | 久久久久久九九九| 麻豆电影在线播放| 在线视频一区二区| 二区在线观看| 一本色道久久88亚洲综合88| 久热av在线| 亚洲品质视频自拍网| 日韩av资源站| 亚洲欧洲在线免费| 三区在线观看| 亚洲欧美综合另类中字| 日本成人一区二区三区| 亚洲欧美日韩精品久久| 三级av在线播放| 亚洲少妇中文在线| www.黄在线观看| 宅男66日本亚洲欧美视频| 狠狠色伊人亚洲综合网站l| 亚洲精品综合精品自拍| 飘雪影院手机免费高清版在线观看| 日韩精品视频在线观看网址| 神马一区二区三区| 日韩精品视频中文在线观看| 神马亚洲视频| 亚洲午夜激情免费视频| 大乳在线免费观看| 精品国产视频在线| 四虎影院观看视频在线观看| 欧美高清第一页| 波多野一区二区| 97精品久久久| 澳门av一区二区三区| 国产剧情日韩欧美| 天堂av一区| 国产视频一区二区不卡| 蜜桃一区二区三区| 一区二区三区四区免费视频| 在线精品小视频| 僵尸世界大战2 在线播放| 亚洲一区欧美二区| 亚洲综合日韩欧美| 国产一区二区三区蝌蚪| 成人在线电影网站| 国产视频视频一区| 欧美风情第一页| 黄色一区二区在线| 中文字幕av网站| 91精品国产综合久久久久久久| 午夜精品久久久久久久99热黄桃| 日韩精品免费在线播放| yjizz视频网站在线播放| 久久亚洲电影天堂| 亚洲黄色网址| 成人国产在线视频| 美女视频免费精品| 亚洲欧美国产不卡| 亚洲免费黄色| 天堂av2020| 91小视频在线免费看| 一区二区国产精品精华液| 偷拍日韩校园综合在线| 中文字幕在线一| 亚洲成人教育av| 色老头视频在线观看| 国a精品视频大全| 青青在线精品| 免费久久99精品国产自| 91精品国产麻豆国产在线观看| 日本免费不卡一区二区| 久久精品国产亚洲高清剧情介绍 | 精品女同一区二区三区在线播放| 黄色大全在线观看| 亚洲国产精品专区久久| 亚洲搞黄视频| 日本精品视频在线观看| 一区二区三区四区精品视频| 少妇精品久久久久久久久久| 在线免费观看欧美| 激情图片中文字幕| 国产校园另类小说区| 国产午夜福利片| 欧美一区午夜精品| 午夜视频在线| 国产成人午夜视频网址| 韩国精品福利一区二区三区| 欧美日韩视频免费在线观看| 可以看av的网站久久看| a级片在线观看视频| 亚洲人一二三区| 亚洲自拍第二页| 亚洲性线免费观看视频成熟| аⅴ资源天堂资源库在线| 91久久精品一区二区别| 99久久亚洲精品蜜臀| www.国产区| 91视频观看免费| 日韩精品一区二区三| 欧美大片日本大片免费观看| 免费在线毛片网站| 国产精品一区二区久久久久| 国产一区二区三区四区五区| 免费黄色日本网站| 91性感美女视频| 国产午夜免费福利 | 在线观看免费黄色| 国产激情视频一区| 国产99亚洲| 不卡影院一区二区| 久久一日本道色综合| 亚洲免费在线视频观看| 日韩电影网在线| 国产一二三在线| 久久狠狠久久综合桃花| 99在线观看免费视频精品观看| 亚洲视频 中文字幕| 亚洲一区电影777| 免费观看的毛片| 91精品国产91久久久久福利| 久久精品66| 茄子视频成人免费观看| wwwwww.欧美系列| 欧美日韩综合一区二区三区| 亚洲天堂男人天堂女人天堂| 成人在线爆射| 婷婷亚洲婷婷综合色香五月| 久久精品久久综合| 国产精品嫩草影院俄罗斯| 91精品国产乱码| japanese色国产在线看视频| 国产在线精品日韩| 噜噜噜91成人网| 国产一区二区三区四区在线| 欧美日本一区二区| 超碰在线免费播放| 国内精品久久久久久久果冻传媒| 国产精品久久久久久久免费软件| 青青草视频成人| 欧美日韩一级视频| v片在线观看| 久久久久久久有限公司| 视频一区二区国产| 国产67194| 日韩国产激情在线| 欧美va在线观看| 51xx午夜影福利| 久久综合九色综合97_久久久| 一区二区视频播放| 欧美国产一区二区三区| 亚洲成在人线免费观看| 五月婷婷狠狠操| 一级精品视频在线观看宜春院| 婷婷视频在线观看| 国产日韩欧美日韩| 亚洲一级网站| 貂蝉被到爽流白浆在线观看| 日韩免费在线观看| 国精产品一区二区三区有限公司| 国产成年人在线观看| 99久久精品国产毛片| 国产又粗又猛又爽又黄视频| 97久久精品人人澡人人爽缅北| 欧美在线观看视频一区| 无码国产精品久久一区免费| 91国产精品成人| 国产蜜臀av在线播放| 日韩色妇久久av| 成人av电影在线| 一级淫片免费看| 5278欧美一区二区三区| 亚洲最新色图| brazzers精品成人一区| 日韩精品一区二区三区四区视频| 97欧美成人| 黄色成人在线看| 亚洲精品水蜜桃|