一、事件
1.基本概念
??JavaScript中的很多代码,都是通过“事件”来触发的。
??事件就是浏览器对于用户的操作行为进行的一个统称。用户对于页面的一些操作(点击, 选择, 修改等) 操作都会在浏览器中产生一个个事件, 被 JS 获取到, 从而进行更复杂的交互操作。
??例如,鼠标在页面上移动,就会产生一个鼠标移动事件; ??例如,鼠标在页面某个位置点击,就会产生一个鼠标点击事件.再例如,鼠标滚轮,来滚动页面,就会产生一组滚动事件; ??例如,用户按下键盘的某个按键,也会产生一个键盘事件; ??例如,用户修改浏览器窗口大小,也会产生一个窗口大小改变事件。
2.事件三要素
- 事件源: 哪个元素触发的
- 事件类型: 是点击, 选中, 还是修改?
- 事件处理程序: 当事件产生之后,执行什么样的JavaScript代码。这里往往是一个回调函数。
示例一:
<div>
<button id = "btn">我是一个按钮</button>
</div>
<script>
let btn = document.getElementById('btn');
btn.onclick = function(){
alert("hello world");
}
</script>
- btn 按钮就是事件源.
- 点击就是事件类型。
- f- unction 这个匿名函数就是事件处理程序
- 其中 btn.onclick = function() 这个操作称为 注册事件/绑定事件
??这个匿名函数相当于一个回调函数, 这个函数不需要程序猿主动来调用, 而是交给浏览器, 由浏览器自动在合适的时机(触发点击操作时) 进行调用
?
?
二、操作元素
操作 = 获取 + 修改
操作元素,主要有以下三种:
- 操作元素内容
- 操作元素属性
- 操作元素样式
1.操作元素内容
1.1.innerText
Element.innerText 属性表示一个节点及其后代的“渲染”文本内容
var renderedText = HTMLElement.innerText;
HTMLElement.innerText = string;
示例:
<div>
<span>hello world</span>
<span>hello world</span>
</div>
<script>
let div = document.querySelector('div');
console.log(div.innerText);
div.innerText = 'hello js <span>hello js</span>';
</script>
??可以看到, 通过 innerText 无法获取到 div 内部的 html 结构, 只能得到文本内容.修改页面的时候也会把 span 标签当成文本进行设置。
1.2.innerHTML
Element.innerHTML 属性设置或获取HTML语法表示的元素的后代。
var content = element.innerHTML;
element.innerHTML = htmlString;
- 先获取到事件源的元素
- 注册事件
示例一:
<div>
<span>hello world</span>
<span>hello world</span>
</div>
<script>
var div = document.querySelector('div');
console.log(div.innerHTML);
div.innerHTML = '<span>hello js</span>'
</script>
??可以看到 innerHTML 不光能获取到页面的 html 结构, 同时也能修改结构. 并且获取到的内容保留的空格和换行。
示例二:获取与修改内容
<div id = "screen">
<ul>
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</ul>
</div>
<button id = "btn">获取内容按钮</button>
<button id = "btn2">修改内容按钮</button>
<script>
let btn = document.querySelector('#btn');
btn.onclick = function(){
let screen = document.querySelector('#screen');
console.log(screen.innerHTML);
}
let btn2 = document.querySelector('#btn2');
btn2.onclick = function(){
let screen = document.querySelector('#screen');
screen.innerHTML = '<h1>修改后的内容</h2>';
}
</script>
? 示例三:显示数字
<div id = "screen">0</div>
<button id = "plus">+</button>
<script>
let plusBtn = document.querySelector('#plus');
plusBtn.onclick = function(){
let screen = document.querySelector('#screen');
let val = screen.innerHTML;
val = parseInt(val);
val += 1;
screen.innerHTML = val;
}
</script>
?
?
2.操作元素属性
可以通过dom的 Element 对象的属性来直接修改, 就能影响到页面显示效果.
<img src="pic.jpg" alt="图片">
<script>
let img = document.querySelector('img');
img.onclick = function(){
console.log(img.src);
}
</script>
我们可以在代码中直接通过这些属性来获取属性的值:
<img src="pic.jpg" alt="图片">
<script>
let img = document.querySelector('img');
console.log(img.src);
console.log(img.alt);
</script>
直接修改属性:点击图片就切换
<img src="pic.jpg" alt="图片">
<script>
let img = document.querySelector('img');
img.onclick = function(){
console.dir(img.src);
if(img.src.indexOf('pic.jpg') >= 0){
img.src = 'pic1.jpg';
}else if(img.src.indexOf('pic1.jpg')){
img.src = 'pic.jpg';
}
}
</script>
?
?
3.获取/修改表单元素属性
表单(主要是指 input 标签)的以下属性都可以通过 DOM 来修改
- value: input 的值.
- disabled: 禁用
- checked: 复选框会使用
- selected: 下拉框会使用
- type: input 的类型(文本, 密码, 按钮, 文件等)
(1)示例一:切换按钮的文本:假设这是个播放按钮, 在 “播放” - “暂停” 之间切换。
<input type="button" value = "播放">
<script>
let btn = document.querySelector('input');
btn.onclick = function(){
if(btn.value == '播放'){
btn.value = '暂停';
}else{
btn.value = '播放';
}
}
</script>
(2)点击计算(这个例子第二篇文章讲过)
- 使用一个输入框输入初始值(整数). 每次点击按钮, 值 + 1。
<input type="text" id = "text" value="0">
<input type="button" id = "btn" value='点击+1'>
<script>
let text = document.querySelector('#text');
let btn = document.querySelector('#btn');
btn.onclick = function(){
let num = text.value;
console.log(num);
num++;
text.value = num;
}
</script>
- input 具有一个重要的属性 value, 这个 value 决定了表单元素的内容
- 如果是输入框, value 表示输入框的内容, 修改这个值会影响到界面显式; 在界面上修改这个值也会影响到代码中的属性
- 如果是按钮, value 表示按钮的内容. 可以通过这个来实现按钮中文本的替换
?
(3)全选/取消全选按钮
- 点击全选按钮, 则选中所有选项
- 只要某个选项取消, 则自动取消全选按钮的勾选状态
<script>
let all = document.querySelector('#all');
let girls = document.querySelectorAll('.girl');
all.onclick = function(){
for(let i =0;i<girls.length;i++){
girls[i].checked = all.checked;
}
}
for(let i =0; i < girls.length; i++){
girls[i].onclick = function(){
all.checked = checkGirls(girls);
}
}
function checkGirls(girls){
for(let i =0;i<girls.length;i++){
if(!girls[i].checked){
return '';
}
}
return 'checked';
}
</script>
?
?
4.获取/修改样式属性
CSS 中指定给元素的属性, 都可以通过 JS 来修改
4.1.行内样式操作
element.style.[属性名] = [属性值];
element.style.cssText = [属性名+属性值];
“行内样式”, 通过 style 直接在标签上指定的样式. 优先级很高. 适用于改的样式少的情况
示例:点击文字则放大字体
<div style="font-size: 20px; font-weight: 600;">姑苏城外寒山寺,夜半钟声到客船</div>
<script>
let div = document.querySelector('div');
div.onclick = function(){
console.log(div.style.fontSize);
let fontSize = parseInt(div.style.fontSize);
fontSize += 5 ;
div.style.fontSize = fontSize + 'px';
}
</script>
- style 中的属性都是使用 驼峰命名 的方式和 CSS 属性对应的例如: font-size => fontSize, background-color => backgroundColor 等这种方式修改只影响到特定样式, 其他内联样式的值不变。
?
4.2.类名样式操作
element.className = [CSS 类名];
修改元素的 CSS 类名. 适用于要修改的样式很多的情况. 由于 class 是 JS 的保留字, 所以名字叫做 className
示例:开启夜间模式
- 点击页面切换到夜间模式(背景变成黑色)
- 再次点击恢复日间模式(背景变成白色)
<style>
.light{
background-color: #fff;
color: #000;
}
.dark{
background-color: #000;
color: #fff;
}
</style>
<div class="light" style="height: 500px;">夜半钟声到客船</div>
<button>关灯</button>
<script>
let div = document.querySelector('div');
let button = document.querySelector('button');
button.onclick = function(){
if(div.className == 'light'){
div.className = 'dark';
button.innerHTML = '开灯';
}else if(div.className == 'dark'){
div.className = 'light';
button.innerHTML = '关灯';
}
}
</script>
?
?
三、操作节点
1.新增节点
分成两个步骤
- 创建元素节点
- 把元素节点插入到 dom 树中
?
(1) 创建元素节点
使用 createElement 方法来创建一个元素。
var element = document.createElement(tagName[, options]);
示例:
<div class="container">
</div>
<script>
let div = document.createElement('div');
div.id = 'mydiv';
div.className = 'box';
div.innerHTML = 'hehe';
console.log(div);
</script>
此时发现, 虽然创建出新的 div 了, 但是 div 并没有显示在页面上. 这是因为新创建的节点并没有加入到DOM 树中。
上面介绍的只是创建元素节点, 还可以使用:
- createTextNode 创建文本节点
- createComment 创建注释节点
- createAttribute 创建属性节点
我们以 createElement 为主即可。
?
(2)插入节点到 dom 树中
第一步:使用 appendChild 将节点插入到指定节点的最后一个孩子之后。
element.appendChild(aChild)
<div class="container">
</div>
<script>
let newDiv = document.createElement('div');
newDiv.id = 'newdiv';
newDiv.className = 'one';
newDiv.innerHTML = 'hehe';
console.log(newDiv);
let container = document.querySelector('.container');
container.appendChild(newDiv);
</script>
第二步:使用 insertBefore 将节点插入到指定节点之前
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
- insertedNode 被插入节点(newNode)
- parentNode 新插入节点的父节点
- newNode 用于插入的节点
- referenceNode newNode 将要插在这个节点之前
如果 referenceNode 为 null 则 newNode 将被插入到子节点的末尾。
- 注意: referenceNode 引用节点不是可选参数
<div class="container">
<div>11</div>
<div>22</div>
<div>33</div>
<div>44</div>
</div>
<script>
var newDiv = document.createElement('div');
newDiv.innerHTML = '我是新的节点';
var container = document.querySelector('.container');
console.log(container.children);
container.insertBefore(newDiv, container.children[0]);
</script>
?
注意1: 如果针对一个节点插入两次, 则只有最后一次生效(相当于把元素移动了)
<div class="container">
<div>11</div>
<div>22</div>
<div>33</div>
<div>44</div>
</div>
<script>
var newDiv = document.createElement('div');
newDiv.innerHTML = '我是新的节点';
var container = document.querySelector('.container');
console.log(container.children);
container.insertBefore(newDiv, container.children[0]);
container.insertBefore(newDiv, container.children[2]);
</script>
?
注意2: 一旦一个节点插入完毕, 再针对刚刚的节点对象进行修改, 能够同步影响到 DOM 树中的内容。
<div class="container">
<div>11</div>
<div>22</div>
<div>33</div>
<div>44</div>
</div>
<script>
var newDiv = document.createElement('div');
newDiv.innerHTML = '我是新的节点';
var container = document.querySelector('.container');
console.log(container.children);
container.insertBefore(newDiv, container.children[0]);
newDiv.innerHTML = '我是新节点2';
</script>
?
?
2.删除节点
使用 removeChild 删除子节点。
oldChild = element.removeChild(child);
- child 为待删除节点
- element 为 child 的父节点
- 返回值为该被删除节点
- 被删除节点只是从 dom 树被删除了, 但是仍然在内存中, 可以随时加入到 dom 树的其他位置。
- 如果上例中的 child节点 不是 element 节点的子节点,则该方法会抛出异常
<div class="container">
</div>
<button>删除 div</button>
<script>
let newDiv = document.createElement('div');
newDiv.id = 'newdiv';
newDiv.className = 'one';
newDiv.innerHTML = 'hehe';
console.log(newDiv);
let container = document.querySelector('.container');
container.appendChild(newDiv);
let button = document.querySelector('button');
button.onclick = function(){
container.removeChild(newDiv);
}
</script>
?
?
四、两个示例
1.示例一:猜数字
<style>
body{
background: yellowgreen;
}
.content{
width: 500px;
height: 500px;
margin: 0 auto;
background: gold;
}
div{
width: 50%;
height: 200px;
background-color: aquamarine;
display: flex;
justify-content: center;
}
div > span{
background-color:beige;
width: 300px;
height: 200px;
}
</style>
<div>
<button id="resetBtn">重新开始</button><br>
<span>要猜的数字</span>
<input type="text" name="" id="">
<button id = "guessBtn">猜</button><br>
<span>结果:</span>
<span id="result"></span><br>
<span>已经猜的次数:</span>
<span id="guessCount"> 0</span>
</div>
<script>
let resetBtn = document.querySelector('#resetBtn');
let input = document.querySelector('input');
let guessBtn = document.querySelector('#guessBtn');
let resultSpan = document.querySelector('#result');
let guessCountSpan = document.querySelector('#guessCount');
let toGuess = Math.floor(Math.random() * 100) +1;
console.log(toGuess);
guessBtn.onclick = function(){
if(input.value == ''){
return;
}
let curNum = parseInt(input.value);
if(curNum < toGuess){
resultSpan.innerHTML = '低了';
resultSpan.style.color = 'red';
}else if(curNum > toGuess){
resultSpan.innerHTML = '高了';
resultSpan.style.color = 'red';
}else{
resultSpan.innerHTML = '猜对了';
resultSpan.style.color = 'green';
}
let guessCount = parseInt(guessCountSpan.innerHTML);
guessCountSpan.innerHTML = guessCount + 1;
}
resetBtn.onclick = function(){
location.reload();
}
</script>
?
?
2.示例二:表白墙
输入后点击提交, 会将信息显示在表格中
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container{
width: 100%;
}
h3{
text-align: center;
padding: 40px 0;
font-size: 24px;
}
p{
text-align: center;
color: #666;
padding: 10px 0;
}
.row{
width: 400px;
height: 50px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
.row span{
width: 60px;
font-size: 20px;
}
.row input{
width: 300px;
height: 40px;
line-height: 40px;
font-size: 20px;
text-indent: 0.5em;
outline: none;
}
.row #submit{
width: 300px;
height: 50px;
font-size: 20px;
line-height: 40px;
margin: 0 auto;
color: #fff;
background-color: orange;
border: none;
border-radius: 10px;
}
.row #submit:active{
background-color: #555;
}
</style>
<div class="container">
<h3>表白墙</h3>
<p>输入后点击提交,会将信息显示在表格中</p>
<div class="row">
<span>谁:</span>
<input type="text" name="" id="">
</div>
<div class="row">
<span>
对谁:
</span>
<input type="text" name="" id="">
</div>
<div class="row">
<span>说啥:</span>
<input type="text" name="" id="">
</div>
<div class="row">
<button id = "submit">提交</button>
</div>
</div>
<script>
let submitBtn = document.querySelector('#submit');
submitBtn.onclick = function(){
let inputs = document.querySelectorAll('input');
let from = inputs[0].value;
let to = inputs[1].value;
let msg = inputs[2].value;
if(from == '' || to =='' || msg == ''){
return;
}
let div = document.createElement('div');
div.innerHTML = from + '对' + to + '说:' +msg;
div.className = 'row';
let container = document.querySelector('.container');
container.appendChild(div);
for(let i = 0;i < inputs.length ;i++){
inputs[i].value = '';
}
}
</script>
?
?
??刚才咱们写的表白墙程序,是通过一些div.row来保存咱们提交的消息.这些div.row是挂在DOM树上,就是在内存中的,容易失去的.。一旦页面刷新/关闭了,此时,之前内存中保存的数据,就没了。为了解决上述的数据容易丢失问题,有以下解决方案:
-
可以把提交的数据,保存在浏览器本地。(浏览器提供了localStorage / indexDB这样的机制,能够实现本地存储),本质上,是通过浏览器,把你要存的数据,存到当前电脑的磁盘上。但是这里也有问题:就是只有我在自己的电脑上能看到,别人看不到。 -
可以把提交的数据,通过网络通信,传输给服务器.由服务器进行保存。 1)服务器保存在内存里 2)服务器保存在文件中 3)服务器保存在数据库里
?
? 完!
|