JavaScript 事件(六)

脚本响应事件的方式, 通常是更新 web 页面内容

交互操作创建事件 --> 事件触发代码 --> 代码反馈信息给用户

UI 事件

当与浏览器 UI 本身交互时发生的事件

load - Web 页面加载完成
unload - Web 页面正在卸载
error - 浏览器遇到 JS 错误或不存在的资源
resize - 浏览器窗口的大小发生变化
scroll - 用户使用滚动条移动了页面

键盘事件

当用户操作键盘时发生

keydown - 用户第一次按下一个键(按住这个键时会反复触发)
keyup - 用户松开了一个键
keypress - 输入一个字符

//例:表单键入并直接显示

var el;                                                    // Declare variables

function charCount(e) {                                    // Declare function
 var textEntered, charDisplay, counter, lastkey;          // Declare variables
 textEntered = document.getElementById('message').value;  // User's text
 charDisplay = document.getElementById('charactersLeft'); // Counter element
 counter = (180 - (textEntered.length));                  // Num of chars left
 charDisplay.textContent = counter;                       // Show chars left
 lastkey = document.getElementById('lastKey');            // Get last key elem
 lastkey.textContent = 'Last key in ASCII code: ' + e.keyCode; // Create msg 
}

el = document.getElementById('message');                   // Get msg element
el.addEventListener('keyup', charCount, false); // on keyup - call charCount()
鼠标事件

当用户操作鼠标或触控屏幕

click - 单击一个元素
dblclick - 双击一个元素
mousedown - 在一个元素上按下
mouseup - 在一个元素上松开
mousemove - 移动鼠标(不会发生在触屏上)
mouseover - 鼠标移到一个元素上(不会发生在触屏上)
mouseout - 鼠标在一个元素上移开(不会发生在触屏上)

var msg = '<div class=\"header\"><a id=\"close\" href="#">close X</a></div>';
msg += '<div><h2>System Maintenance</h2>';
msg += 'Our servers are being updated between 3 and 4 a.m. ';
msg += 'During this time, there may be minor disruptions to service.</div>';

var elNote = document.createElement('div');       // Create a new element
elNote.setAttribute('id', 'note');                // Add an id of note
elNote.innerHTML = msg;                           // Add the message
document.body.appendChild(elNote);                // Add it to the page

function dismissNote() {                          // Declare function
 document.body.removeChild(elNote);              // Remove the note
}

var elClose = document.getElementById('close');   // Get the close button
elClose.addEventListener('click', dismissNote, false);// Click close-clear note
焦点事件

当一个元素得到或失去一个焦点时

focus/focusin - 元素得到焦点
blur/focusout - 元素失去焦点

function checkUsername() {                        // Declare function
 var username = el.value;                        // Store username in variable
 if (username.length < 5) {                      // If username < 5 characters
   elMsg.className = 'warning';                  // Change class on message
   elMsg.textContent = 'Not long enough, yet...';// Update message
 } else {                                        // Otherwise
   elMsg.textContent = '';                       // Clear the message
 }
}

function tipUsername() {                          // Declare function
 elMsg.className = 'tip';                        // Change class for message
 elMsg.innerHTML = 'Username must be at least 5 characters'; // Add message
}

var el = document.getElementById('username');     // Username input
var elMsg = document.getElementById('feedback');  // Element to hold message

// When the username input gains / loses focus call functions above:
el.addEventListener('focus', tipUsername, false); // focus call tipUsername()
el.addEventListener('blur', checkUsername, false);// blur call checkUsername()
表单事件

当用户与表单元素发生交互时

input - 输入框元素中发生了变化
change - 选框按钮发生变化
submit - 用户提交表单
reset - 用户点了表单上的重置按钮(少用)
cut - 用户从表单中剪切了内容
copy - 用户从表单中复制了内容
paste - 用户向表单中粘贴了内容
selet - 用户在表单中选中了一些文本

//表单提示和检查代码示例:
//HTML 例:
<!DOCTYPE html>
<html>
 <head>
   <title>JavaScript &amp; jQuery - Chapter 6: Events - Form Events</title>
   <link rel="stylesheet" href="css/c06.css" />
 </head>
 <body>
   <div id="page">
     <h1>List King</h1>
     <form method="post" action="http://www.example.org/register" id="formSignup">
       <h2>Membership</h2>

       <label for="package" class="selectbox"> Select a package: </label>
       <select id="package">
         <option value="annual">1 year ($50)</option>
         <option value="monthly">1 month ($5)</option>
       </select>
       <div id="packageHint" class="tip"></div>

       <input type="checkbox" id="terms" />
       <label for="terms" class="checkbox"> Check to agree to terms &amp; conditions</label>
       <div id="termsHint" class="warning"></div>

       <input type="submit" value="next" />

       </form>
     </div>
     <script src="js/form.js"></script>
   </body>
</html>


//JS 例:
var elForm, elSelectPackage, elPackageHint, elTerms, elTermsHint; // Declare variables
elForm          = document.getElementById('formSignup');          // Store elements
elSelectPackage = document.getElementById('package');
elPackageHint   = document.getElementById('packageHint');
elTerms         = document.getElementById('terms');
elTermsHint     = document.getElementById('termsHint');

function packageHint() {                                 // Declare function
 var pack = this.options[this.selectedIndex].value;     // Get selected option
 if (pack === 'monthly') {                              // If monthly package
   elPackageHint.innerHTML = 'Save $10 if you pay for 1 year!';//Show this msg
 } else {                                               // Otherwise
   elPackageHint.innerHTML = 'Wise choice!';            // Show this message
 }
}

function checkTerms(event) {                             // Declare function
 if (!elTerms.checked) {                                // If checkbox ticked
   elTermsHint.innerHTML = 'You must agree to the terms.'; // Show message
   event.preventDefault();                              // Don't submit form
 }
}

//Create event listeners: submit calls checkTerms(), change calls packageHint()
elForm.addEventListener('submit', checkTerms, false);
elSelectPackage.addEventListener('change', packageHint, false);

事件如何触发 JavaScript 代码

事件处理三步骤:

  • 一. 获取触发事件的 DOM 节点
  • 二. 将事件绑定到 DOM 节点

1.传统的 DOM 事件处理

element.onevent = functionName;      //目标函数节点.事件带"on"前缀 = 调用的函数名(后面不带小括号)

//例:
function checkUsername() {
 //事件的函数代码
}

var el = document.getElementById('username');
el.onblur = checkUsername;

2.DOM 监听器

element.addEventListener('event', functionName [, Boolean]);      
//元素.时间选择器(事件"无on前缀", 函数代码, 事件流"一般为 false")

//例:
function checkUsername() {
 //事件的函数代码
}

var el = document.getElementById('username');
el.addEventListener('blur', checkUsername, false);

3.如何向事件中的函数传参

//需要将事件函数封装在匿名函数中
el.addEventListener(
   'blur',
   function() {
       checkUsername(5);
   },
   false
);
  • 三. 编写事件需要自行的的函数(有名或匿名)

事件对象

可获取事件的信息, 以及发生在哪个元素上

  • 属性
    target -事件的目标元素
    type - 事件的类型
    cancelabel - 是否可撤销事件在这个元素上的默认行为
  • 方法
    preventDefault() - 撤销这个事件的默认行为
    stopPropagation() - 停止事件继续冒泡或向下捕获的过程
//使用事件对象例:

---
//无参数事件
function checkUsername(e) {
   var target = e.target;
}

var el = document.getElementById('username');
el.addEventListener('blur', checkUsername, false);

---
//带参数的事件
function checkUsername(e, minLength) {
   var target = e.target;
}

var el = document.getElementById('username');
el.addEventListener(
   'blur',
   function() {
       checkUsername(e, 5);
   },
   false
);

事件委托

为大量元素创建监听事件会影响页面速度, 所以使用事件流在父元素上监听事件.

//HTML:
<div id="page">
  <h1>List King</h1>
  <h2>Buy groceries</h2>
  <ul id="shoppingList">
    <li class="complete"><a href="itemDone.php?id=1"><em>fresh</em> figs</a></li>
    <li class="complete"><a href="itemDone.php?id=2">pine nuts</a></li>
    <li class="complete"><a href="itemDone.php?id=3">honey</a></li>
    <li class="complete"><a href="itemDone.php?id=4">balsamic vinegar</a></li>
  </ul>
</div>

//JS例:
function itemDone(e) {
  var target, elParent, elGrandparent;
  target = getTarget(e);
  elParent = target.parentNode;
  elGrandparent = target.parentNode.parentNode;
  elGrandparent.removeChild(elParent);
  e.preventDefault;
}

var el = document.getElementById('shoppingList');
el.addEventListener('click', function(e){
  itemDone(e);
}, false)

this 关键字指向函数的所有者

当没有参数传递给函数时, 常常使用 this 作为沟通

function checkUsername(){
  var elMsg = document.getElementById('feedback');
  if (this.value.length < 5) { 
    elMsg.innerHTML = 'Not long enough';
   } else {
    elMsg.innerHTML = ' ';
  }
}

var el = document.getElementById('username');
el.addEventListener('blur', checkUsername, false);

如果需要往函数传递参数,那么this 关键字就会失效

因为这个函数的所有者不再是监听器所绑定的元素, 而是那个匿名函数

function checkUsername(el, minLength) {
  var elMsg = document.getElementById('feedback')
  if (el.value.length < minLength) {
    elMsg.innerHTML = 'Not long enough';
  } else {
    elMsg.innerHTML = ' ';
  }
}

var el = document.getElementById('username');
el.addEventListener('blur', function(){
  checkUsername(el, 5);
}, false);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,739评论 2 17
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,061评论 1 10
  • 问答 一、dom对象的innerText和innerHTML有什么区别? innerTextinnerText是一...
    婷楼沐熙阅读 403评论 0 0
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,048评论 0 29
  • 一支芦苇 摇曳在池里 风来 拔韧着你的根蒂 无意像浮萍 绿的娇艳 却随波浮沉淡起 一支芦苇 摇曳在池里 雨来 涤荡...
    素心微凉阅读 237评论 0 3