精品欧美一区二区三区在线观看 _久久久久国色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)

国产精品88久久久久久| 欧美性xxx| 99久久久久久| 国产精品久久久久免费a∨| 91ts人妖另类精品系列| 欧美电影院免费观看| 高潮白浆女日韩av免费看| 相泽南亚洲一区二区在线播放| 国产强被迫伦姧在线观看无码| 国产一区二区三区自拍| 一个色综合导航| 国产精品99久久久精品无码| 你懂得影院夜精品a| 亚洲免费av网站| 日本一区二区三区视频在线播放| 亚洲av无码乱码国产精品久久| 欧美一级久久| 久久久久久久久久国产| 熟女av一区二区| 亚洲色图美女| 亚洲精品一线二线三线无人区| 国产视频手机在线播放| 无遮挡在线观看| 亚洲国产精品精华液网站| 在线免费观看成人网| 国产专区在线| 99久久综合99久久综合网站| 亚洲一区二区免费| 中文字幕在线观看欧美| 男人天堂欧美日韩| 97人人爽人人喊人人模波多 | 国产精品久久久久永久免费观看 | 日本亚洲欧美成人| 久久久久亚洲av片无码下载蜜桃| 欧美电影《轻佻寡妇》| 国产午夜精品一区理论片飘花 | 午夜精品在线免费观看| 男人av在线播放| 亚洲午夜免费电影| 欧美在线观看视频免费| 91在线中文| 亚洲免费在线电影| 自拍偷拍视频在线| 黄色网在线免费看| 自拍偷拍亚洲激情| 正在播放精油久久| 麻豆免费在线观看| 亚洲三级久久久| 熟妇熟女乱妇乱女网站| 黄av在线免费观看| 日韩理论在线观看| 狠狠精品干练久久久无码中文字幕 | gay欧美网站| 亚洲一区二区三区中文字幕在线| 国产91av视频在线观看| 五月天婷婷在线观看视频| 九九精品视频免费| 欧美欧美黄在线二区| 亚洲电影免费观看高清完整版在线观看| 亚洲妇熟xx妇色黄蜜桃| 欧美高清你懂的| 欧美精品在线观看播放| 三级性生活视频| 日本精品在线播放| 精品国产百合女同互慰| www.日本高清| 成人国产精品一级毛片视频| 神马国产精品影院av| 加勒比婷婷色综合久久| 国产精品九九| 欧美在线免费观看| 中文精品久久久久人妻不卡| 久久激情五月激情| yy111111少妇影院日韩夜片| 熟妇人妻中文av无码| 久久久久久久久岛国免费| 欧美大陆一区二区| 91精彩视频在线观看| 亚洲三级久久久| 伊人成色综合网| 电影一区电影二区| 欧美大片在线观看一区| 国产精品揄拍100视频| 日韩精品免费一区二区在线观看| 久久九九全国免费精品观看| 国产无套内射又大又猛又粗又爽| 蜜桃伊人久久| 成人在线播放av| 天堂成人在线视频| 中文字幕av在线一区二区三区| 18视频在线观看娇喘| sm在线观看| 在线观看日韩电影| wwwxxxx在线观看| 深夜福利久久| 欧美激情国产精品| 中文字幕免费高清网站| 国产精品一区二区你懂的| 久热国产精品视频一区二区三区| 欧美成人精品一区二区男人看| 亚洲曰韩产成在线| wwwwxxxx日韩| 老牛精品亚洲成av人片| www国产精品视频| 中文字幕在线观看视频网站| 久久精品国产亚洲aⅴ| 久久99精品久久久水蜜桃| 欧美激情午夜| 欧美性xxxxx极品| 国产亚洲色婷婷久久| 精品国产91乱码一区二区三区四区 | 国产精品扒开腿做爽爽爽视频| av加勒比在线| 国产精品婷婷午夜在线观看| 人妻少妇精品久久| www.成人| 最近2019中文免费高清视频观看www99| 久久久久成人网站| 精品一区二区三区免费播放| 色就是色欧美| 色老头在线一区二区三区| 欧美一级高清片| 国产黄a三级三级| 天堂资源在线中文精品| 久久av一区二区| 高清电影在线免费观看| 欧美一区二视频| jizzjizz日本少妇| 日本不卡一区二区三区高清视频| 久久国产一区| 国产在线精彩视频| 精品国产乱码久久| 久久久国产精品人人片| 国产精品一级黄| 一区二区不卡视频| 欧美三级电影网址| 中文字幕欧美视频在线| 国产第一页在线观看| 91麻豆免费观看| 18岁网站在线观看| 日韩三级毛片| 奇门遁甲1982国语版免费观看高清 | 国产极品美女高潮无套嗷嗷叫酒店| 国产主播一区二区| 熟妇熟女乱妇乱女网站| 国产精品中文| 欧美久久精品一级黑人c片 | 日本特黄特色aaa大片免费| 国产精品99久久久久久宅男| 日本三日本三级少妇三级66| av一级久久| 欧美精品中文字幕一区| 亚洲经典一区二区三区| 亚洲成a人v欧美综合天堂下载| 不许穿内裤随时挨c调教h苏绵| 自拍日韩欧美| 国产精品日韩欧美一区二区三区| rebdb初裸写真在线观看| 日韩电影视频免费| 天天干天天色综合| 国产精品素人视频| 天天操精品视频| 亚洲视频久久| 狼狼综合久久久久综合网| 免费成人动漫| 中文字幕日韩在线播放| 国产精品久久婷婷| 亚洲一区二区三区在线| 大尺度做爰床戏呻吟舒畅| 国产精品亚洲综合久久| 日日骚一区二区网站| 99热播精品免费| 欧美另类极品videosbest最新版本| 亚洲黄色精品视频| 日本黄色一区二区| 疯狂试爱三2浴室激情视频| 成人午夜视频在线| 亚洲综合在线网站| 亚洲国产精品久久久天堂| 国产日产精品一区二区三区四区| 亚洲一区站长工具| 精品国内亚洲在观看18黄| 免费国产精品视频| 欧美视频一区在线| 久久久久久久久99| 国产日韩欧美精品电影三级在线| 在线观看av免费观看| 99精品国产福利在线观看免费| 日韩欧美视频一区二区三区四区| 国产精品欧美一区二区三区不卡 | 一区二区三区视频播放| 欧美在线一级视频| caoporn免费在线视频| 国产视频精品va久久久久久| 国产剧情精品在线| 欧美日韩综合视频| 爱爱视频免费在线观看| xnxx国产精品| 日本55丰满熟妇厨房伦| 老司机精品导航| 18禁裸男晨勃露j毛免费观看| av一区二区高清| 国产精品三区www17con| 日本一区二区中文字幕| 欧美又大又硬又粗bbbbb| 成人无遮挡免费网站视频在线观看| 日韩黄在线观看| 国产成人精品av在线观| 91激情在线视频| 日本三级视频在线| 亚洲欧美另类久久久精品| 久久亚洲无码视频| www.亚洲激情.com| 午夜视频在线观| 久久综合九色| jizzjizz国产精品喷水| 欧美精品午夜| 亚洲视频在线二区| 国产精品密蕾丝视频下载| 福利视频一区二区三区| 精品麻豆剧传媒av国产九九九| 青青久久aⅴ北条麻妃| a在线视频v视频| 欧美日韩成人免费| 99久久精品免费观看国产| 日韩在线观看免费网站| 成a人v在线播放| 亚洲欧美日韩在线一区| 色视频在线观看| 亚洲黄色有码视频| 四虎免费在线观看| 亚洲国产精品专区久久| 免费看av毛片| 亚洲成人av片在线观看| 丰满熟妇乱又伦| 欧美一级理论性理论a| 国产精品一级二级| 欧美精品1区2区3区| 亚洲专区第一页| 欧美日韩精品欧美日韩精品一| 久久久久亚洲视频| 在线视频欧美精品| 免费在线不卡av| 欧美日韩一区二区电影| 一区二区日韩在线观看| 777亚洲妇女| 国产模特av私拍大尺度| 在线观看91av| a视频免费在线观看| 欧美一卡2卡3卡4卡| aaaa一级片| 精品国产伦一区二区三区观看体验| 国产高清第一页| 精品国产乱码久久久久久夜甘婷婷| 午夜精品在线播放| 亚洲国产91色在线| 亚洲欧美日韩综合在线| 亚洲精品一区中文| 第一福利在线| 日韩中文字幕视频在线观看| 黄色网址视频在线观看| 大胆人体色综合| caoprom在线| 日本久久亚洲电影| 成人影院在线免费观看| 亚洲一区二区三区香蕉 | 日韩av电影免费观看| 青青草国产免费一区二区下载 | 欧美一区二区三区成人| 成 人 黄 色 片 在线播放| 色综合天天爱| 免费不卡欧美自拍视频| 大香伊人久久| 国产精品18久久久久久麻辣| 久久人体av| ts人妖另类在线| 国产欧美日韩精品一区二区三区 | 欧美一a一片一级一片| 国产又粗又猛又爽又黄的| 欧美成人性战久久| 欧美人体大胆444www| www.99久久热国产日韩欧美.com| 污视频网站免费在线观看| 91精品国产高清久久久久久| 69堂精品视频在线播放| 97人人模人人爽人人少妇| 一区三区在线欧| 日本成人在线不卡| 久久久久国内| 精人妻一区二区三区| 国产片一区二区三区| 久草资源在线视频| 欧美亚洲丝袜传媒另类| 日本韩国在线观看| 日韩一区二区三区xxxx| 欧美男男激情videos| 成人久久久久久久| 要久久爱电视剧全集完整观看| 三年中文高清在线观看第6集 | 玉米视频成人免费看| 亚洲欧美综合另类| 日韩一区二区三区视频在线观看| 九色在线播放| 久久久久久久久国产| 亚洲人成777| 欧美三级网色| 亚洲国产高清视频| 在线a免费观看| 国产丝袜欧美中文另类| 日韩久久久久久久久| 在线不卡一区二区| 男女av在线| 88国产精品欧美一区二区三区| 日本一区二区三区播放| 亚洲精品日韩成人| 久久久综合网| 内射中出日韩无国产剧情| 一区二区三区四区视频精品免费| 久久久久久无码精品大片| 国产婷婷色综合av蜜臀av | 欧美极品一区二区三区| 高清一区在线观看| 国产亚洲欧美在线| 四虎成人永久免费视频| 精品久久久久一区二区国产| 韩国av网站在线| 91精品国产综合久久久久久蜜臀| 国内精品久久久久久久久电影网 | 国产原创一区| 日本在线免费观看一区| 国产精品美女久久久| 成人性生活免费看| 亚洲丶国产丶欧美一区二区三区| 精品国产一级片| 欧美不卡视频一区发布| **欧美日韩在线| 中文字幕欧美日韩一区二区| 免费欧美在线视频| 国产精品久久久久久成人| 欧美综合色免费| wwwxxx在线观看| 国产精品视频永久免费播放 | 国产精品免费看久久久无码| 国产毛片精品一区| 69av视频在线| 欧美刺激午夜性久久久久久久| 国产午夜精品久久久久免费视| 成人免费网站在线看| 2023国产精品久久久精品双| 男女视频在线观看网站| 亚洲男同1069视频| 亚洲AV无码国产精品午夜字幕 | 一二三四中文字幕| 丁香婷婷综合色啪| 五月天婷婷丁香| 亚洲精品一区二三区不卡| 日韩一级二级| youjizz.com亚洲| 国产精品中文有码| 亚洲国产综合久久| 亚洲品质视频自拍网| 99热播精品免费| 国产 国语对白 露脸| 91首页免费视频| 国产又粗又猛又爽又| 不卡av电影在线观看| 国产女人18毛片水真多18精品| 一本大道熟女人妻中文字幕在线| 国产人伦精品一区二区| 国产一区二区麻豆| 性欧美xxxx交| 久久免费大视频| 91人妻一区二区| 色呦呦一区二区三区| 免费在线看黄网站| 国产精品入口免费| 秋霞午夜av一区二区三区| 久久久久99精品成人片试看| 亚洲国产精品久久久久秋霞不卡| av有声小说一区二区三区| 亚洲精品偷拍视频| av成人免费在线观看| 国产一区二区三区在线观看| 久久全球大尺度高清视频| 成人久久电影| 特种兵之深入敌后| 色综合色综合色综合 | 欧美精选视频在线观看| 午夜影院免费版| 欧美午夜激情在线| 成人免费观看视频大全| 蜜桃久久影院| 国产一区二三区| 无码人妻黑人中文字幕| 欧美久久久精品| 日韩成人综合| 国产精品无码电影| 91精品国产色综合久久不卡蜜臀| 欧美极品videos大乳护士| 一本大道东京热无码aⅴ|