123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width,initial-scale=1">
- <title>事件 | 彪哥博客</title>
- <meta name="generator" content="VuePress 1.9.5">
- <link rel="icon" href="/blog/img/favicon.ico">
- <meta name="description" content="web前端技术博客,专注web前端学习与总结。JavaScript,js,ES6,TypeScript,vue,React,python,css3,html5,Node,git,github等技术文章。">
- <meta name="keywords" content="前端博客,个人技术博客,前端,前端开发,前端框架,web前端,前端面试题,技术文档,学习,面试,JavaScript,js,ES6,TypeScript,vue,python,css3,html5,Node,git,github,markdown">
- <meta name="theme-color" content="#11a8cd">
-
- <link rel="preload" href="/blog/assets/css/0.styles.cf8cd190.css" as="style"><link rel="preload" href="/blog/assets/js/app.28edfb28.js" as="script"><link rel="preload" href="/blog/assets/js/2.395c0d18.js" as="script"><link rel="preload" href="/blog/assets/js/3.6748bd5c.js" as="script"><link rel="preload" href="/blog/assets/js/141.128b6e26.js" as="script"><link rel="prefetch" href="/blog/assets/js/10.cad3aa70.js"><link rel="prefetch" href="/blog/assets/js/100.08a8b2d8.js"><link rel="prefetch" href="/blog/assets/js/101.2aabb12c.js"><link rel="prefetch" href="/blog/assets/js/102.13f3cc4d.js"><link rel="prefetch" href="/blog/assets/js/103.c19aee03.js"><link rel="prefetch" href="/blog/assets/js/104.91a6aec1.js"><link rel="prefetch" href="/blog/assets/js/105.71de1aa4.js"><link rel="prefetch" href="/blog/assets/js/106.207422de.js"><link rel="prefetch" href="/blog/assets/js/107.bf754f60.js"><link rel="prefetch" href="/blog/assets/js/108.a43622c2.js"><link rel="prefetch" href="/blog/assets/js/109.3219d87b.js"><link rel="prefetch" href="/blog/assets/js/11.f2e9eca8.js"><link rel="prefetch" href="/blog/assets/js/110.f41596b0.js"><link rel="prefetch" href="/blog/assets/js/111.da99a105.js"><link rel="prefetch" href="/blog/assets/js/112.9dd75c6f.js"><link rel="prefetch" href="/blog/assets/js/113.9322f157.js"><link rel="prefetch" href="/blog/assets/js/114.c5150cc6.js"><link rel="prefetch" href="/blog/assets/js/115.f58b49f8.js"><link rel="prefetch" href="/blog/assets/js/116.8f7d9c6f.js"><link rel="prefetch" href="/blog/assets/js/117.3c970f48.js"><link rel="prefetch" href="/blog/assets/js/118.921e1d54.js"><link rel="prefetch" href="/blog/assets/js/119.0141defb.js"><link rel="prefetch" href="/blog/assets/js/12.98512c60.js"><link rel="prefetch" href="/blog/assets/js/120.de47a761.js"><link rel="prefetch" href="/blog/assets/js/121.a0b3693a.js"><link rel="prefetch" href="/blog/assets/js/122.6c7dd225.js"><link rel="prefetch" href="/blog/assets/js/123.dbff103c.js"><link rel="prefetch" href="/blog/assets/js/124.493776ef.js"><link rel="prefetch" href="/blog/assets/js/125.554c9fbf.js"><link rel="prefetch" href="/blog/assets/js/126.9d3b75dc.js"><link rel="prefetch" href="/blog/assets/js/127.aad20a7e.js"><link rel="prefetch" href="/blog/assets/js/128.6543adba.js"><link rel="prefetch" href="/blog/assets/js/129.d7c56b92.js"><link rel="prefetch" href="/blog/assets/js/13.a79fa0c7.js"><link rel="prefetch" href="/blog/assets/js/130.593d21f0.js"><link rel="prefetch" href="/blog/assets/js/131.4c90d8b8.js"><link rel="prefetch" href="/blog/assets/js/132.4ad12bdc.js"><link rel="prefetch" href="/blog/assets/js/133.6df121d8.js"><link rel="prefetch" href="/blog/assets/js/134.65e904d2.js"><link rel="prefetch" href="/blog/assets/js/135.47498729.js"><link rel="prefetch" href="/blog/assets/js/136.d99350df.js"><link rel="prefetch" href="/blog/assets/js/137.71e8757e.js"><link rel="prefetch" href="/blog/assets/js/138.75e29c6f.js"><link rel="prefetch" href="/blog/assets/js/139.766f20b7.js"><link rel="prefetch" href="/blog/assets/js/14.0fdf0c78.js"><link rel="prefetch" href="/blog/assets/js/140.0d9b8fbc.js"><link rel="prefetch" href="/blog/assets/js/142.e004a584.js"><link rel="prefetch" href="/blog/assets/js/143.5a19a0b2.js"><link rel="prefetch" href="/blog/assets/js/144.5f397211.js"><link rel="prefetch" href="/blog/assets/js/145.3b994de3.js"><link rel="prefetch" href="/blog/assets/js/146.24441c89.js"><link rel="prefetch" href="/blog/assets/js/147.f7f1952e.js"><link rel="prefetch" href="/blog/assets/js/148.25581f95.js"><link rel="prefetch" href="/blog/assets/js/149.7a6ca4f7.js"><link rel="prefetch" href="/blog/assets/js/15.fce722b2.js"><link rel="prefetch" href="/blog/assets/js/150.3a1675b7.js"><link rel="prefetch" href="/blog/assets/js/151.250a4894.js"><link rel="prefetch" href="/blog/assets/js/152.fa700729.js"><link rel="prefetch" href="/blog/assets/js/153.cc421f44.js"><link rel="prefetch" href="/blog/assets/js/154.a04c0164.js"><link rel="prefetch" href="/blog/assets/js/155.b5c0abcd.js"><link rel="prefetch" href="/blog/assets/js/156.2ba750fc.js"><link rel="prefetch" href="/blog/assets/js/157.99ee745c.js"><link rel="prefetch" href="/blog/assets/js/158.09b15f2b.js"><link rel="prefetch" href="/blog/assets/js/159.3fd855e1.js"><link rel="prefetch" href="/blog/assets/js/16.7cf1b239.js"><link rel="prefetch" href="/blog/assets/js/160.307b6a2e.js"><link rel="prefetch" href="/blog/assets/js/161.97acae68.js"><link rel="prefetch" href="/blog/assets/js/162.86431056.js"><link rel="prefetch" href="/blog/assets/js/163.f1bfa2fe.js"><link rel="prefetch" href="/blog/assets/js/164.105b48fa.js"><link rel="prefetch" href="/blog/assets/js/165.700f83da.js"><link rel="prefetch" href="/blog/assets/js/166.8de21024.js"><link rel="prefetch" href="/blog/assets/js/167.2b670c3d.js"><link rel="prefetch" href="/blog/assets/js/168.330ac31c.js"><link rel="prefetch" href="/blog/assets/js/169.f8233c38.js"><link rel="prefetch" href="/blog/assets/js/17.93f492a1.js"><link rel="prefetch" href="/blog/assets/js/170.7c8b0366.js"><link rel="prefetch" href="/blog/assets/js/171.c3155533.js"><link rel="prefetch" href="/blog/assets/js/172.b659d767.js"><link rel="prefetch" href="/blog/assets/js/173.62c681db.js"><link rel="prefetch" href="/blog/assets/js/174.5c66f092.js"><link rel="prefetch" href="/blog/assets/js/175.d41dd28b.js"><link rel="prefetch" href="/blog/assets/js/176.e60d7f0a.js"><link rel="prefetch" href="/blog/assets/js/177.10de95b1.js"><link rel="prefetch" href="/blog/assets/js/178.f301674d.js"><link rel="prefetch" href="/blog/assets/js/179.4d54a4ff.js"><link rel="prefetch" href="/blog/assets/js/18.f17de23a.js"><link rel="prefetch" href="/blog/assets/js/180.955aa8ec.js"><link rel="prefetch" href="/blog/assets/js/181.a53e32e0.js"><link rel="prefetch" href="/blog/assets/js/182.38687994.js"><link rel="prefetch" href="/blog/assets/js/183.544fef00.js"><link rel="prefetch" href="/blog/assets/js/184.711e54a6.js"><link rel="prefetch" href="/blog/assets/js/185.20075148.js"><link rel="prefetch" href="/blog/assets/js/186.08c67f20.js"><link rel="prefetch" href="/blog/assets/js/187.7ca2d0c6.js"><link rel="prefetch" href="/blog/assets/js/188.cd167879.js"><link rel="prefetch" href="/blog/assets/js/189.e8e2eb21.js"><link rel="prefetch" href="/blog/assets/js/19.6b963460.js"><link rel="prefetch" href="/blog/assets/js/190.8b557318.js"><link rel="prefetch" href="/blog/assets/js/191.3e6fdc4f.js"><link rel="prefetch" href="/blog/assets/js/192.99d6e1d8.js"><link rel="prefetch" href="/blog/assets/js/193.4ced091e.js"><link rel="prefetch" href="/blog/assets/js/194.4b375e2e.js"><link rel="prefetch" href="/blog/assets/js/195.003e3d67.js"><link rel="prefetch" href="/blog/assets/js/196.7a3f55e5.js"><link rel="prefetch" href="/blog/assets/js/197.30d4c5b4.js"><link rel="prefetch" href="/blog/assets/js/198.628c2c1a.js"><link rel="prefetch" href="/blog/assets/js/199.89c4e586.js"><link rel="prefetch" href="/blog/assets/js/20.839dae41.js"><link rel="prefetch" href="/blog/assets/js/200.1d9f2ef9.js"><link rel="prefetch" href="/blog/assets/js/201.5ba078d9.js"><link rel="prefetch" href="/blog/assets/js/202.b49b23f4.js"><link rel="prefetch" href="/blog/assets/js/203.d88a03d9.js"><link rel="prefetch" href="/blog/assets/js/204.fb928277.js"><link rel="prefetch" href="/blog/assets/js/205.432c3d8d.js"><link rel="prefetch" href="/blog/assets/js/206.ed726599.js"><link rel="prefetch" href="/blog/assets/js/207.9ac30d7b.js"><link rel="prefetch" href="/blog/assets/js/208.c5e77adc.js"><link rel="prefetch" href="/blog/assets/js/209.d396aad5.js"><link rel="prefetch" href="/blog/assets/js/21.bd21bd29.js"><link rel="prefetch" href="/blog/assets/js/210.02e4ee2f.js"><link rel="prefetch" href="/blog/assets/js/211.0f8a9304.js"><link rel="prefetch" href="/blog/assets/js/212.9220dd3d.js"><link rel="prefetch" href="/blog/assets/js/213.89521ebd.js"><link rel="prefetch" href="/blog/assets/js/214.cd5ec468.js"><link rel="prefetch" href="/blog/assets/js/215.0084d772.js"><link rel="prefetch" href="/blog/assets/js/216.a72becb1.js"><link rel="prefetch" href="/blog/assets/js/217.71a7f3aa.js"><link rel="prefetch" href="/blog/assets/js/218.9793e19a.js"><link rel="prefetch" href="/blog/assets/js/219.c89175e9.js"><link rel="prefetch" href="/blog/assets/js/22.e6bcf65d.js"><link rel="prefetch" href="/blog/assets/js/220.d496e411.js"><link rel="prefetch" href="/blog/assets/js/221.07a9338a.js"><link rel="prefetch" href="/blog/assets/js/222.22bf261f.js"><link rel="prefetch" href="/blog/assets/js/223.b9c6a055.js"><link rel="prefetch" href="/blog/assets/js/224.364b4b11.js"><link rel="prefetch" href="/blog/assets/js/225.adec6660.js"><link rel="prefetch" href="/blog/assets/js/226.78192713.js"><link rel="prefetch" href="/blog/assets/js/227.0c1ec0e5.js"><link rel="prefetch" href="/blog/assets/js/228.a94ad835.js"><link rel="prefetch" href="/blog/assets/js/229.51820867.js"><link rel="prefetch" href="/blog/assets/js/23.7bb82fc7.js"><link rel="prefetch" href="/blog/assets/js/230.6eb1d9bf.js"><link rel="prefetch" href="/blog/assets/js/231.55d62061.js"><link rel="prefetch" href="/blog/assets/js/232.f938a3a8.js"><link rel="prefetch" href="/blog/assets/js/233.2c81f1b3.js"><link rel="prefetch" href="/blog/assets/js/234.4dbf5d59.js"><link rel="prefetch" href="/blog/assets/js/235.f78274d9.js"><link rel="prefetch" href="/blog/assets/js/236.a2b61bec.js"><link rel="prefetch" href="/blog/assets/js/237.6ae31c88.js"><link rel="prefetch" href="/blog/assets/js/238.2f5c56ae.js"><link rel="prefetch" href="/blog/assets/js/239.506a4e9f.js"><link rel="prefetch" href="/blog/assets/js/24.2c9c4ee6.js"><link rel="prefetch" href="/blog/assets/js/25.b4de33d1.js"><link rel="prefetch" href="/blog/assets/js/26.0bb98ba9.js"><link rel="prefetch" href="/blog/assets/js/27.df98327e.js"><link rel="prefetch" href="/blog/assets/js/28.31289bac.js"><link rel="prefetch" href="/blog/assets/js/29.45af5621.js"><link rel="prefetch" href="/blog/assets/js/30.d5c08e66.js"><link rel="prefetch" href="/blog/assets/js/31.78e43a68.js"><link rel="prefetch" href="/blog/assets/js/32.66c0e717.js"><link rel="prefetch" href="/blog/assets/js/33.0efe6b11.js"><link rel="prefetch" href="/blog/assets/js/34.cb1866c1.js"><link rel="prefetch" href="/blog/assets/js/35.dca9b927.js"><link rel="prefetch" href="/blog/assets/js/36.fb4476c3.js"><link rel="prefetch" href="/blog/assets/js/37.09dfc1c5.js"><link rel="prefetch" href="/blog/assets/js/38.6624bf02.js"><link rel="prefetch" href="/blog/assets/js/39.df6c26ac.js"><link rel="prefetch" href="/blog/assets/js/4.44654b1a.js"><link rel="prefetch" href="/blog/assets/js/40.80101c19.js"><link rel="prefetch" href="/blog/assets/js/41.2b5e8c27.js"><link rel="prefetch" href="/blog/assets/js/42.c6ded3fe.js"><link rel="prefetch" href="/blog/assets/js/43.6d9424d6.js"><link rel="prefetch" href="/blog/assets/js/44.835e4b5c.js"><link rel="prefetch" href="/blog/assets/js/45.e7bb6f6a.js"><link rel="prefetch" href="/blog/assets/js/46.1b9286bf.js"><link rel="prefetch" href="/blog/assets/js/47.8d66ca97.js"><link rel="prefetch" href="/blog/assets/js/48.3c1102e1.js"><link rel="prefetch" href="/blog/assets/js/49.e17a3436.js"><link rel="prefetch" href="/blog/assets/js/5.88de390f.js"><link rel="prefetch" href="/blog/assets/js/50.6750f186.js"><link rel="prefetch" href="/blog/assets/js/51.9f93af9f.js"><link rel="prefetch" href="/blog/assets/js/52.f3ef3b5e.js"><link rel="prefetch" href="/blog/assets/js/53.a6bacd25.js"><link rel="prefetch" href="/blog/assets/js/54.dbb7c9ab.js"><link rel="prefetch" href="/blog/assets/js/55.2562d0c8.js"><link rel="prefetch" href="/blog/assets/js/56.14ea4931.js"><link rel="prefetch" href="/blog/assets/js/57.a2fad780.js"><link rel="prefetch" href="/blog/assets/js/58.8165b971.js"><link rel="prefetch" href="/blog/assets/js/59.556cab0d.js"><link rel="prefetch" href="/blog/assets/js/6.277038ca.js"><link rel="prefetch" href="/blog/assets/js/60.f048aa7c.js"><link rel="prefetch" href="/blog/assets/js/61.bdb307a8.js"><link rel="prefetch" href="/blog/assets/js/62.37a94f10.js"><link rel="prefetch" href="/blog/assets/js/63.74811780.js"><link rel="prefetch" href="/blog/assets/js/64.d3429318.js"><link rel="prefetch" href="/blog/assets/js/65.acfdd371.js"><link rel="prefetch" href="/blog/assets/js/66.cb805d9b.js"><link rel="prefetch" href="/blog/assets/js/67.39f85baa.js"><link rel="prefetch" href="/blog/assets/js/68.a1902a2a.js"><link rel="prefetch" href="/blog/assets/js/69.923fdd78.js"><link rel="prefetch" href="/blog/assets/js/7.474f8f8d.js"><link rel="prefetch" href="/blog/assets/js/70.1f3e978d.js"><link rel="prefetch" href="/blog/assets/js/71.13cd9358.js"><link rel="prefetch" href="/blog/assets/js/72.739b22a8.js"><link rel="prefetch" href="/blog/assets/js/73.95f69ae2.js"><link rel="prefetch" href="/blog/assets/js/74.b6624f6a.js"><link rel="prefetch" href="/blog/assets/js/75.31b56e72.js"><link rel="prefetch" href="/blog/assets/js/76.b9c0ce40.js"><link rel="prefetch" href="/blog/assets/js/77.46f6e413.js"><link rel="prefetch" href="/blog/assets/js/78.aebd00ee.js"><link rel="prefetch" href="/blog/assets/js/79.1b784d15.js"><link rel="prefetch" href="/blog/assets/js/8.9428e7ee.js"><link rel="prefetch" href="/blog/assets/js/80.1f550d53.js"><link rel="prefetch" href="/blog/assets/js/81.101cc131.js"><link rel="prefetch" href="/blog/assets/js/82.077c8298.js"><link rel="prefetch" href="/blog/assets/js/83.2e375d11.js"><link rel="prefetch" href="/blog/assets/js/84.38102a34.js"><link rel="prefetch" href="/blog/assets/js/85.24532d6a.js"><link rel="prefetch" href="/blog/assets/js/86.1dabbf00.js"><link rel="prefetch" href="/blog/assets/js/87.763da0f2.js"><link rel="prefetch" href="/blog/assets/js/88.ff6e5f7c.js"><link rel="prefetch" href="/blog/assets/js/89.187e5e16.js"><link rel="prefetch" href="/blog/assets/js/9.da143545.js"><link rel="prefetch" href="/blog/assets/js/90.3c8cff94.js"><link rel="prefetch" href="/blog/assets/js/91.a50bd44d.js"><link rel="prefetch" href="/blog/assets/js/92.5484868f.js"><link rel="prefetch" href="/blog/assets/js/93.c8ee75e3.js"><link rel="prefetch" href="/blog/assets/js/94.b18a3e9b.js"><link rel="prefetch" href="/blog/assets/js/95.cddef6ae.js"><link rel="prefetch" href="/blog/assets/js/96.80e5a938.js"><link rel="prefetch" href="/blog/assets/js/97.1f5e5197.js"><link rel="prefetch" href="/blog/assets/js/98.e3a275c8.js"><link rel="prefetch" href="/blog/assets/js/99.d33bf89e.js">
- <link rel="stylesheet" href="/blog/assets/css/0.styles.cf8cd190.css">
- </head>
- <body class="theme-mode-light">
- <div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/blog/" class="home-link router-link-active"><img src="/blog/img/logo.png" alt="彪哥博客" class="logo"> <span class="site-name can-hide">彪哥博客</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/blog/" class="nav-link">首页</a></div><div class="nav-item"><a href="http://fseller.com" target="_blank" rel="noopener noreferrer" class="nav-link external">
- 个人游戏网站
- <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="前端" class="dropdown-title"><a href="/blog/web/" class="link-title">前端</a> <span class="title" style="display:none;">前端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>前端文章</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/blog/pages/8143cc480faf9a11/" class="nav-link">JavaScript</a></li></ul></li><li class="dropdown-item"><h4>学习笔记</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/blog/note/javascript/" class="nav-link">《JavaScript教程》</a></li><li class="dropdown-subitem"><a href="/blog/note/js/" class="nav-link">《JavaScript高级程序设计》</a></li><li class="dropdown-subitem"><a href="/blog/note/es6/" class="nav-link">《ES6 教程》</a></li><li class="dropdown-subitem"><a href="/blog/note/vue/" class="nav-link">《Vue》</a></li><li class="dropdown-subitem"><a href="/blog/note/react/" class="nav-link">《React》</a></li><li class="dropdown-subitem"><a href="/blog/note/typescript-axios/" class="nav-link">《TypeScript 从零实现 axios》</a></li><li class="dropdown-subitem"><a href="/blog/note/git/" class="nav-link">《Git》</a></li><li class="dropdown-subitem"><a href="/blog/pages/51afd6/" class="nav-link">TypeScript</a></li><li class="dropdown-subitem"><a href="/blog/pages/4643cd/" class="nav-link">JS设计模式总结</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="页面" class="dropdown-title"><a href="/blog/ui/" class="link-title">页面</a> <span class="title" style="display:none;">页面</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/pages/8309a5b876fc95e3/" class="nav-link">HTML</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/0a83b083bdf257cb/" class="nav-link">CSS</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="技术" class="dropdown-title"><a href="/blog/technology/" class="link-title">技术</a> <span class="title" style="display:none;">技术</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/pages/9a7ee40fc232253e/" class="nav-link">技术文档</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/4c778760be26d8b3/" class="nav-link">GitHub技巧</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/117708e0af7f0bd9/" class="nav-link">Nodejs</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/41f87d890d0a02af/" class="nav-link">博客搭建</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="更多" class="dropdown-title"><a href="/blog/more/" class="link-title">更多</a> <span class="title" style="display:none;">更多</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/pages/f2a556/" class="nav-link">学习</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/aea6571b7a8bae86/" class="nav-link">面试</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/2d615df9a36a98ed/" class="nav-link">心情杂货</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/baaa02/" class="nav-link">实用技巧</a></li><li class="dropdown-item"><!----> <a href="/blog/friends/" class="nav-link">友情链接</a></li></ul></div></div><div class="nav-item"><a href="/blog/about/" class="nav-link">关于</a></div><div class="nav-item"><a href="/blog/pages/beb6c0bd8a66cea6/" class="nav-link">收藏</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/blog/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/blog/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/blog/archives/" class="nav-link">归档</a></li></ul></div></div> <a href="https://github.com/heBody/blog" target="_blank" rel="noopener noreferrer" class="repo-link">
- GitHub
- <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar-hover-trigger"></div> <aside class="sidebar" style="display:none;"><div class="blogger"><img src="https://fastly.jsdelivr.net/gh/xugaoyi/image_store/blog/20200103123203.jpg"> <div class="blogger-info"><h3>彪哥</h3> <span>爱好前端</span></div></div> <nav class="nav-links"><div class="nav-item"><a href="/blog/" class="nav-link">首页</a></div><div class="nav-item"><a href="http://fseller.com" target="_blank" rel="noopener noreferrer" class="nav-link external">
- 个人游戏网站
- <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="前端" class="dropdown-title"><a href="/blog/web/" class="link-title">前端</a> <span class="title" style="display:none;">前端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>前端文章</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/blog/pages/8143cc480faf9a11/" class="nav-link">JavaScript</a></li></ul></li><li class="dropdown-item"><h4>学习笔记</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/blog/note/javascript/" class="nav-link">《JavaScript教程》</a></li><li class="dropdown-subitem"><a href="/blog/note/js/" class="nav-link">《JavaScript高级程序设计》</a></li><li class="dropdown-subitem"><a href="/blog/note/es6/" class="nav-link">《ES6 教程》</a></li><li class="dropdown-subitem"><a href="/blog/note/vue/" class="nav-link">《Vue》</a></li><li class="dropdown-subitem"><a href="/blog/note/react/" class="nav-link">《React》</a></li><li class="dropdown-subitem"><a href="/blog/note/typescript-axios/" class="nav-link">《TypeScript 从零实现 axios》</a></li><li class="dropdown-subitem"><a href="/blog/note/git/" class="nav-link">《Git》</a></li><li class="dropdown-subitem"><a href="/blog/pages/51afd6/" class="nav-link">TypeScript</a></li><li class="dropdown-subitem"><a href="/blog/pages/4643cd/" class="nav-link">JS设计模式总结</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="页面" class="dropdown-title"><a href="/blog/ui/" class="link-title">页面</a> <span class="title" style="display:none;">页面</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/pages/8309a5b876fc95e3/" class="nav-link">HTML</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/0a83b083bdf257cb/" class="nav-link">CSS</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="技术" class="dropdown-title"><a href="/blog/technology/" class="link-title">技术</a> <span class="title" style="display:none;">技术</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/pages/9a7ee40fc232253e/" class="nav-link">技术文档</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/4c778760be26d8b3/" class="nav-link">GitHub技巧</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/117708e0af7f0bd9/" class="nav-link">Nodejs</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/41f87d890d0a02af/" class="nav-link">博客搭建</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="更多" class="dropdown-title"><a href="/blog/more/" class="link-title">更多</a> <span class="title" style="display:none;">更多</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/pages/f2a556/" class="nav-link">学习</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/aea6571b7a8bae86/" class="nav-link">面试</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/2d615df9a36a98ed/" class="nav-link">心情杂货</a></li><li class="dropdown-item"><!----> <a href="/blog/pages/baaa02/" class="nav-link">实用技巧</a></li><li class="dropdown-item"><!----> <a href="/blog/friends/" class="nav-link">友情链接</a></li></ul></div></div><div class="nav-item"><a href="/blog/about/" class="nav-link">关于</a></div><div class="nav-item"><a href="/blog/pages/beb6c0bd8a66cea6/" class="nav-link">收藏</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/blog/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/blog/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/blog/archives/" class="nav-link">归档</a></li></ul></div></div> <a href="https://github.com/heBody/blog" target="_blank" rel="noopener noreferrer" class="repo-link">
- GitHub
- <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><a href="/blog/pages/0796ba76b4b55368/" class="sidebar-link">基础</a></li><li><a href="/blog/pages/74d2ab3fbfeaaa68/" class="sidebar-link">内置对象</a></li><li><a href="/blog/pages/659b5af5e2e704e0/" class="sidebar-link">面向对象</a></li><li><a href="/blog/pages/d61b1cb4cdac1f63/" class="sidebar-link">异步操作</a></li><li><a href="/blog/pages/7d961b8030c6099e/" class="sidebar-link">DOM</a></li><li><a href="/blog/pages/10b2761db5a8e089/" aria-current="page" class="active sidebar-link">事件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#一、eventtarget-接口" class="sidebar-link">一、EventTarget 接口</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、概述" class="sidebar-link">1、概述</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、eventtarget-addeventlistener" class="sidebar-link">2、EventTarget.addEventListener()</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、eventtarget-removeeventlistener" class="sidebar-link">3、EventTarget.removeEventListener()</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_4、eventtarget-dispatchevent" class="sidebar-link">4、EventTarget.dispatchEvent()</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#二、事件模型" class="sidebar-link">二、事件模型</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、监听函数" class="sidebar-link">1、监听函数</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-2-html-的-on-属性" class="sidebar-link">1.2 HTML 的 on- 属性</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-2-元素节点的事件属性-例-el-onclick" class="sidebar-link">1.2 元素节点的事件属性 (例:el.onclick)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-3-eventtarget-addeventlistener" class="sidebar-link">1.3 EventTarget.addEventListener()</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-4-小结" class="sidebar-link">1.4 小结</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、this-的指向-指向元素节点" class="sidebar-link">2、this 的指向 (指向元素节点)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、事件的传播-捕获、目标、冒泡" class="sidebar-link">3、事件的传播(捕获、目标、冒泡)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_4、事件的代理" class="sidebar-link">4、事件的代理</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#阻止事件冒泡-event-stoppropagation" class="sidebar-link">阻止事件冒泡 event.stopPropagation()</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#三、event-对象" class="sidebar-link">三、Event 对象</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1-概述" class="sidebar-link">1. 概述</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2-实例属性" class="sidebar-link">2. 实例属性</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-1-event-bubbles-是否会冒泡-只读-event-eventphase-返回整数-表示事件所处阶段-只读" class="sidebar-link">2.1 Event.bubbles 是否会冒泡,只读,Event.eventPhase 返回整数,表示事件所处阶段,只读</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-2-event-cancelable-是否可取消默认行为-event-cancelbubble是否阻止冒泡-event-defaultprevented-是否调用过取消默认行为方法" class="sidebar-link">2.2 Event.cancelable 是否可取消默认行为,Event.cancelBubble是否阻止冒泡,event.defaultPrevented 是否调用过取消默认行为方法</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-3-event-currenttarget当前正在通过的节点-event-target目标节点" class="sidebar-link">2.3 Event.currentTarget当前正在通过的节点,Event.target目标节点</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-4-event-type-事件类型-如-click" class="sidebar-link">2.4 Event.type 事件类型(如:'click')</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-5-event-timestamp-相对于打开网页后的毫秒时间戳" class="sidebar-link">2.5 Event.timeStamp 相对于打开网页后的毫秒时间戳</a></li><li class="sidebar-sub-header level6"><a href="/blog/pages/10b2761db5a8e089/#例子-计算鼠标移动速度" class="sidebar-link">例子:计算鼠标移动速度</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-6-event-istrusted-是否由真实用户行为产生的事件" class="sidebar-link">2.6 Event.isTrusted 是否由真实用户行为产生的事件</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-7-event-detail-事件的细节-单击or双击等" class="sidebar-link">2.7 Event.detail 事件的细节(单击or双击等)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、实例方法" class="sidebar-link">3、实例方法</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-1-event-preventdefault-取消浏览器对当前事件的默认行为" class="sidebar-link">3.1 Event.preventDefault() 取消浏览器对当前事件的默认行为</a></li><li class="sidebar-sub-header level6"><a href="/blog/pages/10b2761db5a8e089/#例子-只能输入字母的输入框" class="sidebar-link">例子:只能输入字母的输入框</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-2-event-stoppropagation-阻止事件传播" class="sidebar-link">3.2 Event.stopPropagation() 阻止事件传播</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-3-event-stopimmediatepropagation-阻止同一个事件的其他监听函数被调用" class="sidebar-link">3.3 Event.stopImmediatePropagation() 阻止同一个事件的其他监听函数被调用</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-4-event-composedpath-数组-目标和冒泡的节点" class="sidebar-link">3.4 Event.composedPath() 数组,目标和冒泡的节点</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#四、鼠标事件" class="sidebar-link">四、鼠标事件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、鼠标事件的种类" class="sidebar-link">1、鼠标事件的种类</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、mouseevent-接口概述" class="sidebar-link">2、MouseEvent 接口概述</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、mouseevent-接口的实例属性" class="sidebar-link">3、MouseEvent 接口的实例属性</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-1-mouseevent-altkey-mouseevent-ctrlkey-mouseevent-metakey-mouseevent-shiftkey" class="sidebar-link">3.1 MouseEvent.altKey,MouseEvent.ctrlKey,MouseEvent.metaKey,MouseEvent.shiftKey</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-2-mouseevent-button-鼠标的哪个键-mouseevent-buttons同时按哪些键" class="sidebar-link">3.2 MouseEvent.button 鼠标的哪个键,MouseEvent.buttons同时按哪些键</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-3-mouseevent-clientx-相对浏览器x坐标-mouseevent-clienty-相对浏览器y坐标" class="sidebar-link">3.3 MouseEvent.clientX 相对浏览器X坐标,MouseEvent.clientY 相对浏览器Y坐标</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-4-mouseevent-movementx-上一个鼠标经过事件的x距离-mouseevent-movementy-上一个鼠标经过事件的y距离" class="sidebar-link">3.4 MouseEvent.movementX 上一个鼠标经过事件的X距离,MouseEvent.movementY 上一个鼠标经过事件的Y距离</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-5-mouseevent-screenx-相对屏幕x坐标-mouseevent-screeny-相对屏幕y坐标" class="sidebar-link">3.5 MouseEvent.screenX 相对屏幕X坐标,MouseEvent.screenY 相对屏幕Y坐标</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-6-mouseevent-offsetx-偏移量x-mouseevent-offsety-偏移量y" class="sidebar-link">3.6 MouseEvent.offsetX 偏移量X,MouseEvent.offsetY 偏移量Y</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-7-mouseevent-pagex-文档x坐标-mouseevent-pagey-文档y坐标" class="sidebar-link">3.7 MouseEvent.pageX 文档X坐标,MouseEvent.pageY 文档Y坐标</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-8-mouseevent-relatedtarget-事件的相关节点" class="sidebar-link">3.8 MouseEvent.relatedTarget 事件的相关节点</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_4、mouseevent-接口的实例方法" class="sidebar-link">4、MouseEvent 接口的实例方法</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-1-mouseevent-getmodifierstate-是否按下指定功能键" class="sidebar-link">4.1 MouseEvent.getModifierState() 是否按下指定功能键</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_5、wheelevent-接口-滚轮" class="sidebar-link">5、WheelEvent 接口 (滚轮)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_5-1-概述" class="sidebar-link">5.1 概述</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_5-2-实例属性" class="sidebar-link">5.2 实例属性</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#五、键盘事件" class="sidebar-link">五、键盘事件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、键盘事件的种类" class="sidebar-link">1、键盘事件的种类</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、keyboardevent-接口概述" class="sidebar-link">2、KeyboardEvent 接口概述</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、keyboardevent-的实例属性" class="sidebar-link">3、KeyboardEvent 的实例属性</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-1-keyboardevent-altkey-keyboardevent-ctrlkey-keyboardevent-metakey-keyboardevent-shiftkey-【是否按下对应键-布尔值】" class="sidebar-link">3.1 KeyboardEvent.altKey,KeyboardEvent.ctrlKey,KeyboardEvent.metaKey,KeyboardEvent.shiftKey 【是否按下对应键,布尔值】</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-2-keyboardevent-code-键码" class="sidebar-link">3.2 KeyboardEvent.code 键码</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-3-keyboardevent-key-键名" class="sidebar-link">3.3 KeyboardEvent.key 键名</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-4-keyboardevent-location-键处于哪个位置-整数" class="sidebar-link">3.4 KeyboardEvent.location 键处于哪个位置,整数</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-5-keyboardevent-repeat-是否长按" class="sidebar-link">3.5 KeyboardEvent.repeat 是否长按</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_4、keyboardevent-的实例方法" class="sidebar-link">4、KeyboardEvent 的实例方法</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-1-keyboardevent-getmodifierstate-是否按下指定功能键" class="sidebar-link">4.1 KeyboardEvent.getModifierState() 是否按下指定功能键</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#六、进度事件" class="sidebar-link">六、进度事件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、进度事件的种类" class="sidebar-link">1、进度事件的种类</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、progressevent-接口" class="sidebar-link">2、ProgressEvent 接口</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-1-概述" class="sidebar-link">2.1 概述</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-2-progressevent的实例属性。" class="sidebar-link">2.2 ProgressEvent的实例属性。</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#七、表单事件" class="sidebar-link">七、表单事件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、表单事件的种类" class="sidebar-link">1、表单事件的种类</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-1-input-事件-值发生变化触发-会连续" class="sidebar-link">1.1 input 事件 (值发生变化触发,会连续)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-2-select-事件-选中文本时触发" class="sidebar-link">1.2 select 事件 (选中文本时触发)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-3-change-事件-值发生变化时触发-单次" class="sidebar-link">1.3 change 事件 (值发生变化时触发,单次)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-4-invalid-事件-表单提交不满足条件触发" class="sidebar-link">1.4 invalid 事件 (表单提交不满足条件触发)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-5-reset-事件-重置-submit-事件-提交" class="sidebar-link">1.5 reset 事件(重置),submit 事件(提交)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、inputevent-接口-input事件的实例" class="sidebar-link">2、InputEvent 接口(input事件的实例)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-inputevent-data-变动的那部分内容" class="sidebar-link">(1)InputEvent.data 变动的那部分内容</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-inputevent-inputtype-变更类型" class="sidebar-link">(2)InputEvent.inputType 变更类型</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-inputevent-datatransfer" class="sidebar-link">(3)InputEvent.dataTransfer</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#八、触摸事件" class="sidebar-link">八、触摸事件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、触摸操作概述" class="sidebar-link">1、触摸操作概述</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、touch-接口" class="sidebar-link">2、Touch 接口</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-1-touch-接口概述-单个触摸点" class="sidebar-link">2.1 Touch 接口概述 (单个触摸点)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-2-touch-接口的实例属性" class="sidebar-link">2.2 Touch 接口的实例属性</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_1-touch-identifier-触摸点的id" class="sidebar-link">(1)Touch.identifier 触摸点的ID</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_2-touch-screenx-touch-screeny-touch-clientx-touch-clienty-pagex-pagey-相对屏幕、浏览器、文档的坐标" class="sidebar-link">(2)Touch.screenX,Touch.screenY,Touch.clientX,Touch.clientY,pageX,pageY (相对屏幕、浏览器、文档的坐标)</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_3-touch-radiusx-touch-radiusy-touch-rotationangle-触摸椭圆区域半径、角度" class="sidebar-link">(3)Touch.radiusX,Touch.radiusY,Touch.rotationAngle (触摸椭圆区域半径、角度)</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_4-touch-force-触摸压力" class="sidebar-link">(4)Touch.force 触摸压力</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_5-touch-target-开始触摸时的元素" class="sidebar-link">(5)Touch.target 开始触摸时的元素</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、touchlist-接口" class="sidebar-link">3、TouchList 接口</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_4、touchevent-接口" class="sidebar-link">4、TouchEvent 接口</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-1-概述" class="sidebar-link">4.1 概述</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-2-实例属性" class="sidebar-link">4.2 实例属性</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_1-touchevent-altkey-touchevent-ctrlkey-touchevent-shiftkey-touchevent-metakey-是否同时按某些功能键" class="sidebar-link">(1)TouchEvent.altKey,TouchEvent.ctrlKey,TouchEvent.shiftKey,TouchEvent.metaKey (是否同时按某些功能键)</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_2-touchevent-changedtouches-触摸点集合-不同触摸事件-含义不同" class="sidebar-link">(2)TouchEvent.changedTouches (触摸点集合,不同触摸事件,含义不同)</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_3-touchevent-touches-仍然活动的触摸点集合" class="sidebar-link">(3)TouchEvent.touches (仍然活动的触摸点集合)</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#_4-touchevent-targettouches-目标元素内活动的触摸点集合" class="sidebar-link">(4)TouchEvent.targetTouches (目标元素内活动的触摸点集合)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_5、触摸事件的种类" class="sidebar-link">5、触摸事件的种类</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#九、拖拉事件" class="sidebar-link">九、拖拉事件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、拖拉事件的种类" class="sidebar-link">1、拖拉事件的种类</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、dragevent-接口" class="sidebar-link">2、DragEvent 接口</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、datatransfer-接口概述" class="sidebar-link">3、DataTransfer 接口概述</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_4、datatransfer-的实例属性" class="sidebar-link">4、DataTransfer 的实例属性</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-1-datatransfer-dropeffect-设置接受拖拉的区域的效果" class="sidebar-link">4.1 DataTransfer.dropEffect 设置接受拖拉的区域的效果</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-2-datatransfer-effectallowed-设置被拖拉的节点允许的效果" class="sidebar-link">4.2 DataTransfer.effectAllowed 设置被拖拉的节点允许的效果</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-3-datatransfer-files-本地文件" class="sidebar-link">4.3 DataTransfer.files 本地文件</a></li><li class="sidebar-sub-header level5"><a href="/blog/pages/10b2761db5a8e089/#例子-接收拖拉文件" class="sidebar-link">例子:接收拖拉文件</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-4-datatransfer-types-数据格式" class="sidebar-link">4.4 DataTransfer.types 数据格式</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-5-datatransfer-items" class="sidebar-link">4.5 DataTransfer.items</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_5、datatransfer-的实例方法" class="sidebar-link">5、DataTransfer 的实例方法</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_5-1-datatransfer-setdata-设置拖拉事件所带有的数据" class="sidebar-link">5.1 DataTransfer.setData() 设置拖拉事件所带有的数据</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_5-2-datatransfer-getdata-返回指定类型的数据" class="sidebar-link">5.2 DataTransfer.getData() 返回指定类型的数据</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_5-3-datatransfer-cleardata-清除指定或全部数据" class="sidebar-link">5.3 DataTransfer.clearData() 清除指定或全部数据</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_5-4-datatransfer-setdragimage-设置拖动过程中的图片" class="sidebar-link">5.4 DataTransfer.setDragImage() 设置拖动过程中的图片</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#十、其他常见事件" class="sidebar-link">十、其他常见事件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、资源事件" class="sidebar-link">1、资源事件</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-1-beforeunload-事件-关闭窗口前调用" class="sidebar-link">1.1 beforeunload 事件 (关闭窗口前调用)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-2-unload-事件-即将关闭窗口时调用" class="sidebar-link">1.2 unload 事件 (即将关闭窗口时调用)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_1-3-load-事件-error-事件-abort事件-页面或某个资源加载成功-失败-取消时调用" class="sidebar-link">1.3 load 事件,error 事件 ,abort事件 (页面或某个资源加载成功/失败/取消时调用)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、session-历史事件" class="sidebar-link">2、session 历史事件</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-1-pageshow-事件-页面显示-加载页面后执行-pagehide-事件-退出当前页面触发" class="sidebar-link">2.1 pageshow 事件(页面显示,加载页面后执行),pagehide 事件(退出当前页面触发)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-2-popstate-事件-在浏览器的history对象的当前记录发生显式切换时触发" class="sidebar-link">2.2 popstate 事件(在浏览器的history对象的当前记录发生显式切换时触发)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_2-3-hashchange-事件-hash发生变化时触发" class="sidebar-link">2.3 hashchange 事件 (hash发生变化时触发)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、网页状态事件" class="sidebar-link">3、网页状态事件</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-1-domcontentloaded-事件-dom内容加载完成后触发" class="sidebar-link">3.1 DOMContentLoaded 事件 (DOM内容加载完成后触发)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_3-2-readystatechange-事件-document-对象和-xmlhttprequest-对象的readystate属性发生变化时触发" class="sidebar-link">3.2 readystatechange 事件(Document 对象和 XMLHttpRequest 对象的readyState属性发生变化时触发)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_4、窗口事件" class="sidebar-link">4、窗口事件</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-1-scroll-事件-文档或文档元素滚动时触发" class="sidebar-link">4.1 scroll 事件 (文档或文档元素滚动时触发)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-2-resize-事件-窗口大小变化时触发" class="sidebar-link">4.2 resize 事件(窗口大小变化时触发)</a></li><li class="sidebar-sub-header level4"><a href="/blog/pages/10b2761db5a8e089/#_4-3-fullscreenchange-事件-元素进入-退出全屏时触发-fullscreenerror-事件-无法切换全屏时触发" class="sidebar-link">4.3 fullscreenchange 事件(元素进入/退出全屏时触发),fullscreenerror 事件(无法切换全屏时触发)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_5、剪贴板事件" class="sidebar-link">5、剪贴板事件</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_6、焦点事件" class="sidebar-link">6、焦点事件</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_7、customevent-接口-自定义事件" class="sidebar-link">7、CustomEvent 接口(自定义事件)</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#十一、globaleventhandlers-接口-全局事件处理接口" class="sidebar-link">十一、GlobalEventHandlers 接口 (全局事件处理接口)</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_1、globaleventhandlers-onabort-中断事件" class="sidebar-link">1、GlobalEventHandlers.onabort (中断事件)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_2、globaleventhandlers-onerror-错误事件" class="sidebar-link">2、GlobalEventHandlers.onerror (错误事件)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_3、globaleventhandlers-onload-加载完成事件-、globaleventhandlers-onloadstart-开始加载事件" class="sidebar-link">3、GlobalEventHandlers.onload(加载完成事件)、GlobalEventHandlers.onloadstart(开始加载事件)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_4、globaleventhandlers-onfocus-获取焦点事件-globaleventhandlers-onblur-失去焦点事件" class="sidebar-link">4、GlobalEventHandlers.onfocus(获取焦点事件),GlobalEventHandlers.onblur(失去焦点事件)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_5、globaleventhandlers-onscroll-滚动事件" class="sidebar-link">5、GlobalEventHandlers.onscroll(滚动事件)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_6、globaleventhandlers-oncontextmenu-右键菜单事件-globaleventhandlers-onshow-显示右键菜单时触发" class="sidebar-link">6、GlobalEventHandlers.oncontextmenu(右键菜单事件),GlobalEventHandlers.onshow(显示右键菜单时触发)</a></li><li class="sidebar-sub-header level3"><a href="/blog/pages/10b2761db5a8e089/#_7、其他的事件属性" class="sidebar-link">7、其他的事件属性</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/blog/pages/10b2761db5a8e089/#文档" class="sidebar-link">文档</a></li></ul></li><li><a href="/blog/pages/bab4930124ad2c10/" class="sidebar-link">浏览器模型</a></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper "><div class="articleInfo-wrap" data-v-06970110><div class="articleInfo" data-v-06970110><ul class="breadcrumbs" data-v-06970110><li data-v-06970110><a href="/blog/" title="首页" class="iconfont icon-home router-link-active" data-v-06970110></a></li> <li data-v-06970110><a href="/blog/note/javascript/#《JavaScript教程》笔记" data-v-06970110>《JavaScript教程》笔记</a></li></ul> <div class="info" data-v-06970110><div title="作者" class="author iconfont icon-touxiang" data-v-06970110><a href="https://github.com/heBody" target="_blank" title="作者" class="beLink" data-v-06970110>heBody</a></div> <div title="创建时间" class="date iconfont icon-riqi" data-v-06970110><a href="javascript:;" data-v-06970110>2020-01-12</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-title">目录</div> <div class="right-menu-content"></div></div></div> <h1><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABKFJREFUSA3tVl1oFVcQnrMbrak3QUgkya1akpJYcrUtIqW1JvFBE9LiQ5v6JmJpolbMg32rVrhgoYK0QiMY6i9Y6EMaW5D+xFJaTYItIuK2Kr3+BJNwkxBj05sQY3b3nM6cs2dv9t7NT/vQJw/sndk5M/PNzJkzewGerP+pAmy+ON8lLzUJgA8ZYxYIYZmGYRnctDaWvJJAmTtfP1pvXsBCCPP8QFcCaRkZYACgDZFO4stNIcBCajEOlmmC9XpJ9bAGCaPaPmzPl32dvLSVu3BWCTQs0XQQ6g0DYgwLIoAZbBCdW/i+781o1VVlm/410mw4h06Y7bIPHNyWDyL4FHkX03Q8SrzNhZTZriieckWt7cL6MM85YcLpsi/7O9/iXFT6MswI0DmmpkSaJ0qLxFIm3+i1THHB3zmBH3PYx9CcykcLOeQVVa7QtdxTgQgEleX2AjHYfwA+2ddV77ruGoJUbhGDI09YSNXyMpUt5ylOzxgbUmtOp7NmbNt8v3arjTBfYELmLUV+M+nSawNNAUqpT3ClJWg5I3BLT+cGW/DXNGCa6tx1aakCGEigArTn4TDIPdrXXYKCZNrHLMCOEPvHBlLQ99s9eHB7EB6NTki73CVPQ2F5MSx/uRQixfmq7rK0wYD8w8E905bnPDfwoWs/rfv93NWN/ZfvwsLIU7A09gxECyISeGJkHAau98L97tuw7NXnoPyNF8FcYGLGKsOs0mN3OEyec9esGW/ZEl945dTP34wlR2FZVQWU1q0Cw8Tr7p+hgLLNL0FPxx/Q35mA8aEUrH6nCgwEl0tn7wUiZYJnNRh6DK4UH/k0lfyrsBKdPVv/AriGIQcEDQZ65LBAGe2Rzui9Ybjz7XUppz1/uKBbyVPGkN3ZAeC6hr0x7Nr38N5+EqkoOm17xpoqR9ohQF55ERSvr4Dkr3chNfC3DMzGJlNBElW8w9nsGQvhNGIzDkXzCg8cLK951xHsFBlTJspJNi3ZFIMF2AeDV3q8DNOB+YHi6QTrChDIWDBRi5U5f+ZMfJLu3ccrqxtdxk4SKH336LFxSmkqefwU5T8fhdSdQf9IVKD6aNiwI/hnmcAZ91isYMJIaCUCx9W098+LgruikeTqzqqxKPUwqJyCPJiyemVVZBOijDGjD38Os0jOiSPL1z3SPjXNANbiNPXAdzTfukjjuknNBbyz3nwgTd3AVFqUJ5hpHlq9MveLnWwttUfoygBmvVjuikxND3znrhsELnZk7k+OjIGxeNEkomyLVta0xxn+HZhjBc4YZ/AFjHjz9u3xRZl2BN4aq9nFwWh16IrQ1aHHEd3j1+4/dB9OtH4e29A2H1DyHQRmOSfQZ1Fy7MHBTGB6J/Djq6p3OxyO2cB+4Car7v/o3GXgfAkj23+x9ID1Teoamo/SXcbvSf2PX7Vc8DdCmE1vN9di+32P9/5YR3vLnhCVGUWBjEkr3yh4H8v9CzmsbdhzOKzsJKM90iFdaTMjRPhGVsakRvOaRidljo6H6G7j+ctrJpsP+4COhDIl0La2+FS4+5mlocBaXY5QnGZysIBYoeSsl5qQzrSj/cgNrfuEzlWBfwA+EjrZyWUvpAAAAABJRU5ErkJggg==">事件<!----></h1> <div class="theme-vdoing-content content__default"><h1 id="事件"><a href="#事件" class="header-anchor">#</a> 事件</h1> <h2 id="一、eventtarget-接口"><a href="#一、eventtarget-接口" class="header-anchor">#</a> 一、EventTarget 接口</h2> <p>事件的本质是程序各个组成部分之间的一种通信方式,也是异步编程的一种实现。DOM 支持大量的事件,本章开始介绍 <strong>DOM 的事件编程</strong>。</p> <h3 id="_1、概述"><a href="#_1、概述" class="header-anchor">#</a> 1、概述</h3> <p><strong>DOM 的事件操作(监听和触发),都定义在<code>EventTarget</code>接口</strong>。所有节点对象都部署了这个接口,其他一些需要事件通信的浏览器内置对象(比如,<code>XMLHttpRequest</code>、<code>AudioNode</code>、<code>AudioContext</code>)也部署了这个接口。</p> <p>该接口主要提供三个实例方法。</p> <ul><li><code>addEventListener</code>:绑定事件的监听函数</li> <li><code>removeEventListener</code>:移除事件的监听函数</li> <li><code>dispatchEvent</code>:触发事件</li></ul> <h3 id="_2、eventtarget-addeventlistener"><a href="#_2、eventtarget-addeventlistener" class="header-anchor">#</a> 2、EventTarget.addEventListener()</h3> <p><code>EventTarget.addEventListener()</code>用于<strong>在当前节点或对象上,定义一个特定事件的监听函数</strong>。<strong>一旦这个事件发生,就会执行监听函数</strong>。该方法没有返回值。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>target<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> listener<span class="token punctuation">[</span><span class="token punctuation">,</span> useCapture<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 事件名称,监听函数 [,是否在捕获阶段触发]</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>该方法接受三个参数。</p> <ul><li><code>type</code>:事件名称,大小写敏感。</li> <li><code>listener</code>:监听函数。事件发生时,会调用该监听函数。</li> <li><code>useCapture</code>:布尔值,表示监听函数是否在捕获阶段(capture)触发(参见后文《事件的传播》部分),默认为<code>false</code>(监听函数只在冒泡阶段被触发)。该参数可选。</li></ul> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">hello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">var</span> button <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'btn'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- button<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> hello<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>上面代码中,<code>button</code>节点的<code>addEventListener</code>方法绑定<code>click</code>事件的监听函数<code>hello</code>,该函数只在冒泡阶段触发。</p> <p>关于参数,有两个地方需要注意。</p> <p>首先,第二个参数除了监听函数,还可以是一个具有<code>handleEvent</code>方法的对象。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>buttonElement<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
- <span class="token function-variable function">handleEvent</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>上面代码中,<code>addEventListener</code>方法的第二个参数,就是一个具有<code>handleEvent</code>方法的对象。</p> <p>其次,<strong>第三个参数除了布尔值<code>useCapture</code>,还可以是一个属性配置对象</strong>。该对象有以下属性。</p> <blockquote><ul><li><code>capture</code>:布尔值,表示该事件是否在<code>捕获阶段</code>触发监听函数。</li> <li><code>once</code>:布尔值,表示监听函数是否只触发一次,然后就自动移除。</li> <li><code>passive</code>:布尔值,表示监听函数不会调用事件的<code>preventDefault</code>方法。如果监听函数调用了,浏览器将忽略这个要求,并在监控台输出一行警告。</li></ul></blockquote> <p>如果希望事件监听函数<strong>只执行一次</strong>,可以打开属性配置对象的<code>once</code>属性。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>element<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 只执行一次的代码</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">once</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p><code>addEventListener</code>方法可以为针对当前对象的同一个事件,添加多个不同的监听函数。这些函数按照添加顺序触发,即先添加先触发。如果为同一个事件多次添加同一个监听函数,该函数只会执行一次,多余的添加将自动被去除(不必使用<code>removeEventListener</code>方法手动去除)。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">hello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> hello<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> hello<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>执行上面代码,点击文档只会输出一行<code>Hello world</code>。</p> <p>如果<strong>希望向监听函数传递参数,可以用匿名函数包装一下监听函数。</strong></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">var</span> el <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'div1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'Hello'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>上面代码通过匿名函数,向监听函数<code>print</code>传递了一个参数。</p> <p>监听函数<strong>内部的<code>this</code>,指向当前事件所在的那个对象。</strong></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <p id="para">Hello</p></span>
- <span class="token keyword">var</span> para <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'para'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- para<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>nodeName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "P"</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>上面代码中,监听函数内部的<code>this</code>指向事件所在的对象<code>para</code>。</p> <h3 id="_3、eventtarget-removeeventlistener"><a href="#_3、eventtarget-removeeventlistener" class="header-anchor">#</a> 3、EventTarget.removeEventListener()</h3> <p><code>EventTarget.removeEventListener</code>方法<strong>用来移除<code>addEventListener</code>方法添加的事件监听函数</strong>。该方法没有返回值。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> listener<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> listener<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p><code>removeEventListener</code>方法的参数,与<code>addEventListener</code>方法完全一致。它的第一个参数“事件类型”,大小写敏感。</p> <p>注意,<code>removeEventListener</code>方法移除的监听函数,必须是<code>addEventListener</code>方法添加的那个监听函数,而且必须在同一个元素节点,否则无效。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 移除无效,因为不是同一个监听函数</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>上面代码中,<code>removeEventListener</code>方法无效,因为监听函数不是同一个匿名函数。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>element<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mousedown'</span><span class="token punctuation">,</span> handleMouseDown<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- element<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mousedown"</span><span class="token punctuation">,</span> handleMouseDown<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 移除无效,第三个参数不一样</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>上面代码中,<code>removeEventListener</code>方法也是无效的,因为第三个参数不一样。</p> <h3 id="_4、eventtarget-dispatchevent"><a href="#_4、eventtarget-dispatchevent" class="header-anchor">#</a> 4、EventTarget.dispatchEvent()</h3> <p><code>EventTarget.dispatchEvent</code>方法在当前节点上<strong>触发指定事件,从而触发监听函数的执行。该方法返回一个布尔值</strong>,只要有一个监听函数调用了<code>Event.preventDefault()</code>,则返回值为<code>false</code>,否则为<code>true</code>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>target<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>dispatchEvent</code>方法的<strong>参数是一个<code>Event</code>对象的实例</strong>(详见《Event 对象》章节)。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>para<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> hello<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> event <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- para<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>上面代码在当前节点触发了<code>click</code>事件。</p> <p>如果<code>dispatchEvent</code>方法的参数为空,或者不是一个有效的事件对象,将报错。</p> <p>下面代码根据<code>dispatchEvent</code>方法的返回值,<strong>判断事件是否被取消</strong>了。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> canceled <span class="token operator">=</span> <span class="token operator">!</span>cb<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>canceled<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'事件取消'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'事件未取消'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h2 id="二、事件模型"><a href="#二、事件模型" class="header-anchor">#</a> 二、事件模型</h2> <h3 id="_1、监听函数"><a href="#_1、监听函数" class="header-anchor">#</a> 1、监听函数</h3> <p>浏览器的事件模型,就是通过监听函数(listener)对事件做出反应。事件发生后,浏览器监听到了这个事件,就会执行对应的监听函数。这是事件驱动编程模式(event-driven)的主要编程方式。</p> <p>JavaScript 有三种方法,可以为事件绑定监听函数。</p> <h4 id="_1-2-html-的-on-属性"><a href="#_1-2-html-的-on-属性" class="header-anchor">#</a> 1.2 HTML 的 on- 属性</h4> <p>HTML 语言允许在元素的属性中,直接定义某些事件的监听代码。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>body</span> <span class="token special-attr"><span class="token attr-name">onload</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript"><span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 加圆括号--></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token special-attr"><span class="token attr-name">onclick</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'触发事件'</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>上面代码为<code>body</code>节点的<code>load</code>事件、<code>div</code>节点的<code>click</code>事件,指定了监听代码。一旦事件发生,就会执行这段代码。</p> <p>元素的事件监听属性,都是<code>on</code>加上事件名,比如<code>onload</code>就是<code>on + load</code>,表示<code>load</code>事件的监听代码。</p> <p>注意,这些属性的值是将会执行的代码,而不是一个函数。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token comment"><!-- 正确 --></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>body</span> <span class="token special-attr"><span class="token attr-name">onload</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript"><span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>
- <span class="token comment"><!-- 错误 --></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>body</span> <span class="token special-attr"><span class="token attr-name">onload</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript">doSomething</span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>一旦指定的事件发生,<code>on-</code>属性的值是原样传入 JavaScript 引擎执行。因此如果要执行函数,<strong>不要忘记加上一对圆括号</strong>。</p> <p>使用这个方法指定的监听代码,只会在<strong>冒泡阶段触发</strong>。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token special-attr"><span class="token attr-name">onClick</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token special-attr"><span class="token attr-name">onClick</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>点击<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>上面代码中,<code><button></code>是<code><div></code>的子元素。<code><button></code>的<code>click</code>事件,也会触发<code><div></code>的<code>click</code>事件。由于<code>on-</code>属性的监听代码,只在冒泡阶段触发,所以点击结果是先输出<code>1</code>,再输出<code>2</code>,即事件<strong>从子元素开始冒泡到父元素。</strong></p> <p>直接设置<code>on-</code>属性,与通过元素节点的<code>setAttribute</code>方法设置<code>on-</code>属性,效果是一样的。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>el<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">'onclick'</span><span class="token punctuation">,</span> <span class="token string">'doSomething()'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 等同于</span>
- <span class="token comment">// <Element onclick="doSomething()"></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h4 id="_1-2-元素节点的事件属性-例-el-onclick"><a href="#_1-2-元素节点的事件属性-例-el-onclick" class="header-anchor">#</a> 1.2 元素节点的事件属性 (例:el.onclick)</h4> <p>元素节点对象的<strong>事件属性</strong>,同样可以指定监听函数。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span>onload <span class="token operator">=</span> doSomething<span class="token punctuation">;</span> <span class="token comment">// 注意这里是函数名,不加圆括号</span>
- div<span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// onclick是元素的一个属性,它指向一个函数,在触发点击时执行此函数</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'触发事件'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>使用这个方法指定的监听函数,也是只会在<strong>冒泡阶段触发</strong>。</p> <p>注意,这种方法与 HTML 的<code>on-</code>属性的差异是,它的值是函数名(<code>doSomething</code>),而不像后者,必须给出完整的监听代码(<code>doSomething()</code>)。</p> <h4 id="_1-3-eventtarget-addeventlistener"><a href="#_1-3-eventtarget-addeventlistener" class="header-anchor">#</a> 1.3 EventTarget.addEventListener()</h4> <p><strong>所有 DOM 节点实例都有<code>addEventListener</code>方法</strong>,用来为该节点定义事件的监听函数。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> doSomething<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 注意这里是函数名,不加圆括号</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>addEventListener</code>方法的详细介绍,参见<code>EventTarget</code>章节。</p> <h4 id="_1-4-小结"><a href="#_1-4-小结" class="header-anchor">#</a> 1.4 小结</h4> <p>上面三种方法,</p> <p>第一种“HTML 的 on- 属性”,违反了 HTML 与 JavaScript 代码相分离的原则,将两者写在一起,不利于代码分工,因此<strong>不推荐使用</strong>。</p> <p>第二种“元素节点的事件属性”的<strong>缺点</strong>在于,<strong>同一个事件只能定义一个监听函数</strong>,也就是说,如果定义两次<code>onclick</code>属性,后一次定义会覆盖前一次。因此,<strong>也不推荐使用</strong>。</p> <p>第三种<code>EventTarget.addEventListener</code>是<strong>推荐的指定监听函数的方法</strong>。它有如下优点:</p> <ul><li>同一个事件可以添加多个监听函数。</li> <li>能够指定在哪个阶段(捕获阶段还是冒泡阶段)触发监听函数。</li> <li>除了 DOM 节点,其他对象(比如<code>window</code>、<code>XMLHttpRequest</code>等)也有这个接口,它等于是整个 JavaScript 统一的监听函数接口。</li></ul> <h3 id="_2、this-的指向-指向元素节点"><a href="#_2、this-的指向-指向元素节点" class="header-anchor">#</a> 2、this 的指向 (指向元素节点)</h3> <p><strong>监听函数内部的<code>this</code>指向触发事件的那个元素节点。(三种事件绑定的this全指向元素节点)</strong></p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>btn<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">onclick</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>id<span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>点击<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>执行上面代码,点击后会输出<code>btn</code>。</p> <p>其他两种监听函数的写法,<code>this</code>的指向也是如此。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <button id="btn">点击</button></span>
- <span class="token keyword">var</span> btn <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'btn'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 写法一</span>
- btn<span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- <span class="token comment">// 写法二</span>
- btn<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>
- <span class="token string">'click'</span><span class="token punctuation">,</span>
- <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span>
- <span class="token boolean">false</span>
- <span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>上面两种写法,点击按钮以后也是输出<code>btn</code>。</p> <h3 id="_3、事件的传播-捕获、目标、冒泡"><a href="#_3、事件的传播-捕获、目标、冒泡" class="header-anchor">#</a> 3、事件的传播(捕获、目标、冒泡)</h3> <p>一个事件发生后,会<strong>在子元素和父元素之间传播</strong>(propagation)。这种传播分成三个阶段。</p> <ul><li><strong>第一阶段</strong>:从<code>window</code>对象传导到目标节点(上层传到底层),称为“<strong>捕获阶段</strong>”(capture phase)。</li> <li><strong>第二阶段</strong>:在目标节点上触发,称为“<strong>目标阶段</strong>”(target phase)。</li> <li><strong>第三阶段</strong>:从目标节点传导回<code>window</code>对象(从底层传回上层),称为“<strong>冒泡阶段</strong>”(bubbling phase)。</li></ul> <p>这种三阶段的传播模型,使得同一个事件会在多个节点上触发。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>点击<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>上面代码中,<code><div></code>节点之中有一个<code><p></code>节点。</p> <p>如果对这两个节点,都设置<code>click</code>事件的监听函数(每个节点的捕获阶段和冒泡阶段,各设置一个监听函数),共计设置四个监听函数。然后,对<code><p></code>点击,<code>click</code>事件会触发四次。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> phases <span class="token operator">=</span> <span class="token punctuation">{</span>
- <span class="token number">1</span><span class="token operator">:</span> <span class="token string">'capture'</span><span class="token punctuation">,</span>
- <span class="token number">2</span><span class="token operator">:</span> <span class="token string">'target'</span><span class="token punctuation">,</span>
- <span class="token number">3</span><span class="token operator">:</span> <span class="token string">'bubble'</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> p <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> callback<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true 表示在捕获阶段触发</span>
- p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> callback<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true 表示在捕获阶段触发</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> callback<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// fasle 表示在冒泡阶段触发</span>
- p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> callback<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// fasle 表示在冒泡阶段触发</span>
- <span class="token keyword">function</span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> tag <span class="token operator">=</span> event<span class="token punctuation">.</span>currentTarget<span class="token punctuation">.</span>tagName<span class="token punctuation">;</span> <span class="token comment">// 当前目标对象的标签名</span>
- <span class="token keyword">var</span> phase <span class="token operator">=</span> phases<span class="token punctuation">[</span>event<span class="token punctuation">.</span>eventPhase<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 触发的阶段</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Tag: '"</span> <span class="token operator">+</span> tag <span class="token operator">+</span> <span class="token string">"'. EventPhase: '"</span> <span class="token operator">+</span> phase <span class="token operator">+</span> <span class="token string">"'"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token comment">// 点击以后的结果</span>
- <span class="token comment">// Tag: 'DIV'. EventPhase: 'capture' 捕获阶段</span>
- <span class="token comment">// Tag: 'P'. EventPhase: 'target' 目标阶段</span>
- <span class="token comment">// Tag: 'P'. EventPhase: 'target' 目标阶段</span>
- <span class="token comment">// Tag: 'DIV'. EventPhase: 'bubble' 冒泡阶段</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><p>上面代码表示,<code>click</code>事件被触发了四次:<code><div></code>节点的捕获阶段和冒泡阶段各1次,<code><p></code>节点的目标阶段触发了2次。</p> <ol><li>捕获阶段:事件从<code><div></code>向<code><p></code>传播时,触发<code><div></code>的<code>click</code>事件;</li> <li>目标阶段:事件从<code><div></code>到达<code><p></code>时,触发<code><p></code>的<code>click</code>事件;</li> <li>冒泡阶段:事件从<code><p></code>传回<code><div></code>时,再次触发<code><div></code>的<code>click</code>事件。</li></ol> <p>其中,<code><p></code>节点有两个监听函数(<code>addEventListener</code>方法第三个参数的不同,会导致绑定两个监听函数),因此它们都会因为<code>click</code>事件触发一次。所以,<code><p></code>会在<code>target</code>阶段有两次输出。</p> <p><strong>注意</strong>,<strong>浏览器总是假定<code>click</code>事件的目标节点,就是点击位置嵌套最深的那个节点</strong>(本例是<code><div></code>节点里面的<code><p></code>节点)。所以,<strong><code><p></code>节点的捕获阶段和冒泡阶段,都会显示为<code>target</code>阶段。</strong></p> <p>事件传播的最上层对象是<code>window</code>,接着依次是<code>document</code>,<code>html</code>(<code>document.documentElement</code>)和<code>body</code>(<code>document.body</code>)。也就是说,上例的事件传播顺序,在捕获阶段依次为<code>window</code>、<code>document</code>、<code>html</code>、<code>body</code>、<code>div</code>、<code>p</code>,在冒泡阶段依次为<code>p</code>、<code>div</code>、<code>body</code>、<code>html</code>、<code>document</code>、<code>window</code>。</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>捕获阶段:
- window(浏览器对象)--> document(文档对象) --> html --> body --> div --> p (点击目标,在目标阶段)
- 冒泡阶段:
- p (点击目标,在目标阶段)--> div --> body --> html --> document(文档对象) --> window(浏览器对象)
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h3 id="_4、事件的代理"><a href="#_4、事件的代理" class="header-anchor">#</a> 4、事件的代理</h3> <p>由于事件会在冒泡阶段向上传播到父节点,因此可以把<strong>子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理</strong>(delegation)。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> ul <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'ul'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- ul<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>tagName<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">'li'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 浏览器假定click嵌套最深的元素是目标元素</span>
- <span class="token comment">// some code</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>上面代码中,<code>click</code>事件的监听函数定义在<code><ul></code>节点,但是实际上,它处理的是子节点<code><li></code>的<code>click</code>事件。这样做的好处是,只要定义一个监听函数,就能处理多个子节点的事件,而不用在每个<code><li></code>节点上定义监听函数。而且以后再添加子节点,监听函数依然有效。</p> <h5 id="阻止事件冒泡-event-stoppropagation"><a href="#阻止事件冒泡-event-stoppropagation" class="header-anchor">#</a> 阻止事件冒泡 event.stopPropagation()</h5> <p>如果希望事件到某个节点为止,不再传播,可以使用事件对象的<code>stopPropagation</code>方法。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// 事件传播到 p 元素后,就不再向下传播了</span>
- p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 该方法在事件对象event上</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true表示在捕获阶段绑定事件监听函数</span>
- <span class="token comment">// 事件冒泡到 p 元素后,就不再向上冒泡了</span>
- p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false表示在冒泡阶段(默认值)绑定事件监听函数</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>上面代码中,<code>stopPropagation</code>方法分别在捕获阶段和冒泡阶段,阻止了事件的传播。</p> <p>但是,<strong><code>stopPropagation</code>方法只会阻止事件的传播,不会阻止该事件触发<code><p></code>节点的其他<code>click</code>事件的监听函数</strong>。也就是说,不是彻底取消<code>click</code>事件。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 会触发</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>上面代码中,<code>p</code>元素绑定了两个<code>click</code>事件的监听函数。<code>stopPropagation</code>方法只能阻止这个事件的传播,不能取消这个事件,因此,第二个监听函数会触发。输出结果会先是1,然后是2。</p> <p>如果<strong>想要彻底取消该事件</strong>,不再触发后面所有<code>click</code>的监听函数,<strong>可以使用<code>stopImmediatePropagation()</code>方法</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span><span class="token function">stopImmediatePropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 不会被触发</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>上面代码中,<code>stopImmediatePropagation</code>方法可以彻底取消这个事件,使得后面绑定的所有<code>click</code>监听函数都不再触发。所以,只会输出1,不会输出2。</p> <h2 id="三、event-对象"><a href="#三、event-对象" class="header-anchor">#</a> 三、Event 对象</h2> <h3 id="_1-概述"><a href="#_1-概述" class="header-anchor">#</a> 1. 概述</h3> <p><strong>事件发生以后,会产生一个事件对象,作为参数传给监听函数</strong>。浏览器原生提供一个<code>Event</code>对象,所有的事件都是这个对象的实例,或者说继承了<code>Event.prototype</code>对象。</p> <p><strong><code>Event</code>对象本身就是一个构造函数,可以用来生成新的实例</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>event <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 参数一,事件名称; 参数二,事件对象的配置对象</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>Event</code>构造函数接受两个参数。第一个参数<code>type</code>是字符串,表示事件的名称;第二个参数<code>options</code>是一个对象,表示事件对象的配置。该对象主要有下面两个属性。</p> <ul><li><code>bubbles</code>:布尔值,可选,默认为<code>false</code>,表示事件对象<strong>是否冒泡</strong>。</li> <li><code>cancelable</code>:布尔值,可选,默认为<code>false</code>,表示事件<strong>是否可以被取消</strong>,即能否用<code>Event.preventDefault()</code>取消这个事件。一旦事件被取消,就好像从来没有发生过,不会触发浏览器对该事件的默认行为。</li></ul> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> ev <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span> <span class="token comment">// 创建一个新的事件实例</span>
- <span class="token string">'look'</span><span class="token punctuation">,</span> <span class="token comment">// 事件名称</span>
- <span class="token punctuation">{</span> <span class="token comment">// 事件配置</span>
- <span class="token string-property property">'bubbles'</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token comment">// 事件是否冒泡</span>
- <span class="token string-property property">'cancelable'</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token comment">// 事件是否可以被取消</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>ev<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 触发ev实例,该实例是look事件</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>上面代码新建一个<code>look</code>事件实例,然后使用<code>dispatchEvent</code>方法触发该事件。</p> <p>注意,如果不是显式指定<code>bubbles</code>属性为<code>true</code>,生成的事件就只能在“捕获阶段”触发监听函数。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码为</span>
- <span class="token comment">// <div><p>Hello</p></div></span>
- <span class="token keyword">var</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> p <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> tag <span class="token operator">=</span> event<span class="token punctuation">.</span>currentTarget<span class="token punctuation">.</span>tagName<span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Tag: '</span> <span class="token operator">+</span> tag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 没有任何输出</span>
- <span class="token punctuation">}</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> callback<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 该事件是在冒泡阶段监听函数</span>
- <span class="token keyword">var</span> click <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- p<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>click<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 给p发出一个click事件,该事件默认不会冒泡,因此不会触发父元素div的click事件</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>上面代码中,<code>p</code>元素发出一个<code>click</code>事件,该事件默认不会冒泡。<code>div.addEventListener</code>方法指定在冒泡阶段监听,因此监听函数不会触发。如果写成<code>div.addEventListener('click', callback, true)</code>,那么在“捕获阶段”可以监听到这个事件。</p> <p>另一方面,如果这个事件在<code>div</code>元素上触发。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>click<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>那么,不管<code>div</code>元素是在冒泡阶段监听,还是在捕获阶段监听,都会触发监听函数。因为这时<code>div</code>元素是事件的目标,不存在是否冒泡的问题,<code>div</code>元素总是会接收到事件,因此导致监听函数生效。</p> <h3 id="_2-实例属性"><a href="#_2-实例属性" class="header-anchor">#</a> 2. 实例属性</h3> <h4 id="_2-1-event-bubbles-是否会冒泡-只读-event-eventphase-返回整数-表示事件所处阶段-只读"><a href="#_2-1-event-bubbles-是否会冒泡-只读-event-eventphase-返回整数-表示事件所处阶段-只读" class="header-anchor">#</a> 2.1 Event.bubbles 是否会冒泡,只读,Event.eventPhase 返回整数,表示事件所处阶段,只读</h4> <p><code>Event.bubbles</code>属性<strong>返回一个布尔值,表示当前事件是否会冒泡</strong>。该属性为<strong>只读</strong>属性,一般用来了解 Event 实例是否可以冒泡。前面说过,除非显式声明,<code>Event</code>构造函数生成的事件,默认是不冒泡的。</p> <p><code>Event.eventPhase</code>属性<strong>返回一个整数常量,表示事件目前所处的阶段。该属性只读</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> phase <span class="token operator">=</span> event<span class="token punctuation">.</span>eventPhase<span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>Event.eventPhase</code>的返回值有四种可能。</p> <ul><li>0,事件目前<strong>没有发生</strong>。</li> <li>1,事件目前处于<strong>捕获阶段</strong>,即处于从祖先节点向目标节点的传播过程中。</li> <li>2,事件<strong>到达目标节点</strong>,即<code>Event.target</code>属性指向的那个节点。</li> <li>3,事件处于<strong>冒泡阶段</strong>,即处于从目标节点向祖先节点的反向传播过程中。</li></ul> <h4 id="_2-2-event-cancelable-是否可取消默认行为-event-cancelbubble是否阻止冒泡-event-defaultprevented-是否调用过取消默认行为方法"><a href="#_2-2-event-cancelable-是否可取消默认行为-event-cancelbubble是否阻止冒泡-event-defaultprevented-是否调用过取消默认行为方法" class="header-anchor">#</a> 2.2 Event.cancelable 是否可取消默认行为,Event.cancelBubble是否阻止冒泡,event.defaultPrevented 是否调用过取消默认行为方法</h4> <p><code>Event.cancelable</code>属性<strong>返回一个布尔值,表示事件是否可以取消</strong>。该属性为<strong>只读</strong>属性,一般用来了解 Event 实例的特性。</p> <p><strong>大多数浏览器的原生事件是可以取消的</strong>。比如,取消<code>click</code>事件,点击链接将无效。但是除非显式声明,<code>Event</code>构造函数生成的事件,<strong>默认是不可以取消的</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> evt <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span><span class="token string">'foo'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- evt<span class="token punctuation">.</span>cancelable <span class="token comment">// false 默认不可取消</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>当<code>Event.cancelable</code>属性为<code>true</code>时,调用<code>Event.preventDefault()</code>就可以取消这个事件,阻止浏览器对该事件的默认行为。</p> <p>如果事件不能取消,调用<code>Event.preventDefault()</code>会没有任何效果。所以使用这个方法之前,最好用<code>Event.cancelable</code>属性判断一下是否可以取消。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">preventEvent</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>cancelable<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token string">'This event couldn\'t be canceled.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">dir</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p><code>Event.cancelBubble</code>属性是一个布尔值,如果设为<code>true</code>,相当于执行<code>Event.stopPropagation()</code>,可以<strong>阻止事件的传播。</strong></p> <p><code>Event.defaultPrevented</code>属性返回一个布尔值,表示该事件<strong>是否调用过<code>Event.preventDefault</code>方法。该属性只读。</strong></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>defaultPrevented<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'该事件已经取消了'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h4 id="_2-3-event-currenttarget当前正在通过的节点-event-target目标节点"><a href="#_2-3-event-currenttarget当前正在通过的节点-event-target目标节点" class="header-anchor">#</a> 2.3 Event.currentTarget当前正在通过的节点,Event.target目标节点</h4> <p>事件发生以后,会经过捕获和冒泡两个阶段,依次通过多个 DOM 节点。因此,任意时点都有两个与事件相关的节点,一个是事件的<strong>原始触发节点</strong>(<code>Event.target</code>),另一个是事件<strong>当前正在通过的节点</strong>(<code>Event.currentTarget</code>)。<strong>前者通常是后者的后代节点</strong>。</p> <p><code>Event.currentTarget</code>属性返回事件<strong>当前所在的节点</strong>,即事件当前正在通过的节点,也就是当前正在执行的监听函数所在的那个节点。<strong>随着事件的传播,这个属性的值会变</strong>。</p> <p><code>Event.target</code>属性返回<strong>原始触发事件的那个节点</strong>,即事件最初发生的节点。这个属性不会随着事件的传播而改变。</p> <p>事件传播过程中,不同节点的监听函数内部的<code>Event.target</code>与<code>Event.currentTarget</code>属性的值是不一样的。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码为</span>
- <span class="token comment">// <p id="para">Hello <em>World</em></p></span>
- <span class="token keyword">function</span> <span class="token function">hide</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 不管点击 Hello 或 World,总是返回 true</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">===</span> e<span class="token punctuation">.</span>currentTarget<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 点击 Hello,返回 true</span>
- <span class="token comment">// 点击 World,返回 false</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">===</span> e<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'para'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> hide<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><p>上面代码中,<code><em></code>是<code><p></code>的子节点,点击<code><em></code>或者点击<code><p></code>,都会导致监听函数执行。这时,<code>e.target</code>总是指向原始点击位置的那个节点,而<code>e.currentTarget</code>指向事件传播过程中正在经过的那个节点。由于监听函数只有事件经过时才会触发,所以<code>e.currentTarget</code>总是等同于监听函数内部的<code>this</code>。</p> <h4 id="_2-4-event-type-事件类型-如-click"><a href="#_2-4-event-type-事件类型-如-click" class="header-anchor">#</a> 2.4 Event.type 事件类型(如:'click')</h4> <p><code>Event.type</code>属性<strong>返回一个字符串,表示事件类型</strong>。事件的类型是在生成事件的时候指定的。该属性只读。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> evt <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span><span class="token string">'foo'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- evt<span class="token punctuation">.</span>type <span class="token comment">// "foo"</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h4 id="_2-5-event-timestamp-相对于打开网页后的毫秒时间戳"><a href="#_2-5-event-timestamp-相对于打开网页后的毫秒时间戳" class="header-anchor">#</a> 2.5 Event.timeStamp 相对于打开网页后的毫秒时间戳</h4> <p><code>Event.timeStamp</code>属性返回一个毫秒时间戳,表示事件发生的时间。它是相对于网页加载成功开始计算的。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> evt <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span><span class="token string">'foo'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- evt<span class="token punctuation">.</span>timeStamp <span class="token comment">// 3683.6999999995896</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>它的返回值有可能是整数,也有可能是小数(高精度时间戳),取决于浏览器的设置。</p> <p>下面是一个<strong>计算鼠标移动速度的例子</strong>,显示每秒移动的像素数量。</p> <h6 id="例子-计算鼠标移动速度"><a href="#例子-计算鼠标移动速度" class="header-anchor">#</a> 例子:计算鼠标移动速度</h6> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> previousX<span class="token punctuation">;</span>
- <span class="token keyword">var</span> previousY<span class="token punctuation">;</span>
- <span class="token keyword">var</span> previousT<span class="token punctuation">;</span>
- window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mousemove'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>
- previousX <span class="token operator">!==</span> <span class="token keyword">undefined</span> <span class="token operator">&&</span>
- previousY <span class="token operator">!==</span> <span class="token keyword">undefined</span> <span class="token operator">&&</span>
- previousT <span class="token operator">!==</span> <span class="token keyword">undefined</span>
- <span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> deltaX <span class="token operator">=</span> event<span class="token punctuation">.</span>screenX <span class="token operator">-</span> previousX<span class="token punctuation">;</span>
- <span class="token keyword">var</span> deltaY <span class="token operator">=</span> event<span class="token punctuation">.</span>screenY <span class="token operator">-</span> previousY<span class="token punctuation">;</span>
- <span class="token keyword">var</span> deltaD <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">sqrt</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">pow</span><span class="token punctuation">(</span>deltaX<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">+</span> Math<span class="token punctuation">.</span><span class="token function">pow</span><span class="token punctuation">(</span>deltaY<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> deltaT <span class="token operator">=</span> event<span class="token punctuation">.</span>timeStamp <span class="token operator">-</span> previousT<span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>deltaD <span class="token operator">/</span> deltaT <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- previousX <span class="token operator">=</span> event<span class="token punctuation">.</span>screenX<span class="token punctuation">;</span>
- previousY <span class="token operator">=</span> event<span class="token punctuation">.</span>screenY<span class="token punctuation">;</span>
- previousT <span class="token operator">=</span> event<span class="token punctuation">.</span>timeStamp<span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br></div></div><h4 id="_2-6-event-istrusted-是否由真实用户行为产生的事件"><a href="#_2-6-event-istrusted-是否由真实用户行为产生的事件" class="header-anchor">#</a> 2.6 Event.isTrusted 是否由真实用户行为产生的事件</h4> <p><code>Event.isTrusted</code>属性返回一个<strong>布尔值</strong>,表示<strong>该事件是否由真实的用户行为产生</strong>。比如,用户点击链接会产生一个<code>click</code>事件,该事件是用户产生的;<code>Event</code>构造函数生成的事件,则是脚本产生的。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> evt <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span><span class="token string">'foo'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- evt<span class="token punctuation">.</span>isTrusted <span class="token comment">// false</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>上面代码中,<code>evt</code>对象是脚本产生的,所以<code>isTrusted</code>属性返回<code>false</code>。</p> <h4 id="_2-7-event-detail-事件的细节-单击or双击等"><a href="#_2-7-event-detail-事件的细节-单击or双击等" class="header-anchor">#</a> 2.7 Event.detail 事件的细节(单击or双击等)</h4> <p><code>Event.detail</code>属性只有浏览器的 UI (用户界面)事件才具有。该属性返回一个数值,表示事件的某种信息。具体含义与事件类型相关。比如,对于<code>click</code>和<code>dblclick</code>事件,<code>Event.detail</code>是鼠标按下的次数(<code>1</code>表示单击,<code>2</code>表示双击,<code>3</code>表示三击);对于鼠标滚轮事件,<code>Event.detail</code>是滚轮正向滚动的距离,负值就是负向滚动的距离,返回值总是3的倍数。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <p>Hello</p></span>
- <span class="token keyword">function</span> <span class="token function">giveDetails</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>detail<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 快速点击的次数</span>
- <span class="token punctuation">}</span>
- document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>onclick <span class="token operator">=</span> giveDetails<span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h3 id="_3、实例方法"><a href="#_3、实例方法" class="header-anchor">#</a> 3、实例方法</h3> <h4 id="_3-1-event-preventdefault-取消浏览器对当前事件的默认行为"><a href="#_3-1-event-preventdefault-取消浏览器对当前事件的默认行为" class="header-anchor">#</a> 3.1 Event.preventDefault() 取消浏览器对当前事件的默认行为</h4> <p><code>Event.preventDefault</code>方法<strong>取消浏览器对当前事件的默认行为</strong>。比如点击链接后,浏览器默认会跳转到另一个页面,使用这个方法以后,就不会跳转了;再比如,按一下空格键,页面向下滚动一段距离,使用这个方法以后也不会滚动了。该方法生效的前提是,事件对象的<code>cancelable</code>属性为<code>true</code>,如果为<code>false</code>,调用该方法没有任何效果。</p> <p><strong>注意,该方法只是取消事件对当前元素的默认影响,不会阻止事件的传播</strong>。如果要阻止传播,可以使用<code>stopPropagation()</code>或<code>stopImmediatePropagation()</code>方法。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码为</span>
- <span class="token comment">// <input type="checkbox" id="my-checkbox" /></span>
- <span class="token keyword">var</span> cb <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'my-checkbox'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- cb<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>
- <span class="token string">'click'</span><span class="token punctuation">,</span>
- <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token punctuation">{</span> e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
- <span class="token boolean">false</span>
- <span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>上面代码中,浏览器的默认行为是单击会选中单选框,取消这个行为,就导致无法选中单选框。</p> <p>利用这个方法,可以为文本输入框设置校验条件。如果用户的输入不符合条件,就无法将字符输入文本框。</p> <h6 id="例子-只能输入字母的输入框"><a href="#例子-只能输入字母的输入框" class="header-anchor">#</a> 例子:只能输入字母的输入框</h6> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码为</span>
- <span class="token comment">// <input type="text" id="my-input" /></span>
- <span class="token keyword">var</span> input <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'my-input'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- input<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'keypress'</span><span class="token punctuation">,</span> checkName<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">checkName</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>charCode <span class="token operator"><</span> <span class="token number">97</span> <span class="token operator">||</span> e<span class="token punctuation">.</span>charCode <span class="token operator">></span> <span class="token number">122</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>上面代码为文本框的<code>keypress</code>事件设定监听函数后,将只能输入小写字母,否则输入事件的默认行为(写入文本框)将被取消,导致不能向文本框输入内容。</p> <h4 id="_3-2-event-stoppropagation-阻止事件传播"><a href="#_3-2-event-stoppropagation-阻止事件传播" class="header-anchor">#</a> 3.2 Event.stopPropagation() 阻止事件传播</h4> <p><code>stopPropagation</code>方法阻止事件在 DOM 中继续传播,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上其他的事件监听函数。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">stopEvent</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- e<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 阻止事件冒泡</span>
- <span class="token punctuation">}</span>
- el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> stopEvent<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>上面代码中,<code>click</code>事件将不会进一步冒泡到<code>el</code>节点的父节点。</p> <h4 id="_3-3-event-stopimmediatepropagation-阻止同一个事件的其他监听函数被调用"><a href="#_3-3-event-stopimmediatepropagation-阻止同一个事件的其他监听函数被调用" class="header-anchor">#</a> 3.3 Event.stopImmediatePropagation() 阻止同一个事件的其他监听函数被调用</h4> <p><code>Event.stopImmediatePropagation</code>方法阻止同一个事件的其他监听函数被调用,不管监听函数定义在当前节点还是其他节点。也就是说,该方法阻止事件的传播,比<code>Event.stopPropagation()</code>更彻底。</p> <p>如果同一个节点对于同一个事件指定了多个监听函数,这些函数会根据添加的顺序依次调用。只要其中有一个监听函数调用了<code>Event.stopImmediatePropagation</code>方法,其他的监听函数就不会再执行了。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">l1</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- e<span class="token punctuation">.</span><span class="token function">stopImmediatePropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">function</span> <span class="token function">l2</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// 不会被调用</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'hello world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> l1<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> l2<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>上面代码在<code>el</code>节点上,为<code>click</code>事件添加了两个监听函数<code>l1</code>和<code>l2</code>。由于<code>l1</code>调用了<code>event.stopImmediatePropagation</code>方法,所以<code>l2</code>不会被调用。</p> <h4 id="_3-4-event-composedpath-数组-目标和冒泡的节点"><a href="#_3-4-event-composedpath-数组-目标和冒泡的节点" class="header-anchor">#</a> 3.4 Event.composedPath() 数组,目标和冒泡的节点</h4> <p><code>Event.composedPath()</code>返回一个数组,成员是事件的最底层节点和依次冒泡经过的所有上层节点。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <div></span>
- <span class="token comment">// <p>Hello</p></span>
- <span class="token comment">// </div></span>
- <span class="token keyword">var</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> p <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span><span class="token function">composedPath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// [p, div, body, html, document, Window]</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>上面代码中,<code>click</code>事件的最底层节点是<code>p</code>,向上依次是<code>div</code>、<code>body</code>、<code>html</code>、<code>document</code>、<code>Window</code>。</p> <h2 id="四、鼠标事件"><a href="#四、鼠标事件" class="header-anchor">#</a> 四、鼠标事件</h2> <h3 id="_1、鼠标事件的种类"><a href="#_1、鼠标事件的种类" class="header-anchor">#</a> 1、鼠标事件的种类</h3> <p>鼠标事件指与鼠标相关的事件,继承了<code>MouseEvent</code>接口。具体的事件主要有以下一些。</p> <ul><li><code>click</code>:按下鼠标(通常是按下主按钮)时触发。<strong>【单击】</strong></li> <li><code>dblclick</code>:在同一个元素上双击鼠标时触发。<strong>【双击】</strong></li> <li><code>mousedown</code>:按下鼠标键时触发。<strong>【按下】</strong></li> <li><code>mouseup</code>:释放按下的鼠标键时触发。<strong>【抬起】</strong></li> <li><code>mousemove</code>:当鼠标在一个节点内部移动时触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该事件的监听函数做一些限定,比如限定一段时间内只能运行一次。<strong>【经过(多次)】</strong></li> <li><code>mouseenter</code>:鼠标进入一个节点时触发,进入子节点不会触发这个事件(详见后文)。<strong>【进入(单次)】</strong></li> <li><code>mouseover</code>:鼠标进入一个节点时触发,进入子节点会再一次触发这个事件(详见后文)。<strong>【进入+子节点】</strong></li> <li><code>mouseleave</code>:鼠标离开一个节点时触发,离开父节点不会触发这个事件(详见后文)。<strong>【离开(单次)】</strong></li> <li><code>mouseout</code>:鼠标离开一个节点时触发,离开父节点会触发这个事件(详见后文)。<strong>【离开+子节点】</strong></li> <li><code>contextmenu</code>:按下鼠标右键时(上下文菜单出现前)触发,或者按下“上下文菜单键”时触发。<strong>【右键】</strong></li> <li><code>wheel</code>:滚动鼠标的滚轮时触发,该事件继承的是<code>WheelEvent</code>接口。<strong>【滚轮】</strong></li></ul> <p><code>click</code>事件指的是,用户在同一个位置先完成<code>mousedown</code>动作,再完成<code>mouseup</code>动作。因此,触发顺序是,<code>mousedown</code>首先触发,<code>mouseup</code>接着触发,<code>click</code>最后触发。</p> <p><code>dblclick</code>事件则会在<code>mousedown</code>、<code>mouseup</code>、<code>click</code>之后触发。</p> <p><code>mouseover</code>事件和<code>mouseenter</code>事件,都是鼠标进入一个节点时触发。两者的区别是,<code>mouseenter</code>事件只触发一次,而只要鼠标在节点内部移动,<code>mouseover</code>事件会在子节点上触发多次。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">/* HTML 代码如下
- <ul>
- <li>item 1</li>
- <li>item 2</li>
- <li>item 3</li>
- </ul>
- */</span>
- <span class="token keyword">var</span> ul <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'ul'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 进入 ul 节点以后,mouseenter 事件只会触发一次</span>
- <span class="token comment">// 以后只要鼠标在节点内移动,都不会再触发这个事件</span>
- <span class="token comment">// event.target 是 ul 节点</span>
- ul<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mouseenter'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">'purple'</span><span class="token punctuation">;</span>
- <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 进入 ul 节点以后,只要在子节点上移动,mouseover 事件会触发多次</span>
- <span class="token comment">// event.target 是 li 节点</span>
- ul<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mouseover'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">'orange'</span><span class="token punctuation">;</span>
- <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><p>上面代码中,在父节点内部进入子节点,不会触发<code>mouseenter</code>事件,但是会触发<code>mouseover</code>事件。</p> <p><code>mouseout</code>事件和<code>mouseleave</code>事件,都是鼠标离开一个节点时触发。两者的区别是,在父元素内部离开一个子元素时,<code>mouseleave</code>事件不会触发,而<code>mouseout</code>事件会触发。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">/* HTML 代码如下
- <ul>
- <li>item 1</li>
- <li>item 2</li>
- <li>item 3</li>
- </ul>
- */</span>
- <span class="token keyword">var</span> ul <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'ul'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 先进入 ul 节点,然后在节点内部移动,不会触发 mouseleave 事件</span>
- <span class="token comment">// 只有离开 ul 节点时,触发一次 mouseleave</span>
- <span class="token comment">// event.target 是 ul 节点</span>
- ul<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mouseleave'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">'purple'</span><span class="token punctuation">;</span>
- <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 先进入 ul 节点,然后在节点内部移动,mouseout 事件会触发多次</span>
- <span class="token comment">// event.target 是 li 节点</span>
- ul<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mouseout'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">'orange'</span><span class="token punctuation">;</span>
- <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><p>上面代码中,在父节点内部离开子节点,不会触发<code>mouseleave</code>事件,但是会触发<code>mouseout</code>事件。</p> <h3 id="_2、mouseevent-接口概述"><a href="#_2、mouseevent-接口概述" class="header-anchor">#</a> 2、MouseEvent 接口概述</h3> <p><code>MouseEvent</code>接口代表<strong>所有鼠标事件所产生的对象都是<code>MouseEvent</code>实例</strong>。此外,<strong>滚轮事件和拖拉事件也是<code>MouseEvent</code>实例。</strong></p> <p><code>MouseEvent</code>接口<strong>继承了<code>Event</code>接口</strong>,所以拥有<code>Event</code>的所有属性和方法。它还有自己的属性和方法。</p> <p>浏览器<strong>原生提供一个<code>MouseEvent</code>构造函数</strong>,用于新建一个<code>MouseEvent</code>实例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> event <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MouseEvent</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 参数一,事件名称字符串;参数二,事件配置对象</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>MouseEvent</code>构造函数接受两个参数。第一个参数是字符串,表示<strong>事件名称</strong>;第二个参数是一个<strong>事件配置对象</strong>,该参数可选。除了<code>Event</code>接口的实例配置属性,该对象可以配置以下属性,所有属性都是可选的。</p> <ul><li><code>screenX</code>:数值,鼠标相对于<strong>屏幕</strong>的水平位置(单位像素),默认值为0,设置该属性不会移动鼠标。</li> <li><code>screenY</code>:数值,鼠标相对于<strong>屏幕</strong>的垂直位置(单位像素),其他与<code>screenX</code>相同。</li> <li><code>clientX</code>:数值,鼠标相对于<strong>程序窗口</strong>的水平位置(单位像素),默认值为0,设置该属性不会移动鼠标。</li> <li><code>clientY</code>:数值,鼠标相对于<strong>程序窗口</strong>的垂直位置(单位像素),其他与<code>clientX</code>相同。</li> <li><code>ctrlKey</code>:布尔值,是否同时按下了 Ctrl 键,默认值为<code>false</code>。</li> <li><code>shiftKey</code>:布尔值,是否同时按下了 Shift 键,默认值为<code>false</code>。</li> <li><code>altKey</code>:布尔值,是否同时按下 Alt 键,默认值为<code>false</code>。</li> <li><code>metaKey</code>:布尔值,是否同时按下 Meta 键(win键),默认值为<code>false</code>。</li> <li><code>button</code>:数值,表示按下了哪一个鼠标按键,默认值为<code>0</code>,表示按下主键(通常是鼠标的左键)或者当前事件没有定义这个属性;<code>1</code>表示按下辅助键(通常是鼠标的中间键),<code>2</code>表示按下次要键(通常是鼠标的右键)。</li> <li><code>buttons</code>:数值,表示按下了鼠标的哪些键,是一个三个比特位的二进制值,默认为<code>0</code>(没有按下任何键)。<code>1</code>(二进制<code>001</code>)表示按下主键(通常是左键),<code>2</code>(二进制<code>010</code>)表示按下次要键(通常是右键),<code>4</code>(二进制<code>100</code>)表示按下辅助键(通常是中间键)。因此,如果返回<code>3</code>(二进制<code>011</code>)就表示同时按下了左键和右键。</li> <li><code>relatedTarget</code>:节点对象,表示事件的相关节点,默认为<code>null</code>。<code>mouseenter</code>和<code>mouseover</code>事件时,表示鼠标刚刚离开的那个元素节点;<code>mouseout</code>和<code>mouseleave</code>事件时,表示鼠标正在进入的那个元素节点。</li></ul> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> event <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MouseEvent</span><span class="token punctuation">(</span><span class="token string">'click2'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
- <span class="token string-property property">'bubbles'</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
- <span class="token string-property property">'cancelable'</span><span class="token operator">:</span> <span class="token boolean">true</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> cb <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'checkbox'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- cb<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click2'</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// 绑定事件监听函数</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">22</span><span class="token punctuation">)</span> <span class="token comment">// 被执行</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span>
- cb<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 触发事件</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>上面代码生成一个鼠标点击事件,并触发该事件。</p> <h3 id="_3、mouseevent-接口的实例属性"><a href="#_3、mouseevent-接口的实例属性" class="header-anchor">#</a> 3、MouseEvent 接口的实例属性</h3> <h4 id="_3-1-mouseevent-altkey-mouseevent-ctrlkey-mouseevent-metakey-mouseevent-shiftkey"><a href="#_3-1-mouseevent-altkey-mouseevent-ctrlkey-mouseevent-metakey-mouseevent-shiftkey" class="header-anchor">#</a> 3.1 MouseEvent.altKey,MouseEvent.ctrlKey,MouseEvent.metaKey,MouseEvent.shiftKey</h4> <p><code>MouseEvent.altKey</code>、<code>MouseEvent.ctrlKey</code>、<code>MouseEvent.metaKey</code>、<code>MouseEvent.shiftKey</code>这四个属性都返回一个布尔值,表示事件发生时,是否按下对应的键。它们都是<strong>只读</strong>属性。</p> <ul><li><code>altKey</code>属性:Alt 键</li> <li><code>ctrlKey</code>属性:Ctrl 键</li> <li><code>metaKey</code>属性:Meta 键(Mac 键盘是一个四瓣的小花,Windows 键盘是 Windows 键)</li> <li><code>shiftKey</code>属性:Shift 键</li></ul> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <body onclick="showKey(event)"></span>
- <span class="token keyword">function</span> <span class="token function">showKey</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'ALT key pressed: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>altKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'CTRL key pressed: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>ctrlKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'META key pressed: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>metaKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'SHIFT key pressed: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>shiftKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>上面代码中,点击网页会输出是否同时按下对应的键。</p> <h4 id="_3-2-mouseevent-button-鼠标的哪个键-mouseevent-buttons同时按哪些键"><a href="#_3-2-mouseevent-button-鼠标的哪个键-mouseevent-buttons同时按哪些键" class="header-anchor">#</a> 3.2 MouseEvent.button 鼠标的哪个键,MouseEvent.buttons同时按哪些键</h4> <p><code>MouseEvent.button</code>属性返回<strong>一个数值,表示事件发生时按下了鼠标的哪个键</strong>。该属性<strong>只读</strong>。</p> <ul><li>0:按下主键(通常是左键),或者该事件没有初始化这个属性(比如<code>mousemove</code>事件)。</li> <li>1:按下辅助键(通常是中键或者滚轮键)。</li> <li>2:按下次键(通常是右键)。</li></ul> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码为</span>
- <span class="token comment">// <button onmouseup="whichButton(event)">点击</button></span>
- <span class="token keyword">var</span> <span class="token function-variable function">whichButton</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">switch</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>button<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">case</span> <span class="token number">0</span><span class="token operator">:</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Left button clicked.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">break</span><span class="token punctuation">;</span>
- <span class="token keyword">case</span> <span class="token number">1</span><span class="token operator">:</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Middle button clicked.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">break</span><span class="token punctuation">;</span>
- <span class="token keyword">case</span> <span class="token number">2</span><span class="token operator">:</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Right button clicked.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">break</span><span class="token punctuation">;</span>
- <span class="token keyword">default</span><span class="token operator">:</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Unexpected code: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>button<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p><code>MouseEvent.buttons</code>属性返回一个<strong>三个比特位的值</strong>,表示<strong>同时按下了哪些键</strong>。它<strong>用来处理同时按下多个鼠标键的情况</strong>。该属性<strong>只读</strong>。</p> <ul><li>1:二进制为<code>001</code>(十进制的1),表示按下左键。</li> <li>2:二进制为<code>010</code>(十进制的2),表示按下右键。</li> <li>4:二进制为<code>100</code>(十进制的4),表示按下中键或滚轮键。</li></ul> <p>同时按下多个键的时候,每个按下的键对应的比特位都会有值。比如,同时按下左键和右键,会返回3(二进制为011)。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mousemove'</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// 注意,用click时一直都是0</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>buttons<span class="token punctuation">)</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span>
- <span class="token comment">// 未按下任何键时是 0</span>
- <span class="token comment">// 按下左键 1 (001)</span>
- <span class="token comment">// 按下右键 2 (010)</span>
- <span class="token comment">// 按下中键 4 (100)</span>
- <span class="token comment">// 按下左键和右键 3 (011)</span>
- <span class="token comment">// 按下左键和中键 5 (101)</span>
- <span class="token comment">// 按下右键和中键 6 (110)</span>
- <span class="token comment">// 按下左、中、右键 7 (111)</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h4 id="_3-3-mouseevent-clientx-相对浏览器x坐标-mouseevent-clienty-相对浏览器y坐标"><a href="#_3-3-mouseevent-clientx-相对浏览器x坐标-mouseevent-clienty-相对浏览器y坐标" class="header-anchor">#</a> 3.3 MouseEvent.clientX 相对浏览器X坐标,MouseEvent.clientY 相对浏览器Y坐标</h4> <p><code>MouseEvent.clientX</code>属性返回鼠标位置相对于浏览器窗口左上角的水平坐标(单位像素),<code>MouseEvent.clientY</code>属性返回垂直坐标。这两个属性都是<strong>只读</strong>属性。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码为</span>
- <span class="token comment">// <body onmousedown="showCoords(event)"></span>
- <span class="token keyword">function</span> <span class="token function">showCoords</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>
- <span class="token string">'clientX value: '</span> <span class="token operator">+</span> evt<span class="token punctuation">.</span>clientX <span class="token operator">+</span> <span class="token string">'\n'</span> <span class="token operator">+</span>
- <span class="token string">'clientY value: '</span> <span class="token operator">+</span> evt<span class="token punctuation">.</span>clientY <span class="token operator">+</span> <span class="token string">'\n'</span>
- <span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>这两个属性还分别有一个<strong>别名<code>MouseEvent.x</code>和<code>MouseEvent.y</code></strong>。</p> <h4 id="_3-4-mouseevent-movementx-上一个鼠标经过事件的x距离-mouseevent-movementy-上一个鼠标经过事件的y距离"><a href="#_3-4-mouseevent-movementx-上一个鼠标经过事件的x距离-mouseevent-movementy-上一个鼠标经过事件的y距离" class="header-anchor">#</a> 3.4 MouseEvent.movementX 上一个鼠标经过事件的X距离,MouseEvent.movementY 上一个鼠标经过事件的Y距离</h4> <p><code>MouseEvent.movementX</code>属性返回当前位置与上一个<code>mousemove</code>事件之间的水平距离(单位像素)。数值上,它等于下面的计算公式。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>currentEvent<span class="token punctuation">.</span>movementX <span class="token operator">=</span> currentEvent<span class="token punctuation">.</span>screenX <span class="token operator">-</span> previousEvent<span class="token punctuation">.</span>screenX
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>MouseEvent.movementY</code>属性返回当前位置与上一个<code>mousemove</code>事件之间的垂直距离(单位像素)。数值上,它等于下面的计算公式。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>currentEvent<span class="token punctuation">.</span>movementY <span class="token operator">=</span> currentEvent<span class="token punctuation">.</span>screenY <span class="token operator">-</span> previousEvent<span class="token punctuation">.</span>screenY。
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>这两个属性都是<strong>只读</strong>属性。</p> <h4 id="_3-5-mouseevent-screenx-相对屏幕x坐标-mouseevent-screeny-相对屏幕y坐标"><a href="#_3-5-mouseevent-screenx-相对屏幕x坐标-mouseevent-screeny-相对屏幕y坐标" class="header-anchor">#</a> 3.5 MouseEvent.screenX 相对屏幕X坐标,MouseEvent.screenY 相对屏幕Y坐标</h4> <p><code>MouseEvent.screenX</code>属性返回鼠标位置相对于屏幕左上角的水平坐标(单位像素),<code>MouseEvent.screenY</code>属性返回垂直坐标。这两个属性都是<strong>只读</strong>属性。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <body onmousedown="showCoords(event)"></span>
- <span class="token keyword">function</span> <span class="token function">showCoords</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>
- <span class="token string">'screenX value: '</span> <span class="token operator">+</span> evt<span class="token punctuation">.</span>screenX <span class="token operator">+</span> <span class="token string">'\n'</span><span class="token punctuation">,</span>
- <span class="token string">'screenY value: '</span> <span class="token operator">+</span> evt<span class="token punctuation">.</span>screenY <span class="token operator">+</span> <span class="token string">'\n'</span>
- <span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h4 id="_3-6-mouseevent-offsetx-偏移量x-mouseevent-offsety-偏移量y"><a href="#_3-6-mouseevent-offsetx-偏移量x-mouseevent-offsety-偏移量y" class="header-anchor">#</a> 3.6 MouseEvent.offsetX 偏移量X,MouseEvent.offsetY 偏移量Y</h4> <p><code>MouseEvent.offsetX</code>属性返回鼠标位置与目标节点左侧的<code>padding</code>边缘的水平距离(单位像素),<code>MouseEvent.offsetY</code>属性返回与目标节点上方的<code>padding</code>边缘的垂直距离。这两个属性都是只读属性。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">/* HTML 代码如下
- <style>
- p {
- width: 100px;
- height: 100px;
- padding: 100px;
- }
- </style>
- <p>Hello</p>
- */</span>
- <span class="token keyword">var</span> p <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- p<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>
- <span class="token string">'click'</span><span class="token punctuation">,</span>
- <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>offsetX<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 包含padding</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>offsetY<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span>
- <span class="token boolean">false</span>
- <span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><p>上面代码中,鼠标如果在<code>p</code>元素的中心位置点击,会返回<code>150 150</code>。因此中心位置距离左侧和上方的<code>padding</code>边缘,等于<code>padding</code>的宽度(100像素)加上元素内容区域一半的宽度(50像素)。</p> <h4 id="_3-7-mouseevent-pagex-文档x坐标-mouseevent-pagey-文档y坐标"><a href="#_3-7-mouseevent-pagex-文档x坐标-mouseevent-pagey-文档y坐标" class="header-anchor">#</a> 3.7 MouseEvent.pageX 文档X坐标,MouseEvent.pageY 文档Y坐标</h4> <p><code>MouseEvent.pageX</code>属性返回鼠标位置与文档左侧边缘的距离(单位像素),<code>MouseEvent.pageY</code>属性返回与文档上侧边缘的距离(单位像素)。它们的<strong>返回值都包括文档不可见的部分</strong>。这两个属性都是<strong>只读</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">/* HTML 代码如下
- <style>
- body {
- height: 2000px;
- }
- </style>
- */</span>
- document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>
- <span class="token string">'click'</span><span class="token punctuation">,</span>
- <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>pageX<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>pageY<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span>
- <span class="token boolean">false</span>
- <span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>上面代码中,页面高度为2000像素,会产生垂直滚动条。滚动到页面底部,点击鼠标输出的<code>pageY</code>值会接近2000。</p> <h4 id="_3-8-mouseevent-relatedtarget-事件的相关节点"><a href="#_3-8-mouseevent-relatedtarget-事件的相关节点" class="header-anchor">#</a> 3.8 MouseEvent.relatedTarget 事件的相关节点</h4> <p><code>MouseEvent.relatedTarget</code>属性<strong>返回事件的相关节点</strong>。对于那些没有相关节点的事件,该属性返回<code>null</code>。该属性<strong>只读</strong>。</p> <p>下表列出不同事件的<code>target</code>属性值和<code>relatedTarget</code>属性值义。</p> <table><thead><tr><th style="text-align:left;">事件名称</th> <th style="text-align:left;">target 属性</th> <th style="text-align:left;">relatedTarget 属性</th></tr></thead> <tbody><tr><td style="text-align:left;">focusin</td> <td style="text-align:left;">接受焦点的节点</td> <td style="text-align:left;">丧失焦点的节点</td></tr> <tr><td style="text-align:left;">focusout</td> <td style="text-align:left;">丧失焦点的节点</td> <td style="text-align:left;">接受焦点的节点</td></tr> <tr><td style="text-align:left;">mouseenter</td> <td style="text-align:left;">将要进入的节点</td> <td style="text-align:left;">将要离开的节点</td></tr> <tr><td style="text-align:left;">mouseleave</td> <td style="text-align:left;">将要离开的节点</td> <td style="text-align:left;">将要进入的节点</td></tr> <tr><td style="text-align:left;">mouseout</td> <td style="text-align:left;">将要离开的节点</td> <td style="text-align:left;">将要进入的节点</td></tr> <tr><td style="text-align:left;">mouseover</td> <td style="text-align:left;">将要进入的节点</td> <td style="text-align:left;">将要离开的节点</td></tr> <tr><td style="text-align:left;">dragenter</td> <td style="text-align:left;">将要进入的节点</td> <td style="text-align:left;">将要离开的节点</td></tr> <tr><td style="text-align:left;">dragexit</td> <td style="text-align:left;">将要离开的节点</td> <td style="text-align:left;">将要进入的节点</td></tr></tbody></table> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">/*
- HTML 代码如下
- <div id="outer" style="height:50px;width:50px;border-width:1px solid black;">
- <div id="inner" style="height:25px;width:25px;border:1px solid black;"></div>
- </div>
- */</span>
- <span class="token keyword">var</span> inner <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'inner'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- inner<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mouseover'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'进入'</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>id <span class="token operator">+</span> <span class="token string">' 离开'</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>relatedTarget<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- inner<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mouseenter'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'进入'</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>id <span class="token operator">+</span> <span class="token string">' 离开'</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>relatedTarget<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- inner<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'mouseout'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'离开'</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>id <span class="token operator">+</span> <span class="token string">' 进入'</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>relatedTarget<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- inner<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mouseleave"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'离开'</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>id <span class="token operator">+</span> <span class="token string">' 进入'</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>relatedTarget<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 鼠标从 outer 进入inner,输出</span>
- <span class="token comment">// 进入inner 离开outer</span>
- <span class="token comment">// 进入inner 离开outer</span>
- <span class="token comment">// 鼠标从 inner进入 outer,输出</span>
- <span class="token comment">// 离开inner 进入outer</span>
- <span class="token comment">// 离开inner 进入outer</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><h3 id="_4、mouseevent-接口的实例方法"><a href="#_4、mouseevent-接口的实例方法" class="header-anchor">#</a> 4、MouseEvent 接口的实例方法</h3> <h4 id="_4-1-mouseevent-getmodifierstate-是否按下指定功能键"><a href="#_4-1-mouseevent-getmodifierstate-是否按下指定功能键" class="header-anchor">#</a> 4.1 MouseEvent.getModifierState() 是否按下指定功能键</h4> <p><code>MouseEvent.getModifierState</code>方法<strong>返回一个布尔值,表示有没有按下特定的功能键。它的参数是一个表示<a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState#Modifier_keys_on_Gecko" target="_blank" rel="noopener noreferrer">功能键<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>的字符串。</strong></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span><span class="token function">getModifierState</span><span class="token punctuation">(</span><span class="token string">'CapsLock'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>上面的代码可以了解用户是否按下了大写键。</p> <h3 id="_5、wheelevent-接口-滚轮"><a href="#_5、wheelevent-接口-滚轮" class="header-anchor">#</a> 5、WheelEvent 接口 (滚轮)</h3> <h4 id="_5-1-概述"><a href="#_5-1-概述" class="header-anchor">#</a> 5.1 概述</h4> <p><strong>WheelEvent 接口继承了 MouseEvent 实例,代表鼠标滚轮事件的实例对象</strong>。目前,鼠标滚轮相关的事件只有一个<code>wheel</code>事件,用户滚动鼠标的滚轮,就生成这个事件的实例。</p> <p>浏览器原生提供<code>WheelEvent()</code>构造函数,用来生成<code>WheelEvent</code>实例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> wheelEvent <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WheelEvent</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>WheelEvent()</code>构造函数可以接受两个参数,第一个是字符串,表示事件类型,对于滚轮事件来说,这个值目前只能是<code>wheel</code>。第二个参数是事件的配置对象。该对象的属性除了<code>Event</code>、<code>UIEvent</code>的配置属性以外,还可以接受以下几个属性,所有属性都是可选的。</p> <ul><li><code>deltaX</code>:数值,表示滚轮的水平滚动量,默认值是 0.0。</li> <li><code>deltaY</code>:数值,表示滚轮的垂直滚动量,默认值是 0.0。</li> <li><code>deltaZ</code>:数值,表示滚轮的 Z 轴滚动量,默认值是 0.0。</li> <li><code>deltaMode</code>:数值,表示相关的滚动事件的单位,适用于上面三个属性。<code>0</code>表示滚动单位为像素,<code>1</code>表示单位为行,<code>2</code>表示单位为页,默认为<code>0</code>。</li></ul> <h4 id="_5-2-实例属性"><a href="#_5-2-实例属性" class="header-anchor">#</a> 5.2 实例属性</h4> <p><code>WheelEvent</code>事件实例除了具有<code>Event</code>和<code>MouseEvent</code>的实例属性和实例方法,还有一些自己的实例属性,但是没有自己的实例方法。</p> <p>下面的属性都是只读属性。</p> <ul><li><code>WheelEvent.deltaX</code>:数值,表示滚轮的水平滚动量。</li> <li><code>WheelEvent.deltaY</code>:数值,表示滚轮的垂直滚动量。</li> <li><code>WheelEvent.deltaZ</code>:数值,表示滚轮的 Z 轴滚动量。</li> <li><code>WheelEvent.deltaMode</code>:数值,表示上面三个属性的单位,<code>0</code>是像素,<code>1</code>是行,<code>2</code>是页。</li></ul> <h2 id="五、键盘事件"><a href="#五、键盘事件" class="header-anchor">#</a> 五、键盘事件</h2> <h3 id="_1、键盘事件的种类"><a href="#_1、键盘事件的种类" class="header-anchor">#</a> 1、键盘事件的种类</h3> <p>键盘事件由用户击打键盘触发,主要有<code>keydown</code>、<code>keypress</code>、<code>keyup</code>三个事件,它们都继承了<code>KeyboardEvent</code>接口。</p> <ul><li><code>keydown</code>:按下键盘时触发。<strong>【按下】</strong></li> <li><code>keypress</code>:按下有值的键时触发,即按下 Ctrl、Alt、Shift、Meta 这样无值的键,这个事件不会触发。对于有值的键,按下时先触发<code>keydown</code>事件,再触发这个事件。<strong>【按下有值的键】</strong></li> <li><code>keyup</code>:松开键盘时触发该事件。<strong>【松开】</strong></li></ul> <p>如果用户一直按键不松开,就会连续触发键盘事件,触发的顺序如下。</p> <ol><li>keydown</li> <li>keypress</li> <li>keydown</li> <li>keypress</li> <li>...(重复以上过程)</li> <li>keyup</li></ol> <h3 id="_2、keyboardevent-接口概述"><a href="#_2、keyboardevent-接口概述" class="header-anchor">#</a> 2、KeyboardEvent 接口概述</h3> <p><code>KeyboardEvent</code>接口用来描述用户与键盘的互动。这个接口<strong>继承了<code>Event</code>接口</strong>,并且定义了自己的实例属性和实例方法。</p> <p>浏览器原生提供<code>KeyboardEvent</code>构造函数,用来新建键盘事件的实例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">KeyboardEvent</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span> <span class="token comment">// 参数一,事件类型;参数二,事件配置对象</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>KeyboardEvent</code>构造函数接受两个参数。第一个参数是字符串,表示<strong>事件类型</strong>;第二个参数是一个<strong>事件配置对象</strong>,该参数可选。除了<code>Event</code>接口提供的属性,还可以配置以下字段,它们都是可选。</p> <ul><li><code>key</code>:字符串,当前按下的键,默认为空字符串。<strong>【键名】</strong></li> <li><code>code</code>:字符串,表示当前按下的键的字符串形式,默认为空字符串。<strong>【键码】</strong></li> <li><code>location</code>:整数,当前按下的键的位置,默认为<code>0</code>。</li> <li><code>ctrlKey</code>:布尔值,是否按下 Ctrl 键,默认为<code>false</code>。</li> <li><code>shiftKey</code>:布尔值,是否按下 Shift 键,默认为<code>false</code>。</li> <li><code>altKey</code>:布尔值,是否按下 Alt 键,默认为<code>false</code>。</li> <li><code>metaKey</code>:布尔值,是否按下 Meta 键,默认为<code>false</code>。</li> <li><code>repeat</code>:布尔值,是否重复按键,默认为<code>false</code>。</li></ul> <h3 id="_3、keyboardevent-的实例属性"><a href="#_3、keyboardevent-的实例属性" class="header-anchor">#</a> 3、KeyboardEvent 的实例属性</h3> <h4 id="_3-1-keyboardevent-altkey-keyboardevent-ctrlkey-keyboardevent-metakey-keyboardevent-shiftkey-【是否按下对应键-布尔值】"><a href="#_3-1-keyboardevent-altkey-keyboardevent-ctrlkey-keyboardevent-metakey-keyboardevent-shiftkey-【是否按下对应键-布尔值】" class="header-anchor">#</a> 3.1 KeyboardEvent.altKey,KeyboardEvent.ctrlKey,KeyboardEvent.metaKey,KeyboardEvent.shiftKey 【是否按下对应键,布尔值】</h4> <p>以下属性都是<strong>只读</strong>属性,返回一个布尔值,表示是否按下对应的键。</p> <ul><li><code>KeyboardEvent.altKey</code>:是否按下 Alt 键</li> <li><code>KeyboardEvent.ctrlKey</code>:是否按下 Ctrl 键</li> <li><code>KeyboardEvent.metaKey</code>:是否按下 meta 键(Mac 系统是一个四瓣的小花,Windows 系统是 windows 键)</li> <li><code>KeyboardEvent.shiftKey</code>:是否按下 Shift 键</li></ul> <p>下面是一个示例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">showChar</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'ALT: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>altKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'CTRL: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>ctrlKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Meta: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>metaKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Shift: '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>shiftKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'keydown'</span><span class="token punctuation">,</span> showChar<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h4 id="_3-2-keyboardevent-code-键码"><a href="#_3-2-keyboardevent-code-键码" class="header-anchor">#</a> 3.2 KeyboardEvent.code 键码</h4> <p><code>KeyboardEvent.code</code>属性<strong>返回一个字符串,表示当前按下的键的字符串形式</strong>。该属性<strong>只读</strong>。</p> <p>下面是一些常用键的字符串形式,其他键请查<a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code#Code_values" target="_blank" rel="noopener noreferrer">文档<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>。</p> <ul><li>数字键0 - 9:返回<code>digital0</code> - <code>digital9</code></li> <li>字母键A - z:返回<code>KeyA</code> - <code>KeyZ</code></li> <li>功能键F1 - F12:返回 <code>F1</code> - <code>F12</code></li> <li>方向键:返回<code>ArrowDown</code>、<code>ArrowUp</code>、<code>ArrowLeft</code>、<code>ArrowRight</code></li> <li>Alt 键:返回<code>AltLeft</code>或<code>AltRight</code></li> <li>Shift 键:返回<code>ShiftLeft</code>或<code>ShiftRight</code></li> <li>Ctrl 键:返回<code>ControlLeft</code>或<code>ControlRight</code></li></ul> <h4 id="_3-3-keyboardevent-key-键名"><a href="#_3-3-keyboardevent-key-键名" class="header-anchor">#</a> 3.3 KeyboardEvent.key 键名</h4> <p><code>KeyboardEvent.key</code>属性<strong>返回一个字符串,表示按下的键名</strong>。该属性<strong>只读</strong>。</p> <p>如果按下的键代表可打印字符,则返回这个字符,比如数字、字母。</p> <p>如果按下的键代表不可打印的特殊字符,则返回预定义的键值,比如 Backspace,Tab,Enter,Shift,Control,Alt,CapsLock,Esc,Spacebar,PageUp,PageDown,End,Home,Left,Right,Up,Down,PrintScreen,Insert,Del,Win,F1~F12,NumLock,Scroll 等。</p> <p>如果同时按下一个控制键和一个符号键,则返回符号键的键名。比如,按下 Ctrl + a,则返回<code>a</code>;按下 Shift + a,则返回大写的<code>A</code>。</p> <p>如果无法识别键名,返回字符串<code>Unidentified</code>。</p> <h4 id="_3-4-keyboardevent-location-键处于哪个位置-整数"><a href="#_3-4-keyboardevent-location-键处于哪个位置-整数" class="header-anchor">#</a> 3.4 KeyboardEvent.location 键处于哪个位置,整数</h4> <p><code>KeyboardEvent.location</code>属性<strong>返回一个整数,表示按下的键处在键盘的哪一个区域</strong>。它可能取以下值。</p> <ul><li><p>0:处在键盘的主区域,或者无法判断处于哪一个区域。</p></li> <li><p>1:处在键盘的左侧,只适用那些有两个位置的键(比如 Ctrl 和 Shift 键)。</p></li> <li><p>2:处在键盘的右侧,只适用那些有两个位置的键(比如 Ctrl 和 Shift 键)。</p></li> <li><p>3:处在数字小键盘。</p></li></ul> <h4 id="_3-5-keyboardevent-repeat-是否长按"><a href="#_3-5-keyboardevent-repeat-是否长按" class="header-anchor">#</a> 3.5 KeyboardEvent.repeat 是否长按</h4> <p><code>KeyboardEvent.repeat</code>返回一个<strong>布尔值,代表该键是否被按着不放</strong>,以便判断是否重复这个键,即浏览器会持续触发<code>keydown</code>和<code>keypress</code>事件,直到用户松开手为止。</p> <h3 id="_4、keyboardevent-的实例方法"><a href="#_4、keyboardevent-的实例方法" class="header-anchor">#</a> 4、KeyboardEvent 的实例方法</h3> <h4 id="_4-1-keyboardevent-getmodifierstate-是否按下指定功能键"><a href="#_4-1-keyboardevent-getmodifierstate-是否按下指定功能键" class="header-anchor">#</a> 4.1 KeyboardEvent.getModifierState() 是否按下指定功能键</h4> <p><code>KeyboardEvent.getModifierState()</code>方法返回一个<strong>布尔值,表示是否按下或激活指定的功能键</strong>。它的常用参数如下。</p> <ul><li><code>Alt</code>:Alt 键</li> <li><code>CapsLock</code>:大写锁定键</li> <li><code>Control</code>:Ctrl 键</li> <li><code>Meta</code>:Meta 键</li> <li><code>NumLock</code>:数字键盘开关键</li> <li><code>Shift</code>:Shift 键</li></ul> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">if</span> <span class="token punctuation">(</span>
- event<span class="token punctuation">.</span><span class="token function">getModifierState</span><span class="token punctuation">(</span><span class="token string">'Control'</span><span class="token punctuation">)</span> <span class="token operator">+</span>
- event<span class="token punctuation">.</span><span class="token function">getModifierState</span><span class="token punctuation">(</span><span class="token string">'Alt'</span><span class="token punctuation">)</span> <span class="token operator">+</span>
- event<span class="token punctuation">.</span><span class="token function">getModifierState</span><span class="token punctuation">(</span><span class="token string">'Meta'</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">1</span>
- <span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">return</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>上面代码表示,只要<code>Control</code>、<code>Alt</code>、<code>Meta</code>里面,同时按下任意两个或两个以上的键就返回。</p> <h2 id="六、进度事件"><a href="#六、进度事件" class="header-anchor">#</a> 六、进度事件</h2> <h3 id="_1、进度事件的种类"><a href="#_1、进度事件的种类" class="header-anchor">#</a> 1、进度事件的种类</h3> <p><strong>进度事件用来描述资源加载的进度</strong>,主要由 AJAX 请求、<code><img></code>、<code><audio></code>、<code><video></code>、<code><style></code>、<code><link></code>等外部资源的加载触发,继承了<code>ProgressEvent</code>接口。它主要包含以下几种<strong>事件</strong>。</p> <ul><li><code>abort</code>:外部资源中止加载时(比如用户取消)触发。如果发生错误导致中止,不会触发该事件。<strong>【中止加载】</strong></li> <li><code>error</code>:由于错误导致外部资源无法加载时触发。<strong>【加载错误】</strong></li> <li><code>load</code>:外部资源加载成功时触发。<strong>【加载成功】</strong></li> <li><code>loadstart</code>:外部资源开始加载时触发。<strong>【开始加载】</strong></li> <li><code>loadend</code>:外部资源停止加载时触发,发生顺序排在<code>error</code>、<code>abort</code>、<code>load</code>等事件的后面。<strong>【停止加载】</strong></li> <li><code>progress</code>:外部资源加载过程中不断触发。<strong>【加载中,不断触发】</strong></li> <li><code>timeout</code>:加载超时时触发。<strong>【加载超时】</strong></li></ul> <p>注意,除了资源下载,<strong>文件上传也存在这些事件</strong>。</p> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>image<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 加载成功</span>
- image<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">'finished'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- image<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'error'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 加载出错</span>
- image<span class="token punctuation">.</span>style<span class="token punctuation">.</span>display <span class="token operator">=</span> <span class="token string">'none'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>上面代码在图片元素加载完成后,为图片元素添加一个<code>finished</code>的 Class。如果加载失败,就把图片元素的样式设置为不显示。</p> <p>有时候,图片加载会在脚本运行之前就完成,尤其是当脚本放置在网页底部的时候,因此有可能<code>load</code>和<code>error</code>事件的监听函数根本不会执行。所以,比较可靠的方式,是用<code>complete</code>属性先判断一下是否加载完成。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">loaded</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// ...</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>image<span class="token punctuation">.</span>complete<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 是否加载完成</span>
- <span class="token function">loaded</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
- image<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> loaded<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 加载成功事件</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>由于 DOM 的元素节点没有提供是否加载错误的属性,所以<code>error</code>事件的监听函数最好放在<code><img></code>元素的 HTML 代码中,这样才能保证发生加载错误时百分之百会执行。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/wrong/url<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">onerror</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript"><span class="token keyword">this</span><span class="token punctuation">.</span>style<span class="token punctuation">.</span>display<span class="token operator">=</span><span class="token string">'none'</span><span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span> <span class="token punctuation">/></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>loadend</code>事件的监听函数,可以用来取代<code>abort</code>事件、<code>load</code>事件、<code>error</code>事件的监听函数,因为它总是在这些事件之后发生。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>req<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'loadend'</span><span class="token punctuation">,</span> loadEnd<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">loadEnd</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'传输结束,成功失败未知'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p><code>loadend</code>事件本身不提供关于进度结束的原因,但可以用它来做所有加载结束场景都需要做的一些操作。</p> <p>另外,<code>error</code>事件有一个特殊的性质,就是不会冒泡。所以,子元素的<code>error</code>事件,不会触发父元素的<code>error</code>事件监听函数。</p> <h3 id="_2、progressevent-接口"><a href="#_2、progressevent-接口" class="header-anchor">#</a> 2、ProgressEvent 接口</h3> <h4 id="_2-1-概述"><a href="#_2-1-概述" class="header-anchor">#</a> 2.1 概述</h4> <p><code>ProgressEvent</code>接口主要用来描述外部资源加载的进度,比如 AJAX 加载、<code><img></code>、<code><video></code>、<code><style></code>、<code><link></code>等外部资源加载。进度相关的事件都继承了这个接口。<strong>这个接口继承了Event接口。</strong></p> <p>浏览器原生提供了<code>ProgressEvent()</code>构造函数,用来生成事件实例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">ProgressEvent</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span> <span class="token comment">// 参数一,事件类型;参数二,配置对象</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>ProgressEvent()</code>构造函数接受两个参数。第一个参数是字符串,表示事件的类型,这个参数是必须的。第二个参数是一个配置对象,表示事件的属性,该参数可选。配置对象除了可以使用<code>Event</code>接口的配置属性,还可以使用下面的属性,所有这些属性都是可选的。</p> <ul><li><code>lengthComputable</code>:布尔值,表示加载的<strong>总量是否可以计算</strong>,默认是<code>false</code>。</li> <li><code>loaded</code>:整数,表示<strong>已经加载的量</strong>,默认是<code>0</code>。</li> <li><code>total</code>:整数,表示<strong>需要加载的总量</strong>,默认是<code>0</code>。</li></ul> <h4 id="_2-2-progressevent的实例属性。"><a href="#_2-2-progressevent的实例属性。" class="header-anchor">#</a> 2.2 ProgressEvent的实例属性。</h4> <ul><li><code>ProgressEvent.lengthComputable</code> <strong>总量是否可以计算</strong></li> <li><code>ProgressEvent.loaded</code> <strong>已加载的量</strong></li> <li><code>ProgressEvent.total</code> <strong>需要加载的总量</strong></li></ul> <p>如果<code>ProgressEvent.lengthComputable</code>为<code>false</code>,<code>ProgressEvent.total</code>实际上是没有意义的。</p> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ProgressEvent</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
- <span class="token literal-property property">lengthComputable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
- <span class="token literal-property property">loaded</span><span class="token operator">:</span> <span class="token number">30</span><span class="token punctuation">,</span>
- <span class="token literal-property property">total</span><span class="token operator">:</span> <span class="token number">100</span><span class="token punctuation">,</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'已经加载:'</span> <span class="token operator">+</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>loaded <span class="token operator">/</span> e<span class="token punctuation">.</span>total<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span> <span class="token operator">+</span> <span class="token string">'%'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 已经加载:30%</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><p>上面代码先构造一个<code>load</code>事件,抛出后被监听函数捕捉到。</p> <p>下面是一个实际的例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> xhr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- xhr<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'progress'</span><span class="token punctuation">,</span> updateProgress<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 加载中</span>
- xhr<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> transferComplete<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 加载成功</span>
- xhr<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'error'</span><span class="token punctuation">,</span> transferFailed<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 加载错误</span>
- xhr<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'abort'</span><span class="token punctuation">,</span> transferCanceled<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 中止加载</span>
- xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">updateProgress</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 加载中</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>lengthComputable<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 是否可以计算总量</span>
- <span class="token keyword">var</span> percentComplete <span class="token operator">=</span> e<span class="token punctuation">.</span>loaded <span class="token operator">/</span> e<span class="token punctuation">.</span>total<span class="token punctuation">;</span> <span class="token comment">// 加载进度计算</span>
- <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'不能计算进度'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">function</span> <span class="token function">transferComplete</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 加载成功</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'传输结束'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">function</span> <span class="token function">transferFailed</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 加载错误</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'传输过程中发生错误'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">function</span> <span class="token function">transferCanceled</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 中止加载</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'用户取消了传输'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><p>上面是下载过程的进度事件,还存在<strong>上传过程的进度事件</strong>。这时所有监听函数都要放在<code>XMLHttpRequest.upload</code>对象上面。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> xhr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- xhr<span class="token punctuation">.</span>upload<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'progress'</span><span class="token punctuation">,</span> updateProgress<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- xhr<span class="token punctuation">.</span>upload<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> transferComplete<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- xhr<span class="token punctuation">.</span>upload<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'error'</span><span class="token punctuation">,</span> transferFailed<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- xhr<span class="token punctuation">.</span>upload<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'abort'</span><span class="token punctuation">,</span> transferCanceled<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h2 id="七、表单事件"><a href="#七、表单事件" class="header-anchor">#</a> 七、表单事件</h2> <h3 id="_1、表单事件的种类"><a href="#_1、表单事件的种类" class="header-anchor">#</a> 1、表单事件的种类</h3> <h4 id="_1-1-input-事件-值发生变化触发-会连续"><a href="#_1-1-input-事件-值发生变化触发-会连续" class="header-anchor">#</a> 1.1 input 事件 (值发生变化触发,会连续)</h4> <p><code>input</code>事件当<code><input></code>、<code><select></code>、<code><textarea></code>的<strong>值发生变化时触发</strong>。对于复选框(<code><input type=checkbox></code>)或单选框(<code><input type=radio></code>),用户改变选项时,也会触发这个事件。另外,对于打开<code>contenteditable</code>属性的元素,只要值发生变化,也会触发<code>input</code>事件。</p> <p><code>input</code>事件的一个特点,就是<strong>会连续触发</strong>,比如<strong>用户每按下一次按键,就会触发一次<code>input</code>事件</strong>。</p> <p><code>input</code>事件对象<strong>继承了<code>InputEvent</code>接口</strong>。</p> <p>该事件跟<code>change</code>事件很像,不同之处在于**<code>input</code>事件在元素的值发生变化后立即发生**,<strong>而<code>change</code>在元素失去焦点时发生</strong>,而内容此时可能已经变化多次。也就是说,如果有连续变化,<strong><code>input</code>事件会触发多次,而<code>change</code>事件只在失去焦点时触发一次。</strong></p> <p>下面是<code><select></code>元素的例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">/* HTML 代码如下
- <select id="mySelect">
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- </select>
- */</span>
- <span class="token keyword">function</span> <span class="token function">inputHandler</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">)</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">var</span> mySelect <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'#mySelect'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- mySelect<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'input'</span><span class="token punctuation">,</span> inputHandler<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>上面代码中,改变下拉框选项时,会触发<code>input</code>事件,从而执行回调函数<code>inputHandler</code>。</p> <h4 id="_1-2-select-事件-选中文本时触发"><a href="#_1-2-select-事件-选中文本时触发" class="header-anchor">#</a> 1.2 select 事件 (选中文本时触发)</h4> <p><code>select</code>事件当在<code><input></code>、<code><textarea></code>里面<strong>选中文本时触发</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <input id="test" type="text" value="Select me!" /></span>
- <span class="token keyword">var</span> elem <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'test'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- elem<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'select'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "select" 事件类型</span>
- <span class="token keyword">var</span> _target <span class="token operator">=</span> e<span class="token punctuation">.</span>target<span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>_target<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 文本框的全部值</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>_target<span class="token punctuation">.</span>selectionDirection<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 选择的方向:'forward'正向、'backward'反向</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>_target<span class="token punctuation">.</span>selectionStart<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 开始选择的索引</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>_target<span class="token punctuation">.</span>selectionEnd<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 结束选择的索引</span>
- <span class="token comment">// 注意:开始和结束索引是不分选择方向的,开始的索引一直是靠前的</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>_target<span class="token punctuation">.</span>value<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>_target<span class="token punctuation">.</span>selectionStart<span class="token punctuation">,</span> _target<span class="token punctuation">.</span>selectionEnd<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">// 选中的那部分字符串</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>选中的文本可以通过<code>event.target</code>元素的<code>selectionDirection</code>、<code>selectionEnd</code>、<code>selectionStart</code>和<code>value</code>属性拿到。</p> <h4 id="_1-3-change-事件-值发生变化时触发-单次"><a href="#_1-3-change-事件-值发生变化时触发-单次" class="header-anchor">#</a> 1.3 change 事件 (值发生变化时触发,单次)</h4> <p><code>change</code>事件当<code><input></code>、<code><select></code>、<code><textarea></code>的<strong>值发生变化时触发</strong>。它与<code>input</code>事件的最大不同,就是<strong>不会连续触发,只有当全部修改完成时才会触发</strong>,另一方面<code>input</code>事件必然伴随<code>change</code>事件。具体来说,分成以下几种情况。</p> <ul><li>激活单选框(radio)或复选框(checkbox)时触发。</li> <li>用户提交时触发。比如,从下列列表(select)完成选择,在日期或文件输入框完成选择。</li> <li>当文本框或<code><textarea></code>元素的值发生改变,并且丧失焦点时触发。</li></ul> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <select size="1" onchange="changeEventHandler(event);"></span>
- <span class="token comment">// <option>chocolate</option></span>
- <span class="token comment">// <option>strawberry</option></span>
- <span class="token comment">// <option>vanilla</option></span>
- <span class="token comment">// </select></span>
- <span class="token keyword">function</span> <span class="token function">changeEventHandler</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>如果比较一下上面<code>input</code>事件的例子,你会发现对于<code><select></code>元素来说,<code>input</code>和<code>change</code>事件基本是等价的。</p> <h4 id="_1-4-invalid-事件-表单提交不满足条件触发"><a href="#_1-4-invalid-事件-表单提交不满足条件触发" class="header-anchor">#</a> 1.4 invalid 事件 (表单提交不满足条件触发)</h4> <p><strong>用户提交表单时,如果表单元素的值不满足校验条件,就会触发<code>invalid</code>事件。</strong></p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>form</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">required</span> <span class="token attr-name">oninvalid</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>console.log('invalid input')<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>submit<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>提交<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>form</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>上面代码中,输入框是必填的。如果不填,用户点击按钮提交时,就会触发输入框的<code>invalid</code>事件,导致提交被取消。</p> <h4 id="_1-5-reset-事件-重置-submit-事件-提交"><a href="#_1-5-reset-事件-重置-submit-事件-提交" class="header-anchor">#</a> 1.5 reset 事件(重置),submit 事件(提交)</h4> <p><code>reset</code>事件当<strong>表单重置(所有表单成员变回默认值)时触发。</strong></p> <p><code>submit</code>事件当<strong>表单数据向服务器提交时触发</strong>。</p> <p>注意,<strong>这两个事件发生在表单对象<code><form></code>上,而不是发生在表单的成员上</strong>,因为提交的是表单,而不是表单成员。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>form</span> <span class="token special-attr"><span class="token attr-name">onreset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'触发了重置事件'</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span> <span class="token special-attr"><span class="token attr-name">onsubmit</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'触发了提交事件'</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>input<span class="token punctuation">"</span></span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>html_form_action.php<span class="token punctuation">"</span></span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>get<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lname<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Duck<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>reset<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>重置<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>submit<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>提交<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>form</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="_2、inputevent-接口-input事件的实例"><a href="#_2、inputevent-接口-input事件的实例" class="header-anchor">#</a> 2、InputEvent 接口(input事件的实例)</h3> <p><strong><code>InputEvent</code>接口主要用来描述<code>input</code>事件的实例</strong>。该接口<strong>继承了<code>Event</code>接口</strong>,还定义了一些自己的实例属性和实例方法。</p> <p>浏览器原生提供<code>InputEvent()</code>构造函数,用来生成实例对象。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">InputEvent</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span> <span class="token comment">// 参数一,事件名称;参数二,配置对象</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>InputEvent</code>构造函数可以接受两个参数。第一个参数是字符串,表示<strong>事件名称</strong>,该参数是必需的。第二个参数是一个<strong>配置对象</strong>,用来设置事件实例的属性,该参数是可选的。配置对象的字段除了<code>Event</code>构造函数的配置属性,还可以设置下面的字段,这些字段都是可选的。</p> <ul><li><code>inputType</code>:字符串,表示<strong>发生变更的类型</strong>(详见下文)。</li> <li><code>data</code>:字符串,表示<strong>插入的字符串</strong>。如果没有插入的字符串(比如删除操作),则返回<code>null</code>或空字符串。</li> <li><code>dataTransfer</code>:返回一个 <strong>DataTransfer 对象实例,该属性通常只在输入框接受富文本输入时有效</strong>。</li></ul> <p><code>InputEvent</code>的实例属性主要就是上面三个属性,这三个实例属性都是<strong>只读的</strong>。</p> <h4 id="_1-inputevent-data-变动的那部分内容"><a href="#_1-inputevent-data-变动的那部分内容" class="header-anchor">#</a> (1)InputEvent.data 变动的那部分内容</h4> <p><code>InputEvent.data</code>属性返回一个字符串,表示<strong>变动的内容</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <input type="text" id="myInput"></span>
- <span class="token keyword">var</span> input <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'myInput'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- input<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'input'</span><span class="token punctuation">,</span> myFunction<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">myFunction</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>上面代码中,如果手动在输入框里面输入<code>abc</code>,控制台会先输出<code>a</code>,再在下一行输出<code>b</code>,再在下一行输出<code>c</code>。然后选中<code>abc</code>,一次性将它们删除,控制台会输出<code>null</code>或一个空字符串。</p> <h4 id="_2-inputevent-inputtype-变更类型"><a href="#_2-inputevent-inputtype-变更类型" class="header-anchor">#</a> (2)InputEvent.inputType 变更类型</h4> <p><code>InputEvent.inputType</code>属性返回一个字符串,表示字符串<strong>发生变更的类型</strong>。</p> <p>对于常见情况,Chrome 浏览器的返回值如下。完整列表可以参考<a href="https://w3c.github.io/input-events/index.html#dom-inputevent-inputtype" target="_blank" rel="noopener noreferrer">文档<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>。</p> <ul><li>手动插入文本:<code>insertText</code></li> <li>粘贴插入文本:<code>insertFromPaste</code></li> <li>向后删除:<code>deleteContentBackward</code></li> <li>向前删除:<code>deleteContentForward</code></li></ul> <h4 id="_3-inputevent-datatransfer"><a href="#_3-inputevent-datatransfer" class="header-anchor">#</a> (3)InputEvent.dataTransfer</h4> <p><code>InputEvent.dataTransfer</code>属性<strong>返回一个 DataTransfer 实例。该属性只在文本框接受粘贴内容(insertFromPaste)或拖拽内容(<code>insertFromDrop</code>)时才有效</strong>。</p> <h2 id="八、触摸事件"><a href="#八、触摸事件" class="header-anchor">#</a> 八、触摸事件</h2> <h3 id="_1、触摸操作概述"><a href="#_1、触摸操作概述" class="header-anchor">#</a> 1、触摸操作概述</h3> <p>浏览器的触摸 API 由三个部分组成。</p> <ul><li>Touch:一个触摸点的实例</li> <li>TouchList:多个触摸点集合的实例</li> <li>TouchEvent:触摸引发的事件实例</li></ul> <p><code>Touch</code>接口的实例对象用来表示触摸点(一根手指或者一根触摸笔),包括<strong>位置、大小、形状、压力、目标元素等属性</strong>。有时,触摸动作由多个触摸点(多根手指)组成,多个触摸点的集合由<code>TouchList</code>接口的实例对象表示。<code>TouchEvent</code>接口的实例对象代表由触摸引发的事件,只有触摸屏才会引发这一类事件。</p> <p>很多时候,<strong>触摸事件和鼠标事件同时触发</strong>,即使这个时候并没有用到鼠标。这是为了让那些只定义鼠标事件、没有定义触摸事件的代码,在触摸屏的情况下仍然能用。如果想避免这种情况,<strong>可以用<code>event.preventDefault</code>方法阻止发出鼠标事件</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>TouchEvent <span class="token punctuation">{</span><span class="token literal-property property">isTrusted</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">touches</span><span class="token operator">:</span> TouchList<span class="token punctuation">,</span> <span class="token literal-property property">targetTouches</span><span class="token operator">:</span> TouchList<span class="token punctuation">,</span> <span class="token literal-property property">changedTouches</span><span class="token operator">:</span> TouchList<span class="token punctuation">,</span> <span class="token literal-property property">altKey</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> …<span class="token punctuation">}</span> <span class="token comment">// TouchEvent接口 ,继承Event接口属性和方法</span>
- <span class="token literal-property property">altKey</span><span class="token operator">:</span> <span class="token boolean">false</span>
- <span class="token literal-property property">bubbles</span><span class="token operator">:</span> <span class="token boolean">true</span>
- <span class="token literal-property property">cancelBubble</span><span class="token operator">:</span> <span class="token boolean">false</span>
- <span class="token literal-property property">cancelable</span><span class="token operator">:</span> <span class="token boolean">false</span>
- <span class="token literal-property property">changedTouches</span><span class="token operator">:</span> TouchList <span class="token comment">// TouchList 接口 (所有触摸点集合)</span>
- <span class="token number">0</span><span class="token operator">:</span> Touch <span class="token comment">// Touch 接口 (单个触摸点)</span>
- <span class="token literal-property property">clientX</span><span class="token operator">:</span> <span class="token number">232</span>
- <span class="token literal-property property">clientY</span><span class="token operator">:</span> <span class="token number">96</span>
- <span class="token literal-property property">force</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token comment">// 触摸压力</span>
- <span class="token literal-property property">identifier</span><span class="token operator">:</span> <span class="token number">0</span> <span class="token comment">// 唯一ID</span>
- <span class="token literal-property property">pageX</span><span class="token operator">:</span> <span class="token number">232</span>
- <span class="token literal-property property">pageY</span><span class="token operator">:</span> <span class="token number">96</span>
- <span class="token literal-property property">radiusX</span><span class="token operator">:</span> <span class="token number">11.5</span>
- <span class="token literal-property property">radiusY</span><span class="token operator">:</span> <span class="token number">11.5</span>
- <span class="token literal-property property">region</span><span class="token operator">:</span> <span class="token keyword">null</span>
- <span class="token literal-property property">rotationAngle</span><span class="token operator">:</span> <span class="token number">0</span>
- <span class="token literal-property property">screenX</span><span class="token operator">:</span> <span class="token number">476</span>
- <span class="token literal-property property">screenY</span><span class="token operator">:</span> <span class="token number">266</span>
- <span class="token literal-property property">target</span><span class="token operator">:</span> html <span class="token comment">// 触摸目标元素</span>
- <span class="token literal-property property">__proto__</span><span class="token operator">:</span> Touch
- <span class="token literal-property property">length</span><span class="token operator">:</span> <span class="token number">1</span>
- <span class="token literal-property property">__proto__</span><span class="token operator">:</span> TouchList
- <span class="token literal-property property">composed</span><span class="token operator">:</span> <span class="token boolean">true</span>
- <span class="token literal-property property">ctrlKey</span><span class="token operator">:</span> <span class="token boolean">false</span>
- <span class="token literal-property property">currentTarget</span><span class="token operator">:</span> <span class="token keyword">null</span>
- <span class="token literal-property property">defaultPrevented</span><span class="token operator">:</span> <span class="token boolean">false</span>
- <span class="token literal-property property">detail</span><span class="token operator">:</span> <span class="token number">0</span>
- <span class="token literal-property property">eventPhase</span><span class="token operator">:</span> <span class="token number">0</span>
- <span class="token literal-property property">isTrusted</span><span class="token operator">:</span> <span class="token boolean">true</span>
- <span class="token literal-property property">metaKey</span><span class="token operator">:</span> <span class="token boolean">false</span>
- <span class="token literal-property property">path</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">[</span>html<span class="token punctuation">,</span> document<span class="token punctuation">,</span> Window<span class="token punctuation">]</span>
- <span class="token literal-property property">returnValue</span><span class="token operator">:</span> <span class="token boolean">true</span>
- <span class="token literal-property property">shiftKey</span><span class="token operator">:</span> <span class="token boolean">false</span>
- <span class="token literal-property property">sourceCapabilities</span><span class="token operator">:</span> InputDeviceCapabilities <span class="token punctuation">{</span><span class="token literal-property property">firesTouchEvents</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span>
- <span class="token literal-property property">srcElement</span><span class="token operator">:</span> html
- <span class="token literal-property property">target</span><span class="token operator">:</span> html
- <span class="token literal-property property">targetTouches</span><span class="token operator">:</span> TouchList <span class="token punctuation">{</span><span class="token number">0</span><span class="token operator">:</span> Touch<span class="token punctuation">,</span> <span class="token literal-property property">length</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span> <span class="token comment">// TouchList 接口 (所有触摸点集合)</span>
- <span class="token literal-property property">timeStamp</span><span class="token operator">:</span> <span class="token number">994.1749999998137</span>
- <span class="token literal-property property">touches</span><span class="token operator">:</span> TouchList <span class="token punctuation">{</span><span class="token number">0</span><span class="token operator">:</span> Touch<span class="token punctuation">,</span> <span class="token literal-property property">length</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span> <span class="token comment">// TouchList 接口 (所有触摸点集合)</span>
- <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"touchmove"</span> <span class="token comment">// 当前触摸事件类型</span>
- <span class="token literal-property property">view</span><span class="token operator">:</span> Window <span class="token punctuation">{</span><span class="token literal-property property">postMessage</span><span class="token operator">:</span> ƒ<span class="token punctuation">,</span> <span class="token literal-property property">blur</span><span class="token operator">:</span> ƒ<span class="token punctuation">,</span> <span class="token literal-property property">focus</span><span class="token operator">:</span> ƒ<span class="token punctuation">,</span> <span class="token literal-property property">close</span><span class="token operator">:</span> ƒ<span class="token punctuation">,</span> <span class="token literal-property property">parent</span><span class="token operator">:</span> Window<span class="token punctuation">,</span> …<span class="token punctuation">}</span>
- <span class="token literal-property property">which</span><span class="token operator">:</span> <span class="token number">0</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br></div></div><h3 id="_2、touch-接口"><a href="#_2、touch-接口" class="header-anchor">#</a> 2、Touch 接口</h3> <h4 id="_2-1-touch-接口概述-单个触摸点"><a href="#_2-1-touch-接口概述-单个触摸点" class="header-anchor">#</a> 2.1 Touch 接口概述 (单个触摸点)</h4> <p>Touch 接口<strong>代表单个触摸点</strong>。触摸点可能是一根手指,也可能是一根触摸笔。</p> <p>浏览器原生提供<code>Touch</code>构造函数,用来生成<code>Touch</code>实例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> touch <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Touch</span><span class="token punctuation">(</span>touchOptions<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>Touch</code>构造函数接受一个<strong>配置对象作为参数</strong>,它有以下属性。</p> <ul><li><code>identifier</code>:必需,类型为整数,表示触摸点的唯一 ID。</li> <li><code>target</code>:必需,类型为元素节点,表示触摸点开始时所在的网页元素。</li> <li><code>clientX</code>:可选,类型为数值,表示触摸点相对于浏览器窗口左上角的水平距离,默认为0。</li> <li><code>clientY</code>:可选,类型为数值,表示触摸点相对于浏览器窗口左上角的垂直距离,默认为0。</li> <li><code>screenX</code>:可选,类型为数值,表示触摸点相对于屏幕左上角的水平距离,默认为0。</li> <li><code>screenY</code>:可选,类型为数值,表示触摸点相对于屏幕左上角的垂直距离,默认为0。</li> <li><code>pageX</code>:可选,类型为数值,表示触摸点相对于网页左上角的水平位置(即包括页面的滚动距离),默认为0。</li> <li><code>pageY</code>:可选,类型为数值,表示触摸点相对于网页左上角的垂直位置(即包括页面的滚动距离),默认为0。</li> <li><code>radiusX</code>:可选,类型为数值,表示触摸点周围受到影响的椭圆范围的 X 轴半径,默认为0。</li> <li><code>radiusY</code>:可选:类型为数值,表示触摸点周围受到影响的椭圆范围的 Y 轴半径,默认为0。</li> <li><code>rotationAngle</code>:可选,类型为数值,表示触摸区域的椭圆的旋转角度,单位为度数,在0到90度之间,默认值为0。</li> <li><code>force</code>:可选,类型为数值,范围在<code>0</code>到<code>1</code>之间,表示触摸压力。<code>0</code>代表没有压力,<code>1</code>代表硬件所能识别的最大压力,默认为<code>0</code>。</li></ul> <h4 id="_2-2-touch-接口的实例属性"><a href="#_2-2-touch-接口的实例属性" class="header-anchor">#</a> 2.2 Touch 接口的实例属性</h4> <h5 id="_1-touch-identifier-触摸点的id"><a href="#_1-touch-identifier-触摸点的id" class="header-anchor">#</a> (1)Touch.identifier 触摸点的ID</h5> <p><code>Touch.identifier</code>属性返回一个整数,表示触摸点的唯一 ID。这个值在整个触摸过程保持不变,直到触摸事件结束。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>someElement<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchmove'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> e<span class="token punctuation">.</span>changedTouches<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>changedTouches<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>identifier<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h5 id="_2-touch-screenx-touch-screeny-touch-clientx-touch-clienty-pagex-pagey-相对屏幕、浏览器、文档的坐标"><a href="#_2-touch-screenx-touch-screeny-touch-clientx-touch-clienty-pagex-pagey-相对屏幕、浏览器、文档的坐标" class="header-anchor">#</a> (2)Touch.screenX,Touch.screenY,Touch.clientX,Touch.clientY,pageX,pageY (相对屏幕、浏览器、文档的坐标)</h5> <p><code>Touch.screenX</code>属性和<code>Touch.screenY</code>属性,分别表示触摸点相对于屏幕左上角的横坐标和纵坐标,与页面是否滚动无关。</p> <p><code>Touch.clientX</code>属性和<code>Touch.clientY</code>属性,分别表示触摸点相对于浏览器视口左上角的横坐标和纵坐标,与页面是否滚动无关。</p> <p><code>Touch.pageX</code>属性和<code>Touch.pageY</code>属性,分别表示触摸点相对于当前页面左上角的横坐标和纵坐标,包含了页面滚动带来的位移。</p> <h5 id="_3-touch-radiusx-touch-radiusy-touch-rotationangle-触摸椭圆区域半径、角度"><a href="#_3-touch-radiusx-touch-radiusy-touch-rotationangle-触摸椭圆区域半径、角度" class="header-anchor">#</a> (3)Touch.radiusX,Touch.radiusY,Touch.rotationAngle (触摸椭圆区域半径、角度)</h5> <p><code>Touch.radiusX</code>属性和<code>Touch.radiusY</code>属性,分别返回<strong>触摸点周围受到影响的椭圆范围的 X 轴半径和 Y 轴半径,单位为像素。乘以 2 就可以得到触摸范围的宽度和高度</strong>。</p> <p><code>Touch.rotationAngle</code>属性表示触摸区域的椭圆的旋转角度,单位为度数,在<code>0</code>到<code>90</code>度之间。</p> <p>上面这三个属性共同定义了<strong>用户与屏幕接触的区域</strong>,对于描述手指这一类非精确的触摸,很有帮助。指尖接触屏幕,触摸范围会形成一个椭圆,这三个属性就用来描述这个椭圆区域。</p> <p>下面是一个示例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchstart'</span><span class="token punctuation">,</span> rotate<span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchmove'</span><span class="token punctuation">,</span> rotate<span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchend'</span><span class="token punctuation">,</span> rotate<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">rotate</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> touch <span class="token operator">=</span> e<span class="token punctuation">.</span>changedTouches<span class="token punctuation">.</span><span class="token function">item</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- src<span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> touch<span class="token punctuation">.</span>radiusX <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token string">'px'</span><span class="token punctuation">;</span>
- src<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> touch<span class="token punctuation">.</span>radiusY <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token string">'px'</span><span class="token punctuation">;</span>
- src<span class="token punctuation">.</span>style<span class="token punctuation">.</span>transform <span class="token operator">=</span> <span class="token string">'rotate('</span> <span class="token operator">+</span> touch<span class="token punctuation">.</span>rotationAngle <span class="token operator">+</span> <span class="token string">'deg)'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h5 id="_4-touch-force-触摸压力"><a href="#_4-touch-force-触摸压力" class="header-anchor">#</a> (4)Touch.force 触摸压力</h5> <p><code>Touch.force</code>属性返回一个<code>0</code>到<code>1</code>之间的数值,表示触摸压力。<code>0</code>代表没有压力,<code>1</code>代表硬件所能识别的最大压力。</p> <h5 id="_5-touch-target-开始触摸时的元素"><a href="#_5-touch-target-开始触摸时的元素" class="header-anchor">#</a> (5)Touch.target 开始触摸时的元素</h5> <p><code>Touch.target</code>属性返回一个元素节点,代表触摸发生时所在的那个元素节点。即使触摸点已经离开了这个节点,该属性依然不变。</p> <h3 id="_3、touchlist-接口"><a href="#_3、touchlist-接口" class="header-anchor">#</a> 3、TouchList 接口</h3> <p><code>TouchList</code>接口<strong>表示一组触摸点的集合</strong>。它的实例是一个<strong>类似数组的对象</strong>,成员是<code>Touch</code>的实例对象,表示所有触摸点。用户用三根手指触摸,产生的<code>TouchList</code>实例就会包含三个成员,每根手指的触摸点对应一个<code>Touch</code>实例对象。</p> <p>它的实例主要通过触摸事件的<code>TouchEvent.touches</code>、<code>TouchEvent.changedTouches</code>、<code>TouchEvent.targetTouches</code>这几个属性获取。</p> <p>它的实例属性和实例方法只有两个。</p> <ul><li><code>TouchList.length</code>:数值,表示成员数量(即触摸点的数量)。</li> <li><code>TouchList.item()</code>:返回指定位置的成员,它的参数是该成员的位置编号(从零开始)。</li></ul> <h3 id="_4、touchevent-接口"><a href="#_4、touchevent-接口" class="header-anchor">#</a> 4、TouchEvent 接口</h3> <h4 id="_4-1-概述"><a href="#_4-1-概述" class="header-anchor">#</a> 4.1 概述</h4> <p>TouchEvent 接口<strong>继承了 Event 接口</strong>,表示由<strong>触摸引发的事件实例</strong>,通常来自触摸屏或轨迹板。除了被继承的属性以外,它还有一些自己的属性。</p> <p>浏览器原生提供<code>TouchEvent()</code>构造函数,用来生成触摸事件的实例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">TouchEvent</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>TouchEvent()</code>构造函数可以接受两个参数,第一个参数是字符串,表示事件类型;第二个参数是事件的配置对象,该参数是可选的,对象的所有属性也是可选的。除了<code>Event</code>接口的配置属性,该接口还有一些自己的配置属性。</p> <ul><li><code>touches</code>:<code>TouchList</code>实例,代表所有的当前处于活跃状态的触摸点,默认值是一个空数组<code>[]</code>。</li> <li><code>targetTouches</code>:<code>TouchList</code>实例,代表所有处在触摸的目标元素节点内部、且仍然处于活动状态的触摸点,默认值是一个空数组<code>[]</code>。</li> <li><code>changedTouches</code>:<code>TouchList</code>实例,代表本次触摸事件的相关触摸点,默认值是一个空数组<code>[]</code>。</li> <li><code>ctrlKey</code>:布尔值,表示 Ctrl 键是否同时按下,默认值为<code>false</code>。</li> <li><code>shiftKey</code>:布尔值,表示 Shift 键是否同时按下,默认值为<code>false</code>。</li> <li><code>altKey</code>:布尔值,表示 Alt 键是否同时按下,默认值为<code>false</code>。</li> <li><code>metaKey</code>:布尔值,表示 Meta 键(或 Windows 键)是否同时按下,默认值为<code>false</code>。</li></ul> <h4 id="_4-2-实例属性"><a href="#_4-2-实例属性" class="header-anchor">#</a> 4.2 实例属性</h4> <p>TouchEvent 接口的实例具有<code>Event</code>实例的所有属性和方法,此外还有一些它自己的实例属性,这些属性全部都是只读。</p> <h5 id="_1-touchevent-altkey-touchevent-ctrlkey-touchevent-shiftkey-touchevent-metakey-是否同时按某些功能键"><a href="#_1-touchevent-altkey-touchevent-ctrlkey-touchevent-shiftkey-touchevent-metakey-是否同时按某些功能键" class="header-anchor">#</a> (1)TouchEvent.altKey,TouchEvent.ctrlKey,TouchEvent.shiftKey,TouchEvent.metaKey (是否同时按某些功能键)</h5> <ul><li><code>TouchEvent.altKey</code>:布尔值,表示触摸时是否按下了 Alt 键。</li> <li><code>TouchEvent.ctrlKey</code>:布尔值,表示触摸时是否按下了 Ctrl 键。</li> <li><code>TouchEvent.shiftKey</code>:布尔值:表示触摸时是否按下了 Shift 键。</li> <li><code>TouchEvent.metaKey</code>:布尔值,表示触摸时是否按下了 Meta 键(或 Windows 键)。</li></ul> <p>下面是一个示例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>someElement<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchstart'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'altKey = '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>altKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'ctrlKey = '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>ctrlKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'metaKey = '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>metaKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'shiftKey = '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>shiftKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h5 id="_2-touchevent-changedtouches-触摸点集合-不同触摸事件-含义不同"><a href="#_2-touchevent-changedtouches-触摸点集合-不同触摸事件-含义不同" class="header-anchor">#</a> (2)TouchEvent.changedTouches (触摸点集合,不同触摸事件,含义不同)</h5> <p><code>TouchEvent.changedTouches</code>属性返回一个<code>TouchList</code>实例,成员是一组<code>Touch</code>实例对象,表示本次触摸事件的相关触摸点。</p> <p>对于<strong>不同的事件,该属性的含义有所不同。</strong></p> <ul><li><code>touchstart</code>事件:被激活的触摸点</li> <li><code>touchmove</code>事件:发生变化的触摸点</li> <li><code>touchend</code>事件:消失的触摸点(即不再被触碰的点)</li></ul> <p>下面是一个示例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>someElement<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchmove'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> e<span class="token punctuation">.</span>changedTouches<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>changedTouches<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>identifier<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h5 id="_3-touchevent-touches-仍然活动的触摸点集合"><a href="#_3-touchevent-touches-仍然活动的触摸点集合" class="header-anchor">#</a> (3)TouchEvent.touches (仍然活动的触摸点集合)</h5> <p><code>TouchEvent.touches</code>属性返回一个<code>TouchList</code>实例,成员是所有<strong>仍然处于活动状态(即触摸中)的触摸点</strong>。一般来说,一个手指就是一个触摸点。</p> <p>下面是一个示例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>someElement<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchstart'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">switch</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>touches<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 一根手指触摸</span>
- <span class="token keyword">case</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token function">handle_one_touch</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
- <span class="token comment">// 两根手指触摸</span>
- <span class="token keyword">case</span> <span class="token number">2</span><span class="token operator">:</span> <span class="token function">handle_two_touches</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
- <span class="token comment">// 三根手指触摸</span>
- <span class="token keyword">case</span> <span class="token number">3</span><span class="token operator">:</span> <span class="token function">handle_three_touches</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
- <span class="token comment">// 其他情况</span>
- <span class="token keyword">default</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Not supported'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h5 id="_4-touchevent-targettouches-目标元素内活动的触摸点集合"><a href="#_4-touchevent-targettouches-目标元素内活动的触摸点集合" class="header-anchor">#</a> (4)TouchEvent.targetTouches (目标元素内活动的触摸点集合)</h5> <p><code>TouchEvent.targetTouches</code>属性返回一个<code>TouchList</code>实例,成员是<strong>触摸事件的目标元素节点内部、所有仍然处于活动状态(即触摸中)的触摸点</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">touches_in_target</span><span class="token punctuation">(</span><span class="token parameter">ev</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">return</span> <span class="token punctuation">(</span>ev<span class="token punctuation">.</span>touches<span class="token punctuation">.</span>length <span class="token operator">===</span> ev<span class="token punctuation">.</span>targetTouches<span class="token punctuation">.</span>length <span class="token operator">?</span> <span class="token boolean">true</span> <span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>上面代码用来判断,是否所有触摸点都在目标元素内。</p> <h3 id="_5、触摸事件的种类"><a href="#_5、触摸事件的种类" class="header-anchor">#</a> 5、触摸事件的种类</h3> <p>触摸引发的事件,有以下几种。可以通过<code>TouchEvent.type</code>属性,查看到底发生的是哪一种事件。</p> <ul><li><code>touchstart</code>:用户开始触摸时触发,它的<code>target</code>属性返回发生触摸的元素节点。<strong>【开始触摸】</strong></li> <li><code>touchend</code>:用户不再接触触摸屏时(或者移出屏幕边缘时)触发,它的<code>target</code>属性与<code>touchstart</code>事件一致的,就是开始触摸时所在的元素节点。它的<code>changedTouches</code>属性返回一个<code>TouchList</code>实例,包含所有不再触摸的触摸点(即<code>Touch</code>实例对象)。<strong>【触摸结束】</strong></li> <li><code>touchmove</code>:用户移动触摸点时触发,它的<code>target</code>属性与<code>touchstart</code>事件一致。如果触摸的半径、角度、力度发生变化,也会触发该事件。<strong>【触摸移动中】</strong></li> <li><code>touchcancel</code>:触摸点取消时触发,比如在触摸区域跳出一个模态窗口(modal window)、触摸点离开了文档区域(进入浏览器菜单栏)、用户的触摸点太多,超过了支持的上限(自动取消早先的触摸点)。<strong>【触摸点被取消】</strong></li></ul> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> el <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token string">'canvas'</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
- el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchstart'</span><span class="token punctuation">,</span> handleStart<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'touchmove'</span><span class="token punctuation">,</span> handleMove<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">handleStart</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- evt<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> touches <span class="token operator">=</span> evt<span class="token punctuation">.</span>changedTouches<span class="token punctuation">;</span>
- <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> touches<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>touches<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>pageX<span class="token punctuation">,</span> touches<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>pageY<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">function</span> <span class="token function">handleMove</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- evt<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> touches <span class="token operator">=</span> evt<span class="token punctuation">.</span>changedTouches<span class="token punctuation">;</span>
- <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> touches<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> touch <span class="token operator">=</span> touches<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>touch<span class="token punctuation">.</span>pageX<span class="token punctuation">,</span> touch<span class="token punctuation">.</span>pageY<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div><h2 id="九、拖拉事件"><a href="#九、拖拉事件" class="header-anchor">#</a> 九、拖拉事件</h2> <h3 id="_1、拖拉事件的种类"><a href="#_1、拖拉事件的种类" class="header-anchor">#</a> 1、拖拉事件的种类</h3> <p>拖拉(drag)指的是,<strong>用户在某个对象上按下鼠标键不放,拖动它到另一个位置,然后释放鼠标键,将该对象放在那里</strong>。</p> <p>拖拉的对象有好几种,包括<strong>元素节点、图片、链接、选中的文字等等</strong>。在网页中,除了元素节点默认不可以拖拉,其他(图片、链接、选中的文字)都是可以直接拖拉的。为了让元素节点可拖拉,可以将该节点的<code>draggable</code>属性设为<code>true</code>。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">draggable</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
- 此区域可拖拉
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p><code>draggable</code>属性<strong>可用于任何元素节点</strong>,但是图片(<code><img></code>)和链接(<code><a></code>)不加这个属性,就可以拖拉。对于它们,用到这个属性的时候,往往是将其设为<code>false</code>,防止拖拉这两种元素。</p> <p><strong>注意</strong>,一旦某个元素节点的<code>draggable</code>属性设为<code>true</code>,<strong>就无法再用鼠标选中该节点内部的文字或子节点</strong>了。</p> <p>当元素节点或选中的文本被拖拉时,就<strong>会持续触发拖拉事件</strong>,包括以下一些事件。</p> <p><strong>拖拉的节点上触发:</strong></p> <ul><li><code>drag</code>:<strong>拖拉过程中</strong>,在被拖拉的节点上<strong>持续触发</strong>(相隔几百毫秒)。</li> <li><code>dragstart</code>:用户<strong>开始拖拉时</strong>,在被拖拉的节点上触发,该事件的<code>target</code>属性是被拖拉的节点。通常应该在这个事件的监听函数中,指定拖拉的数据。</li> <li><code>dragend</code>:<strong>拖拉结束时</strong>(释放鼠标键或按下 ESC 键)在被拖拉的节点上触发,该事件的<code>target</code>属性是被拖拉的节点。它与<code>dragstart</code>事件,在同一个节点上触发。不管拖拉是否跨窗口,或者中途被取消,<code>dragend</code>事件总是会触发的。</li></ul> <p><strong>拖拉到别的节点上触发:</strong></p> <ul><li><p><code>dragenter</code>:<strong>拖拉进入当前节点</strong>时,<strong>在当前节点上触发一次</strong>,该事件的<code>target</code>属性是当前节点。通常应该在这个事件的监听函数中,<strong>指定是否允许在当前节点放下(drop)拖拉的数据</strong>。如果当前节点没有该事件的监听函数,或者监听函数不执行任何操作,就意味着不允许在当前节点放下数据。在视觉上显示拖拉进入当前节点,也是在这个事件的监听函数中设置。</p></li> <li><p><code>dragover</code>:<strong>拖拉到当前节点上方时</strong>,在当前节点上<strong>持续触发</strong>(相隔几百毫秒),该事件的<code>target</code>属性是当前节点。该事件与<code>dragenter</code>事件的区别是,<code>dragenter</code>事件在进入该节点时触发,然后只要没有离开这个节点,<code>dragover</code>事件会持续触发。</p></li> <li><p><code>dragleave</code>:<strong>拖拉操作离开当前节点范围时</strong>,在当前节点上触发,该事件的<code>target</code>属性是当前节点。如果要在视觉上显示拖拉离开操作当前节点,就在这个事件的监听函数中设置。</p></li> <li><p><code>drop</code>:被拖拉的节点或选中的文本,<strong>释放到目标节点时,在目标节点上触发</strong>。注意,如果当前节点不允许<code>drop</code>,即使在该节点上方松开鼠标键,也不会触发该事件。如果用户按下 ESC 键,取消这个操作,也不会触发该事件。该事件的监听函数负责取出拖拉数据,并进行相关处理。</p></li></ul> <p>下面的例子展示,如何动态改变被拖动节点的背景色。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragstart'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">this</span><span class="token punctuation">.</span>style<span class="token punctuation">.</span>backgroundColor <span class="token operator">=</span> <span class="token string">'red'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragend'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">this</span><span class="token punctuation">.</span>style<span class="token punctuation">.</span>backgroundColor <span class="token operator">=</span> <span class="token string">'green'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>上面代码中,<code>div</code>节点被拖动时,背景色会变为红色,拖动结束,又变回绿色。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>div1<span class="token punctuation">"</span></span> <span class="token attr-name">draggable</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
- div1,此区域可拖拉
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>div2<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
- div2
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
- <span class="token keyword">var</span> div1 <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.div1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> div2 <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.div2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div1<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragstart'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'开始拖拉'</span><span class="token punctuation">)</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div1<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'drag'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'拖拉中'</span><span class="token punctuation">)</span> <span class="token comment">// 持续触发</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div1<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragend'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'结束拖拉'</span><span class="token punctuation">)</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div2<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragenter'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'拖到了div2'</span><span class="token punctuation">)</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span>
- div2<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragover'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- <span class="token comment">//console.log('正在div2上方') // 持续触发</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span>
- div2<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragleave'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'离开div2'</span><span class="token punctuation">)</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span>
- div2<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'drop'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'在div2上释放'</span><span class="token punctuation">)</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span>
- </span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br></div></div><p>下面是一个例子,展示如何实现将一个节点从当前父节点,拖拉到另一个父节点中。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">/* HTML 代码如下
- <div class="dropzone">
- <div id="draggable" draggable="true">
- 该节点可拖拉
- </div>
- </div>
- <div class="dropzone"></div>
- <div class="dropzone"></div>
- <div class="dropzone"></div>
- */</span>
- <span class="token comment">// 被拖拉节点</span>
- <span class="token keyword">var</span> dragged<span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragstart'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 保存被拖拉节点</span>
- dragged <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">;</span>
- <span class="token comment">// 被拖拉节点的背景色变透明</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>opacity <span class="token operator">=</span> <span class="token number">0.5</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragend'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 被拖拉节点的背景色恢复正常</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>opacity <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragover'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 防止拖拉效果被重置,允许被拖拉的节点放入目标节点</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragenter'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 目标节点的背景色变紫色</span>
- <span class="token comment">// 由于该事件会冒泡,所以要过滤节点</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>className <span class="token operator">===</span> <span class="token string">'dropzone'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>background <span class="token operator">=</span> <span class="token string">'purple'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragleave'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span> <span class="token parameter">event</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 目标节点的背景色恢复原样</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>className <span class="token operator">===</span> <span class="token string">'dropzone'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>background <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'drop'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span> <span class="token parameter">event</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 防止事件默认行为(比如某些元素节点上可以打开链接),</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>className <span class="token operator">===</span> <span class="token string">'dropzone'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// 恢复目标节点背景色</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>background <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- <span class="token comment">// 将被拖拉节点插入目标节点</span>
- dragged<span class="token punctuation">.</span>parentNode<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>dragged<span class="token punctuation">)</span><span class="token punctuation">;</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span> dragged <span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br></div></div><p>关于拖拉事件,有以下几个注意点。</p> <ul><li>拖拉过程只触发以上这些拖拉事件,尽管鼠标在移动,但是<strong>鼠标事件不会触发</strong>。</li> <li>将文件从操作系统拖拉进浏览器,不会触发<code>dragstart</code>和<code>dragend</code>事件。</li> <li><code>dragenter</code>和<code>dragover</code>事件的监听函数,用来取出拖拉的数据(即允许放下被拖拉的元素)。由于网页的大部分区域不适合作为放下拖拉元素的目标节点,所以这两个事件的默认设置为当前节点不允许接受被拖拉的元素。<strong>如果想要在目标节点上放下的数据,首先必须阻止这两个事件的默认行为</strong>。</li></ul> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">ondragover</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>return false<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
- <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">ondragover</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>event.preventDefault()<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>上面代码中,如果不取消拖拉事件或者阻止默认行为,就不能在<code>div</code>节点上放下被拖拉的节点。</p> <h3 id="_2、dragevent-接口"><a href="#_2、dragevent-接口" class="header-anchor">#</a> 2、DragEvent 接口</h3> <p><strong>拖拉事件都继承了<code>DragEvent</code>接口,这个接口又继承了<code>MouseEvent</code>接口和<code>Event</code>接口。</strong></p> <p>浏览器原生提供一个<code>DragEvent()</code>构造函数,用来生成拖拉事件的实例对象。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">DragEvent</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>DragEvent()</code>构造函数接受两个参数,第一个参数是<strong>字符串,表示事件的类型</strong>,该参数必须;第二个参数是事件的<strong>配置对象</strong>,用来设置事件的属性,该参数可选。配置对象除了接受<code>MouseEvent</code>接口和<code>Event</code>接口的配置属性,还可以<strong>设置<code>dataTransfer</code>属性要么是<code>null</code>,要么是一个<code>DataTransfer</code>接口的实例。</strong></p> <p><code>DataTransfer</code>的实例对象用来读写拖拉事件中传输的数据,详见下文《DataTransfer 接口》的部分。</p> <h3 id="_3、datatransfer-接口概述"><a href="#_3、datatransfer-接口概述" class="header-anchor">#</a> 3、DataTransfer 接口概述</h3> <p><strong>所有拖拉事件的实例都有一个<code>DragEvent.dataTransfer</code>属性,用来读写需要传递的数据</strong>。这个属性的值是一个<code>DataTransfer</code>接口的实例。</p> <p>浏览器原生提供一个<code>DataTransfer()</code>构造函数,用来生成<code>DataTransfer</code>实例对象。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> dataTrans <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataTransfer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>DataTransfer()</code>构造函数<strong>不接受参数</strong>。</p> <p>拖拉的数据分成两方面:<strong>数据的种类(又称格式)和数据的值</strong>。数据的种类是一个 MIME 字符串(比如<code>text/plain</code>、<code>image/jpeg</code>),数据的值是一个字符串。一般来说,如果拖拉一段文本,则数据默认就是那段文本;如果拖拉一个链接,则数据默认就是链接的 URL。</p> <p>拖拉事件开始时,开发者可以提供数据类型和数据值。拖拉过程中,开发者通过<code>dragenter</code>和<code>dragover</code>事件的监听函数,检查数据类型,以确定是否允许放下(drop)被拖拉的对象。比如,在只允许放下链接的区域,检查拖拉的数据类型是否为<code>text/uri-list</code>。</p> <p><strong>发生<code>drop</code>事件时,监听函数取出拖拉的数据,对其进行处理。</strong></p> <h3 id="_4、datatransfer-的实例属性"><a href="#_4、datatransfer-的实例属性" class="header-anchor">#</a> 4、DataTransfer 的实例属性</h3> <h4 id="_4-1-datatransfer-dropeffect-设置接受拖拉的区域的效果"><a href="#_4-1-datatransfer-dropeffect-设置接受拖拉的区域的效果" class="header-anchor">#</a> 4.1 DataTransfer.dropEffect 设置接受拖拉的区域的效果</h4> <p><code>DataTransfer.dropEffect</code>属性<strong>用来设置放下(drop)被拖拉节点时的效果</strong>,会影响到拖拉经过相关区域时鼠标的形状。它可能取下面的值。</p> <ul><li>copy:复制被拖拉的节点</li> <li>move:移动被拖拉的节点</li> <li>link:创建指向被拖拉的节点的链接</li> <li>none:无法放下被拖拉的节点</li></ul> <p>除了上面这些值,设置其他的值都是无效的。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>target<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragover'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- e<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>dropEffect <span class="token operator">=</span> <span class="token string">'copy'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>上面代码中,被拖拉元素一旦<code>drop</code>,接受的区域会复制该节点。</p> <p><code>dropEffect</code>属性一般<strong>在<code>dragenter</code>和<code>dragover</code>事件的监听函数中设置</strong>,对于<code>dragstart</code>、<code>drag</code>、<code>dragleave</code>这三个事件,该属性不起作用。因为该属性只对接受被拖拉的节点的区域有效,对被拖拉的节点本身是无效的。进入目标区域后,拖拉行为会初始化成设定的效果。</p> <h4 id="_4-2-datatransfer-effectallowed-设置被拖拉的节点允许的效果"><a href="#_4-2-datatransfer-effectallowed-设置被拖拉的节点允许的效果" class="header-anchor">#</a> 4.2 DataTransfer.effectAllowed 设置被拖拉的节点允许的效果</h4> <p><code>DataTransfer.effectAllowed</code>属性<strong>设置本次拖拉中允许的效果</strong>。它可能取下面的值。</p> <ul><li>copy:复制被拖拉的节点</li> <li>move:移动被拖拉的节点</li> <li>link:创建指向被拖拉节点的链接</li> <li>copyLink:允许<code>copy</code>或<code>link</code></li> <li>copyMove:允许<code>copy</code>或<code>move</code></li> <li>linkMove:允许<code>link</code>或<code>move</code></li> <li>all:允许所有效果</li> <li>none:无法放下被拖拉的节点</li> <li>uninitialized:默认值,等同于<code>all</code></li></ul> <p>如果某种效果是不允许的,用户就无法在目标节点中达成这种效果。</p> <p><strong>这个属性与<code>dropEffect</code>属性是同一件事的两个方面。前者设置被拖拉的节点允许的效果,后者设置接受拖拉的区域的效果,它们往往配合使用。</strong></p> <p><strong><code>dragstart</code>事件的监听函数,可以用来设置这个属性</strong>。其他事件的监听函数里面设置这个属性是无效的。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>source<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragstart'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 被拖拉节点上设置</span>
- e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>effectAllowed <span class="token operator">=</span> <span class="token string">'move'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- target<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragover'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 接受区域节点上设置</span>
- e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>dropEffect <span class="token operator">=</span> <span class="token string">'move'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>只要<code>dropEffect</code>属性和<code>effectAllowed</code>属性之中,有一个为<code>none</code>,就无法在目标节点上完成<code>drop</code>操作。</p> <h4 id="_4-3-datatransfer-files-本地文件"><a href="#_4-3-datatransfer-files-本地文件" class="header-anchor">#</a> 4.3 DataTransfer.files 本地文件</h4> <p><code>DataTransfer.files</code>属性是<strong>一个 FileList 对象,包含一组本地文件</strong>,可以用来在拖拉操作中传送。如果本次拖拉不涉及文件,则该属性为空的 FileList 对象。</p> <h5 id="例子-接收拖拉文件"><a href="#例子-接收拖拉文件" class="header-anchor">#</a> 例子:接收拖拉文件</h5> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <div id="output" style="min-height: 200px;border: 1px solid black;"></span>
- <span class="token comment">// 文件拖拉到这里</span>
- <span class="token comment">// </div></span>
- <span class="token keyword">var</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'output'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"dragenter"</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span> <span class="token parameter">event</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
- div<span class="token punctuation">.</span>textContent <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"dragover"</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span> <span class="token parameter">event</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"drop"</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span> <span class="token parameter">event</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> files <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>files<span class="token punctuation">;</span>
- <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> files<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- div<span class="token punctuation">.</span>textContent <span class="token operator">+=</span> files<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">' '</span> <span class="token operator">+</span> files<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>size <span class="token operator">+</span> <span class="token string">'字节\n'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><p>上面代码中,通过<code>dataTransfer.files</code>属性读取被拖拉的文件的信息。如果想要<strong>读取文件内容,就要使用<code>FileReader</code>对象。</strong></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'drop'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- e<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> fileList <span class="token operator">=</span> e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>files<span class="token punctuation">;</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>fileList<span class="token punctuation">.</span>length <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> file <span class="token operator">=</span> fileList<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> reader <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- reader<span class="token punctuation">.</span><span class="token function">readAsDataURL</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 解析为url</span>
- reader<span class="token punctuation">.</span><span class="token function-variable function">onloadend</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>readyState <span class="token operator">===</span> FileReader<span class="token punctuation">.</span><span class="token constant">DONE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> content <span class="token operator">=</span> reader<span class="token punctuation">.</span>result<span class="token punctuation">;</span>
- div<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">'<img src="'</span><span class="token operator">+</span> content <span class="token operator">+</span><span class="token string">'"> File: '</span> <span class="token operator">+</span> file<span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">'\n\n'</span> <span class="token operator">+</span> content<span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- reader<span class="token punctuation">.</span><span class="token function">readAsBinaryString</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><h4 id="_4-4-datatransfer-types-数据格式"><a href="#_4-4-datatransfer-types-数据格式" class="header-anchor">#</a> 4.4 DataTransfer.types 数据格式</h4> <p><code>DataTransfer.types</code>属性<strong>是一个只读的数组</strong>,每个成员是一个字符串,里面是<strong>拖拉的数据格式</strong>(通常是 MIME 值)。比如,如果拖拉的是文字,对应的成员就是<code>text/plain</code>。</p> <p>下面是一个例子,通过检查<code>dataTransfer</code>属性的类型,决定是否允许在当前节点执行<code>drop</code>操作。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">contains</span><span class="token punctuation">(</span><span class="token parameter">list<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> list<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span><span class="token punctuation">(</span>list<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> value<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">function</span> <span class="token function">doDragOver</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> isLink <span class="token operator">=</span> <span class="token function">contains</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>types<span class="token punctuation">,</span> <span class="token string">'text/uri-list'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>isLink<span class="token punctuation">)</span> event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>上面代码中,只有当被拖拉的节点是一个链接时,才允许在当前节点放下。</p> <h4 id="_4-5-datatransfer-items"><a href="#_4-5-datatransfer-items" class="header-anchor">#</a> 4.5 DataTransfer.items</h4> <p><code>DataTransfer.items</code>属性<strong>返回一个类似数组的只读对象(DataTransferItemList 实例)</strong>,每个成员就是本次拖拉的一个对象(DataTransferItem 实例)。如果本次拖拉不包含对象,则返回一个空对象。</p> <p>DataTransferItemList 实例具有以下的属性和方法。</p> <ul><li><code>length</code>:返回成员的数量</li> <li><code>add(data, type)</code>:增加一个指定内容和类型(比如<code>text/html</code>和<code>text/plain</code>)的字符串作为成员</li> <li><code>add(file)</code>:<code>add</code>方法的另一种用法,增加一个文件作为成员</li> <li><code>remove(index)</code>:移除指定位置的成员</li> <li><code>clear()</code>:移除所有的成员</li></ul> <p>DataTransferItem 实例具有以下的属性和方法。</p> <ul><li><code>kind</code>:返回成员的种类(<code>string</code>还是<code>file</code>)。</li> <li><code>type</code>:返回成员的类型(通常是 MIME 值)。</li> <li><code>getAsFile()</code>:如果被拖拉是文件,返回该文件,否则返回<code>null</code>。</li> <li><code>getAsString(callback)</code>:如果被拖拉的是字符串,将该字符传入指定的回调函数处理。该方法是异步的,所以需要传入回调函数。</li></ul> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'drop'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>items <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>items<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>items<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>kind <span class="token operator">+</span> <span class="token string">': '</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>items<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h3 id="_5、datatransfer-的实例方法"><a href="#_5、datatransfer-的实例方法" class="header-anchor">#</a> 5、DataTransfer 的实例方法</h3> <h4 id="_5-1-datatransfer-setdata-设置拖拉事件所带有的数据"><a href="#_5-1-datatransfer-setdata-设置拖拉事件所带有的数据" class="header-anchor">#</a> 5.1 DataTransfer.setData() 设置拖拉事件所带有的数据</h4> <p><code>DataTransfer.setData()</code>方法用来<strong>设置拖拉事件所带有的数据</strong>。该方法没有返回值。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/plain'</span><span class="token punctuation">,</span> <span class="token string">'Text to drag'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>上面代码为当前的拖拉事件加入纯文本数据。</p> <p>该方法接受两个参数,都是字符串。第一个参数<strong>表示数据类型</strong>(比如<code>text/plain</code>),第二个参数是<strong>具体数据</strong>。如果指定类型的数据在<code>dataTransfer</code>属性不存在,那么这些数据将被加入,否则原有的数据将被新数据替换。</p> <p>如果是拖拉文本框或者拖拉选中的文本,会默认将对应的文本数据,添加到<code>dataTransfer</code>属性,不用手动指定。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">draggable</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
- aaa
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>上面代码中,拖拉这个<code><div></code>元素会自动带上文本数据<code>aaa</code>。</p> <p>使用<code>setData</code>方法,可以替换到原有数据。</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span>
- <span class="token attr-name">draggable</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span>
- <span class="token attr-name">ondragstart</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>event.dataTransfer.setData('text/plain', 'bbb')<span class="token punctuation">"</span></span>
- <span class="token punctuation">></span></span>
- aaa
- <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>上面代码中,拖拉数据实际上是<code>bbb</code>,而不是<code>aaa</code>。</p> <p>下面是添加其他类型的数据。由于<code>text/plain</code>是最普遍支持的格式,为了保证兼容性,建议最后总是保存一份纯文本格式的数据。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> dt <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">;</span>
- <span class="token comment">// 添加链接</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/uri-list'</span><span class="token punctuation">,</span> <span class="token string">'http://www.example.com'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/plain'</span><span class="token punctuation">,</span> <span class="token string">'http://www.example.com'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 添加 HTML 代码</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/html'</span><span class="token punctuation">,</span> <span class="token string">'Hello there, <strong>stranger</strong>'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/plain'</span><span class="token punctuation">,</span> <span class="token string">'Hello there, <strong>stranger</strong>'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 添加图像的 URL</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/uri-list'</span><span class="token punctuation">,</span> imageurl<span class="token punctuation">)</span><span class="token punctuation">;</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/plain'</span><span class="token punctuation">,</span> imageurl<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><p>可以一次提供多种格式的数据。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> dt <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">;</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'application/x-bookmark'</span><span class="token punctuation">,</span> bookmarkString<span class="token punctuation">)</span><span class="token punctuation">;</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/uri-list'</span><span class="token punctuation">,</span> <span class="token string">'http://www.example.com'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- dt<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/plain'</span><span class="token punctuation">,</span> <span class="token string">'http://www.example.com'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>上面代码中,通过在同一个事件上面,存放三种类型的数据,使得拖拉事件可以在不同的对象上面,<code>drop</code>不同的值。注意,第一种格式是一个自定义格式,浏览器默认无法读取,这意味着,只有某个部署了特定代码的节点,才可能<code>drop</code>(读取到)这个数据。</p> <h4 id="_5-2-datatransfer-getdata-返回指定类型的数据"><a href="#_5-2-datatransfer-getdata-返回指定类型的数据" class="header-anchor">#</a> 5.2 DataTransfer.getData() 返回指定类型的数据</h4> <p><code>DataTransfer.getData()</code>方法接受一个字符串(表示数据类型)作为参数,<strong>返回事件所带的指定类型的数据(通常是用<code>setData</code>方法添加的数据)</strong>。如果指定类型的数据不存在,则返回空字符串。通常只有<code>drop</code>事件触发后,才能取出数据。</p> <p>下面是一个<code>drop</code>事件的监听函数,用来取出指定类型的数据。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">onDrop</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> data <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span><span class="token function">getData</span><span class="token punctuation">(</span><span class="token string">'text/plain'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>textContent <span class="token operator">=</span> data<span class="token punctuation">;</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>上面代码取出拖拉事件的文本数据,将其替换成当前节点的文本内容。注意,这时还必须取消浏览器的默认行为,因为假如用户拖拉的是一个链接,浏览器默认会在当前窗口打开这个链接。</p> <p><code>getData</code>方法返回的是一个字符串,如果其中包含多项数据,就必须手动解析。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">doDrop</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> lines <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span><span class="token function">getData</span><span class="token punctuation">(</span><span class="token string">'text/uri-list'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> line <span class="token keyword">of</span> lines<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">let</span> link <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'a'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- link<span class="token punctuation">.</span>href <span class="token operator">=</span> line<span class="token punctuation">;</span>
- link<span class="token punctuation">.</span>textContent <span class="token operator">=</span> line<span class="token punctuation">;</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>link<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>上面代码中,<code>getData</code>方法返回的是一组链接,就必须自行解析。</p> <p>类型值指定为<code>URL</code>,可以取出第一个有效链接。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> link <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span><span class="token function">getData</span><span class="token punctuation">(</span><span class="token string">'URL'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>下面的例子是从多种类型的数据里面取出数据。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">doDrop</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> types <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span>types<span class="token punctuation">;</span>
- <span class="token keyword">var</span> supportedTypes <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'text/uri-list'</span><span class="token punctuation">,</span> <span class="token string">'text/plain'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
- types <span class="token operator">=</span> supportedTypes<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> types<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>types<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> data <span class="token operator">=</span> event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span><span class="token function">getData</span><span class="token punctuation">(</span>types<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><h4 id="_5-3-datatransfer-cleardata-清除指定或全部数据"><a href="#_5-3-datatransfer-cleardata-清除指定或全部数据" class="header-anchor">#</a> 5.3 DataTransfer.clearData() 清除指定或全部数据</h4> <p><code>DataTransfer.clearData()</code>方法接受一个字符串(表示数据类型)作为参数,删除事件所带的指定类型的数据。如果没有指定类型,则删除所有数据。如果指定类型不存在,则调用该方法不会产生任何效果。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>event<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span><span class="token function">clearData</span><span class="token punctuation">(</span><span class="token string">'text/uri-list'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>上面代码清除事件所带的<code>text/uri-list</code>类型的数据。</p> <p>该方法不会移除拖拉的文件,因此调用该方法后,<code>DataTransfer.types</code>属性可能依然会返回<code>Files</code>类型(前提是存在文件拖拉)。</p> <p>注意,该方法<strong>只能在<code>dragstart</code>事件的监听函数之中使用</strong>,因为这是拖拉操作的数据唯一可写的时机。</p> <h4 id="_5-4-datatransfer-setdragimage-设置拖动过程中的图片"><a href="#_5-4-datatransfer-setdragimage-设置拖动过程中的图片" class="header-anchor">#</a> 5.4 DataTransfer.setDragImage() 设置拖动过程中的图片</h4> <p>拖动过程中(<code>dragstart</code>事件触发后),浏览器<strong>会显示一张图片跟随鼠标一起移动</strong>,表示被拖动的节点。这张图片是<strong>自动创造的</strong>,通常显示为被拖动节点的外观,不需要自己动手设置。</p> <p><code>DataTransfer.setDragImage()</code>方法<strong>可以自定义这张图片</strong>。它接受三个参数。第一个是<code><img></code>节点或者<code><canvas></code>节点,如果省略或为<code>null</code>,则使用被拖动的节点的外观;第二个和第三个参数为鼠标相对于该图片左上角的横坐标和右坐标。</p> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">/* HTML 代码如下
- <div id="drag-with-image" class="dragdemo" draggable="true">
- drag me
- </div>
- */</span>
- <span class="token keyword">var</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'drag-with-image'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'dragstart'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> img <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'img'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- img<span class="token punctuation">.</span>src <span class="token operator">=</span> <span class="token string">'http://path/to/img'</span><span class="token punctuation">;</span>
- e<span class="token punctuation">.</span>dataTransfer<span class="token punctuation">.</span><span class="token function">setDragImage</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h2 id="十、其他常见事件"><a href="#十、其他常见事件" class="header-anchor">#</a> 十、其他常见事件</h2> <h3 id="_1、资源事件"><a href="#_1、资源事件" class="header-anchor">#</a> 1、资源事件</h3> <h4 id="_1-1-beforeunload-事件-关闭窗口前调用"><a href="#_1-1-beforeunload-事件-关闭窗口前调用" class="header-anchor">#</a> 1.1 beforeunload 事件 (关闭窗口前调用)</h4> <p><code>beforeunload</code>事件在<strong>窗口、文档、各种资源将要卸载前触发</strong>。它可以用来防止用户不小心卸载资源。</p> <p>如果该事件对象的<code>returnValue</code>属性是一个非空字符串,那么浏览器就会弹出一个对话框,询问用户是否要卸载该资源。但是,用户指定的字符串可能无法显示,浏览器会展示预定义的字符串。如果用户点击“取消”按钮,资源就不会卸载。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'beforeunload'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>returnValue <span class="token operator">=</span> <span class="token string">'你确定离开吗?'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>上面代码中,用户如果<strong>关闭窗口,浏览器会弹出一个窗口,要求用户确认</strong>。</p> <p>浏览器对这个事件的行为很不一致,有的浏览器调用<code>event.preventDefault()</code>,也会弹出对话框。IE 浏览器需要显式返回一个非空的字符串,才会弹出对话框。而且,<strong>大多数浏览器在对话框中不显示指定文本,只显示默认文本</strong>。因此,可以采用下面的写法,取得最大的兼容性。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'beforeunload'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> confirmationMessage <span class="token operator">=</span> <span class="token string">'确认关闭窗口?'</span><span class="token punctuation">;</span>
- e<span class="token punctuation">.</span>returnValue <span class="token operator">=</span> confirmationMessage<span class="token punctuation">;</span>
- <span class="token keyword">return</span> confirmationMessage<span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>注意,许多手机浏览器默认忽略这个事件,桌面浏览器也有办法忽略这个事件。所以,它可能根本不会生效,不能依赖它来阻止用户关闭窗口。另外,一旦使用了<code>beforeunload</code>事件,浏览器就不会缓存当前网页,使用“回退”按钮将重新向服务器请求网页。这是因为监听这个事件的目的,一般是修改初始状态,这时缓存初始页面就没意义了。</p> <p>基本上,只有一种场合可以监听<code>unload</code>事件,其他情况都不应该监听:<strong>用户修改了表单,还没有保存就要离开</strong>。</p> <h4 id="_1-2-unload-事件-即将关闭窗口时调用"><a href="#_1-2-unload-事件-即将关闭窗口时调用" class="header-anchor">#</a> 1.2 unload 事件 (即将关闭窗口时调用)</h4> <p><code>unload</code>事件在<strong>窗口关闭或者<code>document</code>对象将要卸载时触发</strong>。它的触发顺序排在<code>beforeunload</code>、<code>pagehide</code>事件后面。</p> <p><code>unload</code>事件发生时,文档处于一个特殊状态。所有资源依然存在,但是对用户来说都不可见,UI 互动全部无效。这个事件是无法取消的,即使在监听函数里面抛出错误,也不能停止文档的卸载。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'unload'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'文档将要卸载'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>手机上,浏览器或系统可能会直接丢弃网页,这时该事件根本不会发生。而且跟<code>beforeunload</code>事件一样,一旦使用了<code>unload</code>事件,浏览器就不会缓存当前网页,理由同上。因此,任何情况下都不应该依赖这个事件,指定网页卸载时要执行的代码,可以考虑完全不使用这个事件。</p> <h4 id="_1-3-load-事件-error-事件-abort事件-页面或某个资源加载成功-失败-取消时调用"><a href="#_1-3-load-事件-error-事件-abort事件-页面或某个资源加载成功-失败-取消时调用" class="header-anchor">#</a> 1.3 load 事件,error 事件 ,abort事件 (页面或某个资源加载成功/失败/取消时调用)</h4> <p><code>load</code>事件<strong>在页面或某个资源加载成功时触发</strong>。注意,<strong>页面或资源从浏览器缓存加载,并不会触发<code>load</code>事件</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'load'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'所有资源都加载完成'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p><code>error</code>事件是<strong>在页面或资源加载失败时触发</strong>。</p> <p><code>abort</code>事件是<strong>在用户取消加载时触发</strong>。</p> <p>这三个事件实际上属于进度事件,不仅发生在<code>document</code>对象,还发生在各种外部资源上面。浏览网页就是一个加载各种资源的过程,图像(image)、样式表(style sheet)、脚本(script)、视频(video)、音频(audio)、Ajax请求(XMLHttpRequest)等等。这些资源和<code>document</code>对象、<code>window</code>对象、XMLHttpRequestUpload 对象,都会触发<code>load</code>事件和<code>error</code>事件。</p> <p><strong>触发这三个事件的对象有</strong>:</p> <ul><li>window</li> <li>document</li> <li>body</li> <li>img</li> <li>style</li> <li>script</li> <li>video</li> <li>audio</li> <li>Ajax</li> <li>等等</li></ul> <h3 id="_2、session-历史事件"><a href="#_2、session-历史事件" class="header-anchor">#</a> 2、session 历史事件</h3> <h4 id="_2-1-pageshow-事件-页面显示-加载页面后执行-pagehide-事件-退出当前页面触发"><a href="#_2-1-pageshow-事件-页面显示-加载页面后执行-pagehide-事件-退出当前页面触发" class="header-anchor">#</a> 2.1 pageshow 事件(页面显示,加载页面后执行),pagehide 事件(退出当前页面触发)</h4> <p>默认情况下,浏览器会在当前会话(session)缓存页面,当用户<strong>点击“前进/后退”按钮时,浏览器就会从缓存中加载页面。</strong></p> <p>pageshow 事件<strong>在页面加载时触发,包括第一次加载和从缓存加载两种情况</strong>。如果要指定页面每次加载(不管是不是从浏览器缓存)时都运行的代码,可以放在这个事件的监听函数。</p> <p>第一次加载时,它的触发顺序排在<code>load</code>事件后面。从缓存加载时,<code>load</code>事件不会触发,因为网页在缓存中的样子通常是<code>load</code>事件的监听函数运行后的样子,所以不必重复执行。同理,如果是从缓存中加载页面,网页内初始化的 JavaScript 脚本(比如 DOMContentLoaded 事件的监听函数)也不会执行。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'pageshow'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'pageshow: '</span><span class="token punctuation">,</span> event<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>pageshow 事件<strong>有一个<code>persisted</code>属性</strong>,返回一个布尔值。页面第一次加载时,这个属性是<code>false</code>;当页面从缓存加载时,这个属性是<code>true</code>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'pageshow'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>persisted<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 是否从缓存加载</span>
- <span class="token comment">// ...</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p><code>pagehide</code>事件与<code>pageshow</code>事件类似,当用户<strong>通过“前进/后退”按钮,离开当前页面时触发</strong>。它与 unload 事件的区别在于,如果在 window 对象上定义<code>unload</code>事件的监听函数之后,页面不会保存在缓存中,而使用<code>pagehide</code>事件,页面会保存在缓存中。</p> <p><code>pagehide</code>事件实例也<strong>有一个<code>persisted</code>属性,将这个属性设为<code>true</code>,就表示页面要保存在缓存中;设为<code>false</code>,表示网页不保存在缓存中</strong>,这时如果设置了unload 事件的监听函数,该函数将在 pagehide 事件后立即运行。</p> <p>如果页面包含<code><frame></code>或<code><iframe></code>元素,则<code><frame></code>页面的<code>pageshow</code>事件和<code>pagehide</code>事件,都会在主页面之前触发。</p> <p><strong>注意,这两个事件只在浏览器的<code>history</code>(历史)对象发生变化时触发,跟网页是否可见没有关系。</strong></p> <h4 id="_2-2-popstate-事件-在浏览器的history对象的当前记录发生显式切换时触发"><a href="#_2-2-popstate-事件-在浏览器的history对象的当前记录发生显式切换时触发" class="header-anchor">#</a> 2.2 popstate 事件(在浏览器的<code>history</code>对象的当前记录发生显式切换时触发)</h4> <p><code>popstate</code>事件<strong>在浏览器的<code>history</code>对象的当前记录发生显式切换时触发</strong>。注意,调用<code>history.pushState()</code>或<code>history.replaceState()</code>,并不会触发<code>popstate</code>事件。该事件只在用户在<code>history</code>记录之间显式切换时触发,比如<strong>鼠标点击“后退/前进”按钮,或者在脚本中调用<code>history.back()</code>、<code>history.forward()</code>、<code>history.go()</code>时触发</strong>。</p> <p>该事件对象有一个<code>state</code>属性,保存<code>history.pushState</code>方法和<code>history.replaceState</code>方法为当前记录添加的<code>state</code>对象。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function-variable function">onpopstate</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'state: '</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- history<span class="token punctuation">.</span><span class="token function">pushState</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token literal-property property">page</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">'title 1'</span><span class="token punctuation">,</span> <span class="token string">'?page=1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- history<span class="token punctuation">.</span><span class="token function">pushState</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token literal-property property">page</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">'title 2'</span><span class="token punctuation">,</span> <span class="token string">'?page=2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- history<span class="token punctuation">.</span><span class="token function">replaceState</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token literal-property property">page</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">'title 3'</span><span class="token punctuation">,</span> <span class="token string">'?page=3'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- history<span class="token punctuation">.</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// state: {"page":1}</span>
- history<span class="token punctuation">.</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// state: null</span>
- history<span class="token punctuation">.</span><span class="token function">go</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// state: {"page":3}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>上面代码中,<code>pushState</code>方法向<code>history</code>添加了两条记录,然后<code>replaceState</code>方法替换掉当前记录。因此,连续两次<code>back</code>方法,会让当前条目退回到原始网址,它没有附带<code>state</code>对象,所以事件的<code>state</code>属性为<code>null</code>,然后前进两条记录,又回到<code>replaceState</code>方法添加的记录。</p> <p>浏览器对于页面首次加载,是否触发<code>popstate</code>事件,处理不一样,Firefox 不触发该事件。</p> <h4 id="_2-3-hashchange-事件-hash发生变化时触发"><a href="#_2-3-hashchange-事件-hash发生变化时触发" class="header-anchor">#</a> 2.3 hashchange 事件 (hash发生变化时触发)</h4> <p><code>hashchange</code>事件在 U<strong>RL 的 hash 部分(即<code>#</code>号后面的部分,包括<code>#</code>号)发生变化时触发</strong>。该事件<strong>一般在<code>window</code>对象上监听</strong>。</p> <p><code>hashchange</code>的事件实例具有两个特有属性:<code>oldURL</code>属性和<code>newURL</code>属性,分别表示变化前后的完整 URL。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// URL 是 http://www.example.com/</span>
- window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'hashchange'</span><span class="token punctuation">,</span> myFunction<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">myFunction</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>oldURL<span class="token punctuation">)</span><span class="token punctuation">;</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>newURL<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- location<span class="token punctuation">.</span>hash <span class="token operator">=</span> <span class="token string">'part2'</span><span class="token punctuation">;</span>
- <span class="token comment">// http://www.example.com/</span>
- <span class="token comment">// http://www.example.com/#part2</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h3 id="_3、网页状态事件"><a href="#_3、网页状态事件" class="header-anchor">#</a> 3、网页状态事件</h3> <h4 id="_3-1-domcontentloaded-事件-dom内容加载完成后触发"><a href="#_3-1-domcontentloaded-事件-dom内容加载完成后触发" class="header-anchor">#</a> 3.1 DOMContentLoaded 事件 (DOM内容加载完成后触发)</h4> <p><strong>网页下载并解析完成以后,浏览器就会在<code>document</code>对象上触发 DOMContentLoaded 事件</strong>。这时,仅仅完成了网页的解析(整张页面的 DOM 生成了),<strong>所有外部资源(样式表、脚本、iframe 等等)可能还没有下载结束</strong>。也就是说,这个事件<strong>比<code>load</code>事件,发生时间早得多</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'DOMContentLoaded'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'DOM生成'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>注意,网页的 JavaScript 脚本是同步执行的,脚本一旦发生堵塞,将推迟触发<code>DOMContentLoaded</code>事件。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'DOMContentLoaded'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'DOM 生成'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token comment">// 这段代码会推迟触发 DOMContentLoaded 事件</span>
- <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">1000000000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// ...</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h4 id="_3-2-readystatechange-事件-document-对象和-xmlhttprequest-对象的readystate属性发生变化时触发"><a href="#_3-2-readystatechange-事件-document-对象和-xmlhttprequest-对象的readystate属性发生变化时触发" class="header-anchor">#</a> 3.2 readystatechange 事件(Document 对象和 XMLHttpRequest 对象的<code>readyState</code>属性发生变化时触发)</h4> <p><code>readystatechange</code>事件<strong>当 Document 对象和 XMLHttpRequest 对象的<code>readyState</code>属性发生变化时触发</strong>。<code>document.readyState</code>有三个可能的值:<code>loading</code>(网页正在加载)、<code>interactive</code>(网页已经解析完成,但是外部资源仍然处在加载状态)和<code>complete</code>(网页和所有外部资源已经结束加载,<code>load</code>事件即将触发)。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>document<span class="token punctuation">.</span><span class="token function-variable function">onreadystatechange</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>document<span class="token punctuation">.</span>readyState <span class="token operator">===</span> <span class="token string">'interactive'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// ...</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>这个事件可以看作<code>DOMContentLoaded</code>事件的另一种实现方法。</p> <h3 id="_4、窗口事件"><a href="#_4、窗口事件" class="header-anchor">#</a> 4、窗口事件</h3> <h4 id="_4-1-scroll-事件-文档或文档元素滚动时触发"><a href="#_4-1-scroll-事件-文档或文档元素滚动时触发" class="header-anchor">#</a> 4.1 scroll 事件 (文档或文档元素滚动时触发)</h4> <p><code>scroll</code>事件在<strong>文档或文档元素滚动时触发</strong>,主要出现在用户拖动滚动条。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>该事件<strong>会连续地大量触发</strong>,所以它的监听函数之中不应该有非常耗费计算的操作。推荐的做法是使用<code>requestAnimationFrame</code>或<code>setTimeout</code>控制该事件的触发频率,然后可以结合<code>customEvent</code>抛出一个新事件。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> <span class="token function-variable function">throttle</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">type<span class="token punctuation">,</span> name<span class="token punctuation">,</span> obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 节流函数 控制触发频率</span>
- <span class="token keyword">var</span> obj <span class="token operator">=</span> obj <span class="token operator">||</span> window<span class="token punctuation">;</span>
- <span class="token keyword">var</span> running <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>running<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
- running <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
- <span class="token function">requestAnimationFrame</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 结合此方法控制在每秒60次</span>
- obj<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">CustomEvent</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- running <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- obj<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> func<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- <span class="token comment">// 将 scroll 事件重定义为 optimizedScroll 事件</span>
- <span class="token function">throttle</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> <span class="token string">'optimizedScroll'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'optimizedScroll'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Resource conscious scroll callback!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br></div></div><p>上面代码中,<code>throttle</code>函数用于控制事件触发频率,<code>requestAnimationFrame</code>方法保证每次页面重绘(每秒60次),只会触发一次<code>scroll</code>事件的监听函数。也就是说,上面方法将<code>scroll</code>事件的触发频率,限制在每秒60次。具体来说,就是<code>scroll</code>事件只要频率低于每秒60次,就会触发<code>optimizedScroll</code>事件,从而执行<code>optimizedScroll</code>事件的监听函数。</p> <p>改用<code>setTimeout</code>方法,可以放置更大的时间间隔。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> scrollThrottler<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">var</span> scrollTimeout<span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">scrollThrottler</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>scrollTimeout<span class="token punctuation">)</span> <span class="token punctuation">{</span>
- scrollTimeout <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- scrollTimeout <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
- <span class="token function">actualScrollHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">66</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- <span class="token keyword">function</span> <span class="token function">actualScrollHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// ...</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>上面代码中,每次<code>scroll</code>事件都会执行<code>scrollThrottler</code>函数。该函数里面有一个定时器<code>setTimeout</code>,每66毫秒触发一次(每秒15次)真正执行的任务<code>actualScrollHandler</code>。</p> <p>下面是一个更一般的<code>throttle</code>函数的写法。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">throttle</span><span class="token punctuation">(</span><span class="token parameter">fn<span class="token punctuation">,</span> wait</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">var</span> time <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">return</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>time <span class="token operator">+</span> wait <span class="token operator">-</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- time <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span>
- window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> <span class="token function">throttle</span><span class="token punctuation">(</span>callback<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>上面的代码将<code>scroll</code>事件的触发频率,限制在一秒一次。</p> <p><a href="https://www.lodashjs.com/" target="_blank" rel="noopener noreferrer">lodash<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>函数库提供了现成的<code>throttle</code>函数,可以直接使用。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> _<span class="token punctuation">.</span><span class="token function">throttle</span><span class="token punctuation">(</span>callback<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>本书前面介绍过<code>debounce</code>的概念,<code>throttle</code>与它区别在于,<code>throttle</code>是“节流”,确保一段时间内只执行一次,而<code>debounce</code>是“防抖”,要连续操作结束后再执行。以网页滚动为例,<code>debounce</code>要等到用户停止滚动后才执行,<code>throttle</code>则是如果用户一直在滚动网页,那么在滚动过程中还是会执行。</p> <h4 id="_4-2-resize-事件-窗口大小变化时触发"><a href="#_4-2-resize-事件-窗口大小变化时触发" class="header-anchor">#</a> 4.2 resize 事件(窗口大小变化时触发)</h4> <p><code>resize</code>事件<strong>在改变浏览器窗口大小时触发</strong>,主要<strong>发生在<code>window</code>对象上面</strong>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> <span class="token function-variable function">resizeMethod</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token keyword">if</span> <span class="token punctuation">(</span>document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>clientWidth <span class="token operator"><</span> <span class="token number">768</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'移动设备的视口'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'resize'</span><span class="token punctuation">,</span> resizeMethod<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>该事件也会连续地大量触发,所以最好像上面的<code>scroll</code>事件一样,通过<code>throttle</code>函数控制事件触发频率。</p> <h4 id="_4-3-fullscreenchange-事件-元素进入-退出全屏时触发-fullscreenerror-事件-无法切换全屏时触发"><a href="#_4-3-fullscreenchange-事件-元素进入-退出全屏时触发-fullscreenerror-事件-无法切换全屏时触发" class="header-anchor">#</a> 4.3 fullscreenchange 事件(元素进入/退出全屏时触发),fullscreenerror 事件(无法切换全屏时触发)</h4> <p><code>fullscreenchange</code>事件<strong>在元素进入或退出全屏状态时触发</strong>,该事件<strong>发生在<code>document</code>对象上面</strong>。</p> <p><strong>注意,此事件非浏览器的进入/退出全屏时触发的事件。</strong></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'fullscreenchange'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span>fullscreenElement<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 全屏的元素,如果为null时表示已退出全屏</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">requestFullscreen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 设置元素为全屏展示</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p><code>fullscreenerror</code>事件在<strong>浏览器无法切换到全屏状态时触发</strong>。</p> <h3 id="_5、剪贴板事件"><a href="#_5、剪贴板事件" class="header-anchor">#</a> 5、剪贴板事件</h3> <p>以下三个事件属于剪贴板操作的相关事件。</p> <ul><li><code>cut</code>:将选中的内容从文档中移除,加入剪贴板时触发。<strong>【剪切】</strong></li> <li><code>copy</code>:进行复制动作时触发。<strong>【拷贝】</strong></li> <li><code>paste</code>:剪贴板内容粘贴到文档后触发。<strong>【粘贴】</strong></li></ul> <p>这三个事件都是**<code>ClipboardEvent</code>接口的实例**。<code>ClipboardEvent</code>有一个实例属性<code>clipboardData</code>,是一个 DataTransfer 对象,存放剪贴的数据。具体的 API 接口和操作方法,请参见《拖拉事件》的 DataTransfer 对象部分。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'copy'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- e<span class="token punctuation">.</span>clipboardData<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/plain'</span><span class="token punctuation">,</span> <span class="token string">'Hello, world!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- e<span class="token punctuation">.</span>clipboardData<span class="token punctuation">.</span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token string">'text/html'</span><span class="token punctuation">,</span> <span class="token string">'<b>Hello, world!</b>'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>上面的代码使得复制进入剪贴板的,都是开发者指定的数据,而不是用户想要拷贝的数据。</p> <h3 id="_6、焦点事件"><a href="#_6、焦点事件" class="header-anchor">#</a> 6、焦点事件</h3> <p>焦点事件发生在元素节点和<code>document</code>对象上面,与获得或失去焦点相关。它主要包括以下四个事件。</p> <ul><li><code>focus</code>:元素节点<strong>获得焦点</strong>后触发,该事件不会冒泡。</li> <li><code>blur</code>:元素节点<strong>失去焦点</strong>后触发,该事件不会冒泡。</li> <li><code>focusin</code>:元素节点<strong>将要获得焦点</strong>时触发,发生在<code>focus</code>事件之前。该事件会冒泡。</li> <li><code>focusout</code>:元素节点<strong>将要失去焦点</strong>时触发,发生在<code>blur</code>事件之前。该事件会冒泡。</li></ul> <p>这四个事件都继承了<code>FocusEvent</code>接口。<code>FocusEvent</code>实例具有以下属性。</p> <ul><li><code>FocusEvent.target</code>:事件的目标节点。</li> <li><code>FocusEvent.relatedTarget</code>:对于<code>focusin</code>事件,返回失去焦点的节点;对于<code>focusout</code>事件,返回将要接受焦点的节点;对于<code>focus</code>和<code>blur</code>事件,返回<code>null</code>。</li></ul> <p>由于<code>focus</code>和<code>blur</code>事件不会冒泡,只能在捕获阶段触发,所以<code>addEventListener</code>方法的第三个参数需要设为<code>true</code>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>form<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'focus'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>background <span class="token operator">=</span> <span class="token string">'pink'</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- form<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'blur'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>style<span class="token punctuation">.</span>background <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>上面代码针对表单的文本输入框,接受焦点时设置背景色,失去焦点时去除背景色。</p> <h3 id="_7、customevent-接口-自定义事件"><a href="#_7、customevent-接口-自定义事件" class="header-anchor">#</a> 7、CustomEvent 接口(自定义事件)</h3> <p>CustomEvent 接口<strong>用于生成自定义的事件实例</strong>。那些浏览器预定义的事件,虽然可以手动生成,但是往往不能在事件上绑定数据。如果需要在触发事件的同时,传入指定的数据,就可以使用 CustomEvent 接口生成的自定义事件对象。</p> <p>浏览器原生提供<code>CustomEvent()</code>构造函数,用来生成 CustomEvent 事件实例。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">CustomEvent</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> options<span class="token punctuation">)</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><code>CustomEvent()</code>构造函数接受两个参数。第一个参数是字符串,表示事件的名字,这是必须的。第二个参数是事件的配置对象,这个参数是可选的。<code>CustomEvent</code>的配置对象除了接受 Event 事件的配置属性,只有一个自己的属性。</p> <ul><li><code>detail</code>:表示事件的附带数据,默认为<code>null</code>。</li></ul> <p>下面是一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> event <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CustomEvent</span><span class="token punctuation">(</span><span class="token string">'build'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token string-property property">'detail'</span><span class="token operator">:</span> <span class="token string">'hello'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token keyword">function</span> <span class="token function">eventHandler</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>detail<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'build'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>detail<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>上面代码中,我们手动定义了<code>build</code>事件。该事件触发后,会被监听到,从而输出该事件实例的<code>detail</code>属性(即字符串<code>hello</code>)。</p> <p>下面是另一个例子。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">var</span> myEvent <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CustomEvent</span><span class="token punctuation">(</span><span class="token string">'myevent'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
- <span class="token literal-property property">detail</span><span class="token operator">:</span> <span class="token punctuation">{</span>
- <span class="token literal-property property">foo</span><span class="token operator">:</span> <span class="token string">'bar'</span>
- <span class="token punctuation">}</span><span class="token punctuation">,</span>
- <span class="token literal-property property">bubbles</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
- <span class="token literal-property property">cancelable</span><span class="token operator">:</span> <span class="token boolean">false</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'myevent'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello '</span> <span class="token operator">+</span> event<span class="token punctuation">.</span>detail<span class="token punctuation">.</span>foo<span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- el<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span>myEvent<span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><p>上面代码也说明,CustomEvent 的事件实例,除了具有 Event 接口的实例属性,还具有<code>detail</code>属性。</p> <h2 id="十一、globaleventhandlers-接口-全局事件处理接口"><a href="#十一、globaleventhandlers-接口-全局事件处理接口" class="header-anchor">#</a> 十一、GlobalEventHandlers 接口 (全局事件处理接口)</h2> <p>指定事件的回调函数,推荐使用的方法是元素的<code>addEventListener</code>方法。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> clickHandler<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>除了之外,还有一种方法可以直接指定事件的回调函数。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>div<span class="token punctuation">.</span>onclick <span class="token operator">=</span> clickHandler<span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>这个接口是由<code>GlobalEventHandlers</code>接口提供的。它的优点是使用比较方便,缺点是只能为每个事件指定一个回调函数,并且无法指定事件触发的阶段(捕获阶段还是冒泡阶段)。</p> <p><strong><code>HTMLElement</code>、<code>Document</code>和<code>Window</code>都继承了这个接口,也就是说,各种 HTML 元素、<code>document</code>对象、<code>window</code>对象上面都可以使用<code>GlobalEventHandlers</code>接口提供的属性</strong>。下面就列出这个接口提供的主要的事件属性。</p> <h3 id="_1、globaleventhandlers-onabort-中断事件"><a href="#_1、globaleventhandlers-onabort-中断事件" class="header-anchor">#</a> 1、GlobalEventHandlers.onabort (中断事件)</h3> <p>某个对象的<code>abort</code>事件(停止加载)发生时,就会调用<code>onabort</code>属性指定的回调函数。</p> <p>各种元素的停止加载事件,到底如何触发,目前并没有统一的规定。因此实际上,这个属性现在一般只用在<code><img></code>元素上面。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// HTML 代码如下</span>
- <span class="token comment">// <img src="example.jpg" id="img"></span>
- <span class="token keyword">var</span> img <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'img'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- img<span class="token punctuation">.</span><span class="token function-variable function">onabort</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'图片加载中断'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="_2、globaleventhandlers-onerror-错误事件"><a href="#_2、globaleventhandlers-onerror-错误事件" class="header-anchor">#</a> 2、GlobalEventHandlers.onerror (错误事件)</h3> <p><code>error</code>事件发生时,就会调用<code>onerror</code>属性指定的回调函数。</p> <p><code>error</code>事件<strong>分成两种</strong>。</p> <p><strong>一种是 JavaScript 的运行时错误</strong>,这会传到<code>window</code>对象,导致<code>window.onerror()</code>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>window<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">message<span class="token punctuation">,</span> source<span class="token punctuation">,</span> lineno<span class="token punctuation">,</span> colno<span class="token punctuation">,</span> error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// ...</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p><code>window.onerror</code>的处理函数共接受五个参数,含义如下。</p> <ul><li>message:错误信息字符串</li> <li>source:报错脚本的 URL</li> <li>lineno:报错的行号,是一个整数</li> <li>colno:报错的列号,是一个整数</li> <li>error: 错误对象</li></ul> <p>另<strong>一种是资源加载错误</strong>,比如<code><img></code>或<code><script></code>加载的资源出现加载错误。这时,Error 对象会传到对应的元素,导致该元素的<code>onerror</code>属性开始执行。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>element<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- <span class="token comment">// ...</span>
- <span class="token punctuation">}</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>注意,一般来说,资源的加载错误不会触发<code>window.onerror</code>。</p> <h3 id="_3、globaleventhandlers-onload-加载完成事件-、globaleventhandlers-onloadstart-开始加载事件"><a href="#_3、globaleventhandlers-onload-加载完成事件-、globaleventhandlers-onloadstart-开始加载事件" class="header-anchor">#</a> 3、GlobalEventHandlers.onload(加载完成事件)、GlobalEventHandlers.onloadstart(开始加载事件)</h3> <p>元素完成加载时,会触发<code>load</code>事件,执行<code>onload()</code>。它的典型使用场景是<code>window</code>对象和<code><img></code>元素。对于<code>window</code>对象来说,只有页面的所有资源加载完成(包括图片、脚本、样式表、字体等所有外部资源),才会触发<code>load</code>事件。</p> <p>对于<code><img></code>和<code><video></code>等元素,加载开始时还会触发<code>loadstart</code>事件,导致执行<code>onloadstart</code>。</p> <h3 id="_4、globaleventhandlers-onfocus-获取焦点事件-globaleventhandlers-onblur-失去焦点事件"><a href="#_4、globaleventhandlers-onfocus-获取焦点事件-globaleventhandlers-onblur-失去焦点事件" class="header-anchor">#</a> 4、GlobalEventHandlers.onfocus(获取焦点事件),GlobalEventHandlers.onblur(失去焦点事件)</h3> <p>当前元素获得焦点时,会触发<code>element.onfocus</code>;失去焦点时,会触发<code>element.onblur</code>。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>element<span class="token punctuation">.</span><span class="token function-variable function">onfocus</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"onfocus event detected!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- element<span class="token punctuation">.</span><span class="token function-variable function">onblur</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
- console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"onblur event detected!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>注意,如果不是可以接受用户输入的元素,要触发<code>onfocus</code>,该元素必须有<code>tabindex</code>属性。</p> <h3 id="_5、globaleventhandlers-onscroll-滚动事件"><a href="#_5、globaleventhandlers-onscroll-滚动事件" class="header-anchor">#</a> 5、GlobalEventHandlers.onscroll(滚动事件)</h3> <p>页面或元素滚动时,会触发<code>scroll</code>事件,导致执行<code>onscroll()</code>。</p> <h3 id="_6、globaleventhandlers-oncontextmenu-右键菜单事件-globaleventhandlers-onshow-显示右键菜单时触发"><a href="#_6、globaleventhandlers-oncontextmenu-右键菜单事件-globaleventhandlers-onshow-显示右键菜单时触发" class="header-anchor">#</a> 6、GlobalEventHandlers.oncontextmenu(右键菜单事件),GlobalEventHandlers.onshow(显示右键菜单时触发)</h3> <p>用户在页面上按下鼠标的右键,会触发<code>contextmenu</code>事件,导致执行<code>oncontextmenu()</code>。如果该属性执行后返回<code>false</code>,就等于禁止了右键菜单。<code>document.oncontextmenu</code>与<code>window.oncontextmenu</code>效果一样。</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>document<span class="token punctuation">.</span><span class="token function-variable function">oncontextmenu</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">// 禁用右键菜单</span>
- <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
- <span class="token punctuation">}</span><span class="token punctuation">;</span>
- </code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>上面代码中,<code>oncontextmenu</code>属性执行后返回<code>false</code>,右键菜单就不会出现。</p> <p>元素的右键菜单显示时,会触发该元素的<code>onshow</code>监听函数。</p> <h3 id="_7、其他的事件属性"><a href="#_7、其他的事件属性" class="header-anchor">#</a> 7、其他的事件属性</h3> <p>鼠标的事件属性。</p> <ul><li>onclick</li> <li>ondblclick</li> <li>onmousedown</li> <li>onmouseenter</li> <li>onmouseleave</li> <li>onmousemove</li> <li>onmouseout</li> <li>onmouseover</li> <li>onmouseup</li> <li>onwheel</li></ul> <p>键盘的事件属性。</p> <ul><li>onkeydown</li> <li>onkeypress</li> <li>onkeyup</li></ul> <p>焦点的事件属性。</p> <ul><li>onblur</li> <li>onfocus</li></ul> <p>表单的事件属性。</p> <ul><li>oninput</li> <li>onchange</li> <li>onsubmit</li> <li>onreset</li> <li>oninvalid</li> <li>onselect</li></ul> <p>触摸的事件属性。</p> <ul><li>ontouchcancel</li> <li>ontouchend</li> <li>ontouchmove</li> <li>ontouchstart</li></ul> <p>拖动的事件属性分成两类:一类与被拖动元素相关,另一类与接收被拖动元素的容器元素相关。</p> <p>被拖动元素的事件属性。</p> <ul><li>ondragstart:拖动开始</li> <li>ondrag:拖动过程中,每隔几百毫秒触发一次</li> <li>ondragend:拖动结束</li></ul> <p>接收被拖动元素的容器元素的事件属性。</p> <ul><li>ondragenter:被拖动元素进入容器元素。</li> <li>ondragleave:被拖动元素离开容器元素。</li> <li>ondragover:被拖动元素在容器元素上方,每隔几百毫秒触发一次。</li> <li>ondrop:松开鼠标后,被拖动元素放入容器元素。</li></ul> <p><code><dialog></code>对话框元素的事件属性。</p> <ul><li>oncancel</li> <li>onclose</li></ul> <h2 id="文档"><a href="#文档" class="header-anchor">#</a> 文档</h2> <p>学习文档:<a href="https://wangdoc.com/javascript/" target="_blank" rel="noopener noreferrer">https://wangdoc.com/javascript/<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></div></div> <div class="page-edit"><div class="edit-link"><a href="https://github.com/heBody/blog/edit/master/docs/《JavaScript教程》笔记/06.事件.md" target="_blank" rel="noopener noreferrer">编辑</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="tags"><a href="/blog/tags/?tag=JavaScript" title="标签">#JavaScript</a></div> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2022/12/14, 19:36:42</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/blog/pages/7d961b8030c6099e/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">DOM</div></a> <a href="/blog/pages/bab4930124ad2c10/" class="page-nav-centre page-nav-centre-next"><div class="tooltip">浏览器模型</div></a></div> <div class="page-nav"><p class="inner"><span class="prev">
- ←
- <a href="/blog/pages/7d961b8030c6099e/" class="prev">DOM</a></span> <span class="next"><a href="/blog/pages/bab4930124ad2c10/">浏览器模型</a>→
- </span></p></div></div></div> <div class="article-list"><div class="article-title"><a href="/blog/archives/" class="iconfont icon-bi">最近更新</a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><a href="/blog/pages/922650/"><div>
- Git修改分支名
- <!----></div></a> <span class="date">08-11</span></dt></dl><dl><dd>02</dd> <dt><a href="/blog/pages/55f894/"><div>
- CSS给table的tbody添加滚动条
- <!----></div></a> <span class="date">06-29</span></dt></dl><dl><dd>03</dd> <dt><a href="/blog/pages/829589/"><div>
- 我做了一个手写春联小网页,祝大家虎年暴富
- <span class="title-tag">
- 原创
- </span></div></a> <span class="date">01-28</span></dt></dl> <dl><dd></dd> <dt><a href="/blog/archives/" class="more">更多文章></a></dt></dl></div></div></main></div> <div class="footer"><div class="icons"><a href="mailto:30363811@qq.com" title="发邮件" target="_blank" class="iconfont icon-youjian"></a><a href="https://github.com/heBody" title="GitHub" target="_blank" class="iconfont icon-github"></a></div>
- Copyright © 2016-2022
- <span>Hesb | <a href="https://github.com/heBody/blob" target="_blank">MIT License</a></span></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-fanhuidingbu" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div> <div title="主题模式" class="button blur theme-mode-but iconfont icon-zhuti"><ul class="select-box" style="display:none;"><li class="iconfont icon-zidong">
- 跟随系统
- </li><li class="iconfont icon-rijianmoshi">
- 浅色模式
- </li><li class="iconfont icon-yejianmoshi">
- 深色模式
- </li><li class="iconfont icon-yuedu">
- 阅读模式
- </li></ul></div></div> <!----> <!----> <!----></div><div class="global-ui"><div></div></div></div>
- <script src="/blog/assets/js/app.28edfb28.js" defer></script><script src="/blog/assets/js/2.395c0d18.js" defer></script><script src="/blog/assets/js/3.6748bd5c.js" defer></script><script src="/blog/assets/js/141.128b6e26.js" defer></script>
- </body>
- </html>
|