# 通过事件操作 DOM
# 课程目标
掌握 JavaScript 事件的概念,并能写出基本的事件相关的代码 掌握如何通过 JavaScript 操作 DOM 的样式 熟悉 DOM 事件相关知识
# 事件机制
# 阅读
首先学习了解 JavaScript 事件的知识
- W3School 事件 (opens new window)
- MDN 事件 (opens new window)
- HTML DOM Text 对象 (opens new window)
- HTML DOM Button 对象 (opens new window)
- JavaScript 事件参考手册 (opens new window)
- 初步理解 JS 的事件机制 (opens new window)
- js 中的事件委托或是事件代理详解 (opens new window)
- 关于 JS 事件冒泡与 JS 事件代理(事件委托) (opens new window)
- JavaScript 事件代理和委托 (opens new window)
- 事件节流 (opens new window)
- 事件防抖 (opens new window)
- javascript 事件代理 (opens new window)
# 编码
我们来继续用封装自己的小 jQuery 库来实现我们对于 JavaScript 事件的学习,还是在你的 util.js ,实现以下函数
// 给一个element绑定一个针对event事件的响应,响应函数为listener
function addEvent(element, event, listener) {
// your implement
}
// 例如:
function clicklistener(event) {
...
}
addEvent($("#doma"), "click", a);
// 移除element对象对于event事件发生时执行listener的响应
function removeEvent(element, event, listener) {
// your implement
}
接下来我们实现一些方便的事件方法
// 实现对click事件的绑定
function addClickEvent(element, listener) {
// your implement
}
// 实现对于按Enter键时的事件绑定
function addEnterEvent(element, listener) {
// your implement
}
接下来我们把上面几个函数和 $ 做一下结合,把他们变成 $ 对象的一些方法
- addEvent(element, event, listener) -> $.on(element, event, listener);
- removeEvent(element, event, listener) -> $.un(element, event, listener);
- addClickEvent(element, listener) -> $.click(element, listener);
- addEnterEvent(element, listener) -> $.enter(element, listener);
接下来考虑这样一个场景,我们需要对一个列表里所有的<li>
增加点击事件的监听
最笨的方法
<ul id="list">
<li id="item1">Simon</li>
<li id="item2">Kenner</li>
<li id="item3">Erik</li>
</ul>
function clickListener(event) {
console.log(event);
}
$.click($("#item1"), clickListener);
$.click($("#item2"), clickListener);
$.click($("#item3"), clickListener);
上面这段代码要针对每一个 item 去绑定事件,这样显然是一件很麻烦的事情。
稍微好一些的
<ul id="list">
<li>Simon</li>
<li>Kenner</li>
<li>Erik</li>
</ul>
我们试图改造一下
function clickListener(event) {
console.log(event);
}
each($("#list").getElementsByTagName("li"), function(li) {
addClickEvent(li, clickListener);
});
我们通过自己写的函数,取到 id 为 list 这个 ul 里面的所有 li ,然后通过遍历给他们绑定事件。这样我们就不需要一个一个去绑定了。但是看看以下代码:
<ul id="list">
<li id="item1">Simon</li>
<li id="item2">Kenner</li>
<li id="item3">Erik</li>
</ul>
<button id="btn">Change</button>
function clickListener(event) {
console.log(event);
}
function renderList() {
// bca-disable-line
$("#list").innerHTML = '<li>new item</li>';
}
function init() {
each($("#list").getElementsByTagName('li'), function(item) {
$.click(item, clickListener);
});
$.click($("#btn"), renderList);
}
init();
我们增加了一个按钮,当点击按钮时,改变 list 里面的项目,这个时候你再点击一下 li ,绑定事件不再生效了。那是不是我们每次改变了 DOM 结构或者内容后,都需要重新绑定事件呢?当然不会这么笨,接下来学习一下事件代理,然后实现下面新的方法:
// 先简单一些
function delegateEvent(element, tag, eventName, listener) {
// your implement
}
$.delegate = delegateEvent;
// 使用示例
// 还是上面那段HTML,实现对list这个ul里面所有li的click事件进行响应
$.delegate($("#list"), "li", "click", clickHandle);
估计有同学已经开始吐槽了,函数里面一堆 $ 看着晕啊,那么接下来把我们的事件函数做如下封装改变:
$.on(selector, event, listener) {
// your implement
}
$.click(selector, listener) {
// your implement
}
$.un(selector, event, listener) {
// your implement
}
$.delegate(selector, tag, event, listener) {
// your implement
}
// 使用示例:
$.click("[data-log]", logListener);
$.delegate('#list', "li", "click", liClicker);
# JavaScript 操作 DOM 样式
# 阅读
接下来学习如何用 JavaScript 操作 DOM 样式
- W3School 样式 (opens new window)
- W3School HTML DOM Style 对象 (opens new window)
- javascript 动态修改 css 样式方法汇总(四种方法) (opens new window)
- cssText 的用法以及特点 (opens new window)
- JavaScript 之 ClassName 属性学习 (opens new window)
- DOM 事件探秘 (opens new window)
# 编码一
接下来我们练习一下通过 JavaScript 完成 DOM 节点的增加和删除,以及样式的控制。
参考 示例 DEMO (opens new window) 编码实现一个简易 TODO 待办管理小工具
<h1>Todo List</h1>
<form id="form">
<input type="text" class="input" id="input" placeholder="Enter your todo" autocomplete="off">
<ul class="todos" id="todos"></ul>
</form>
需求说明
- 用户在输入框中输入要做的任务,键盘按回车,在输入框下方,id 为
tidos
的 ul 中添加一条表示任务 li 元素 - 鼠标点击任务 li 元素,表示任务已经完成。相应样式变化:划掉任务,字体颜色也相应变成浅色
# 编码二
参考 示例 Demo (opens new window) 编码实现一个轮播图.
需求说明
- 图片数量及 URL 均在 HTML 中写好
- 可以配置轮播的顺序(正序、逆序)、是否循环、间隔时长
- 图片切换的动画要流畅
- 在轮播图下方自动生成对应图片的小点,点击小点,轮播图自动动画切换到对应的图片
# 编码三
使用 JavaScript 来实现一个简易的颜色选择器,在页面中以矩阵的方式显示数个颜色,当鼠标点击到某个颜色格子上时,改变页面背景为该色块的颜色
<p oncilck="showColorPicker()">改变背景颜色</p>;
function showColorPicker() {
//JS动态生成含有729个色块,rgb值间隔为32的颜色选择器
}
需求说明
- 在页面中使用 JavaScript 生成一个颜色选择器,按顺序产生颜色矩阵
- 生成颜色时,分别在 RGB 项上以 32 为间隔,从 RGB(0, 0, 0) 遍历到 RGB(255, 255, 255),共生成 729 个颜色格子
- 当鼠标移动到某个颜色格子上是,在页面某个地方显示三个数字,分别为当前鼠标选中颜色的 RGB 值
- 示例 DEMO 仅作参考,css 样式背景颜色边框等可以按照自己的审美自行调整
- 不使用任何第三方的布局或样式库
- 不使用任何第三方的 JavaScript 库
# W3C
# 阅读
最后,可以通过阅读标准,加深理解。
# 提交
把你今天觉得做得最好的代码放在 Github 后进行提交。
# 总结
依然把今天的学习用时,收获,问题进行记录。
# 自测问题
我们有一个空的 DOM 元素 elem 和一个字符串 text。
下面这 3 个命令中的哪个命令做的是完全相同的事儿?
/* bca-disable */
elem.append(document.createTextNode(text))
elem.innerHTML = text
elem.textContent = text