目录
修改样式属性
-
通过 JS 修改元素的大小、颜色、位置等样式
-
element.style:行内样式操作
-
element.className:类名样式操作
行内样式操作
- JS 里面的样式采取驼峰命名法。比如 fontSize、backgroundColor
- JS 修改 style 样式操作,产生的是行内样式,行内样式的 css 权重比较高
<style>
div {
width: 250px;
height: 250px;
background-color: aquamarine;
}
</style>
<body>
<div></div>
<script>
var div = document.querySelector('div');
var flag = 0;
div.onclick = function() {
if (flag == 0) {
// div.style里面的属性采取驼峰命名法
// 且行内样式操作赋值不是 style 中的 ':', 而是 '='
this.style.backgroundColor = 'darkcyan';
this.style.width = '200px';
this.style.height = '200px';
flag = 1;
} else {
this.style.backgroundColor = 'red';
this.style.width = '250px';
this.style.height = '250px';
flag = 0;
}
}
</script>
</body>
仿淘宝关闭二维码案例
- 核心思路:利用样式的显示和隐藏完成
- display: none; 隐藏元素;display: block; 显示元素
<style>
.box {
position: relative;
width: 88px;
height: 88px;
border: 1px solid #ccc;
margin: 100px auto;
font-size: 12px;
text-align: center;
color: #f40;
}
.box img {
width: 60px;
margin-top: 5px;
}
.close-btn {
position: absolute;
top: -1px;
left: -16px;
width: 14px;
height: 14px;
border: 1px solid #ccc;
line-height: 14px;
font-family: Arial, Helvetica, sans-serif;
cursor: pointer;
}
</style>
<body>
<div class="box">
淘宝二维码
<img src="images/tao.png" alt="">
<i class="close-btn">×</i>
</div>
<script>
// var box = document.getElementsByClassName('box');
// 上述语句不能使用,无法进行事件处理
var box = document.querySelector('.box');
var img = document.querySelector('img');
var btn = document.querySelector('.close-btn');
btn.onclick = function() {
// this 指向的是事件函数的调用者 btn
box.style.display = 'none';
}
</script>
</body>
循环精灵图案例
- 利用 for 循环设置一组元素的精灵图背景
案例分析
- 首先精灵图图片排列是有规律的
- 核心思路:利用 for 循环,修改精灵图片的背景位置 background-position
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
.box {
width: 250px;
margin: 100px auto;
}
.box li {
float: left;
width: 24px;
height: 24px;
background-color: darkcyan;
margin: 15px;
background: url(images/sprite.png) no-repeat;
}
</style>
<script>
var box = document.querySelector('.box');
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
var index = i * 44;
lis[i].style.backgroundPosition = '0 -' + index + 'px';
}
</script>
显示隐藏文本框内容
- 当鼠标点击文本框时,里面的默认文字隐藏
- 当鼠标离开文本框时,里面的文字显示
案例分析
- 首先表单需要 2 个新事件,获得焦点 onfocus,失去焦点 onblur
- 如果获得焦点,判断表单内容是否为默认文字。如果是,清空表单内容
- 如果失去焦点,判断表单内容是否为空。如果为空,则表单内容改为默认文字
<body>
<input type="text" value="手机">
<script>
var text = document.querySelector('input');
// 注册事件 获得焦点事件 onfocus
text.onfocus = function() {
// console.log('得到焦点');
if (this.value === '手机') {
this.value = '';
}
// 获得焦点,文字颜色变深
this.style.color = 'black';
}
// 注册事件 失去焦点事件 onblur
text.onblur = function() {
// console.log('失去焦点');
// if () 中的判断条件为全等
if (this.value === '') {
// 条件为真,执行语句为赋值
this.value = '手机';
}
// 失去焦点,文字颜色变浅
this.style.color = '#999';
}
</script>
</body>
类名样式操作
- element.className
注意
- 如果样式修改较多,可以采取操作类名方式更改元素样式
- class 是保留字,因此经常使用 className 来操作元素类名属性
- className 会直接更改元素的类名,并覆盖原先的类名
- 如果想要保留原先的类名,可以借助多类名选择器
-
this.className = '原先的类名 更改的类名';
<style>
div {
width: 100px;
height: 100px;
background-color: darkkhaki;
}
.change {
text-align: center;
line-height: 100px;
background-color: darkcyan;
color: #fff;
font-size: 20px;
margin-top: 100px;
}
</style>
<body>
<div class="first">文本内容</div>
<script>
// 使用 element.style 获得修改元素样式
// 在需要修改的样式比较少 或者 功能简单的情况下使用
var text = document.querySelector('div');
text.onclick = function() {
// this.style.textAlign = 'center';
// this.style.lineHeight = '100px';
// this.style.backgroundColor = 'darkcyan';
// this.style.color = '#fff';
// this.style.fontSize = '20px';
// this.style.marginTop = '100px';
// 通过修改元素的 className 更改元素的样式
// 在需要修改的样式较多 或者 需要实现的功能复杂的情况下使用
// 将当前元素的类名改为 change
this.className = 'change';
// 如果想要保留原先的类名,多类名选择器
this.className = 'first change';
}
</script>
</body>
密码框验证信息
案例分析
- 首先判断的事件是表单失去焦点 onblur
- 如果输入符合格式,提示正确的信息,图标变为绿色小图标
- 如果输入不是 6 到 16 位,提示错误信息,图标变为红色小图标
- 因为里面变化样式较多,采取 className 修改样式
<style>
div {
width: 600px;
margin: 100px auto;
}
.message {
display: inline-block;
font-size: 12px;
color: #999;
background: url(images/mess.png) no-repeat left center;
padding-left: 20px;
}
.wrong {
color: red;
background-image: url('images/wrong.png');
}
.right {
color: green;
background-image: url('images/right.png');
}
</style>
<body>
<div class="register">
<input type="text" class="ipt">
<p class="message">请输入 6~16 位密码</p>
</div>
<script>
var ipt = document.querySelector('.ipt');
var message = document.querySelector('.message');
ipt.onblur = function() {
// 根据表单中值的长度 ipt.value.length
if (ipt.value.length < 6 || ipt.value.length > 16) {
// 不能直接 message.className = 'wrong'; 因为还需要 message 中的某些样式
message.className = 'message wrong';
message.innerHTML = '输出错误,请输入6~16位字符';
} else {
message.className = 'message right';
message.innerHTML = '输入正确'
}
}
</script>
</body>
操作元素总结
- 操作元素是 DOM 核心内容
- 以下属性都是可读写的
- 如果给这些属性一个值,就实现了 赋值操作
操作元素内容
- innerText
- innerHTML
操作常见元素属性
- src、href、title、alt 等
操作表单元素属性
- type、value、disabled 等
操作元素样式属性
- element.style
- className
练习
- 用户名显示隐藏内容
- 京东关闭广告
- 新浪下拉菜单
- 开关灯案例
排他思想(算法)
- 让一组按钮都绑定点击事件
在一组相同的标签中,想让某一个元素实现某种样式,需要用到循环的排他算法:
- 所有元素全部清除样式(干掉所有人)
- 给当前元素添加样式(留下自己)
- 注意顺序不能颠倒,首先干掉所有人,再设置自己
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
// 获取所有的按钮元素
var btns = document.getElementsByTagName('button');
// btns 得到的是伪数组,里面的每一个元素 btn[i]
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function() {
// 1.点击按钮之前,去掉所有按钮的样式
for (var i = 0; i < btns.length; i++) {
btns[i].style.backgroundColor = '';
}
// 2.然后再给当前的按钮添加样式
this.style.backgroundColor = 'darkcyan';
}
}
</script>
</body>
百度换肤效果案例
案例分析
- 给一组元素注册事件
- 给四个小图片利用循环注册点击事件
- 当点击了某个图片,页面背景就改为当前图片
- 核心算法:将当前图片的路径取出来,给 body 做背景
<style>
* {
margin: 0;
padding: 0;
}
body {
background: url(images/1.jpg) no-repeat center top;
}
li {
list-style: none;
}
.baidu {
margin: 100px auto;
background-color: #fff;
width: 410px;
padding-top: 3px;
}
.baidu li {
float: left;
margin: 0 1px;
cursor: pointer;
}
.baidu img {
width: 100px;
}
</style>
<body>
<ul class="baidu">
<li><img src="images/1.jpg" alt=""></li>
<li><img src="images/2.jpg" alt=""></li>
<li><img src="images/3.jpg" alt=""></li>
<li><img src="images/4.jpg" alt=""></li>
</ul>
<script>
// 获取元素
var imgs = document.querySelector('.baidu').querySelectorAll('img');
for (var i = 0; i < imgs.length; i++) {
imgs[i].onclick = function() {
// 点击图片的路径 this.src
// 将此路径给 body
document.body.style.backgroundImage = 'url(' + this.src + ')';
}
}
</script>
</body>
表格隔行变色效果
案例分析
- 新的鼠标事件:鼠标经过 onmouseover,鼠标离开 onmouseout
- 核心思路:鼠标经过 tr 行,当前行更换背景颜色;鼠标离开,恢复原来的背景颜色
- 注意:第一行(thead 里面的行)不需要更换颜色;因此,获取的是 tbody 里面的行
<script>
// 获取元素,获取的是 tbody 中所有的行
var trs = document.querySelector('tbody').querySelectorAll('tr');
// 利用循环注册事件
for (var i = 0; i < trs.length; i++) {
// 鼠标经过事件
trs[i].onmouseover = function() {
this.className = 'bgc';
}
// 鼠标离开事件 onmouseout
trs[i].onmouseout = function() {
this.className = '';
}
}
</script>
表单全选取消全选案例
案例分析
- 全选和取消全选做法:让下面复选框的 checked 属性(选中状态)跟随全选按钮
- 下面的复选框需要全部选中,上面的全选框才能选中:给下面所有的复选框绑定点击事件;每次点击,都要循环查看下面所有的复选框是否有没选中的;如果有一个没选中,上面的全选就不选中
<script>
// 全选和取消全选
// 获取元素
var j_cbAll = document.getElementById('j_cbAll');
var j_tbs = document.getElementById('j_tb').querySelectorAll('input');
// 注册事件
j_cbAll.onclick = function() {
// this.checked; 可以得到当前复选框的选中状态
// 如果选中,为 true;如果未选中,为 false
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].checked = this.checked;
}
}
// 下面的复选框需要全部选中,上面的全选框才会选中
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].onclick = function() {
// flag 控制全选框是否被选中
var flag = true;
// 每次点击下面的复选框都需要循环检查四个复选框是否都被选中
for (var i = 0; i < j_tbs.length; i++) {
// 如果有复选框未被选中,全选框 checked 为 false
if (!j_tbs[i].checked) {
// j_cbAll.checked = false;
flag = false;
break; // 跳出 for 循环,只要有一个未选中,剩下的就不继续循环
}
}
j_cbAll.checked = flag;
}
}
</script>
自定义属性的操作
获取属性值
- element.属性
- element.getAttribute('属性');
区别
- element.属性:获取内置属性值(元素本身自带的属性)
- element.getAttribute('属性'); :主要获得自定义的属性(标准),程序员自行添加的属性
<body>
<!-- div 为元素,id 和 index 都为 div 元素的属性 -->
<div id="demo" index="1"></div>
<script>
var div = document.querySelector('div');
// 获取元素的属性值
// 1.element.属性
console.log(div.id); // demo
// 2.element getAttribute('属性') attribute 属性
// 程序员自行添加的属性 如:index
console.log(div.getAttribute('index')); // 1
</script>
</body>
设置属性值
- element.属性 = '值'
- element.setAttribute('属性', '值');
区别
- element.属性:设置内置属性值
- element.setAttribute('属性'); : 主要设置自定义的属性(标准)
<body>
<!-- div 为元素 element,id 和 index 都为 div 元素的属性 -->
<div id="demo" index="1" class="nav"></div>
<script>
// 设置属性值
// 1.element.属性='属性值';
div.id = 'test';
div.className = 'navs';
// element.setAttribute('属性', '属性值');
// 主要针对自定义属性
div.setAttribute('index', 0);
// class 特殊,注意'属性' = class,而不是 className
div.setAttribute('class', 'nava');
// <div id="test" index="0" class="nava"></div>
</script>
</body>
移除属性
- element.removeAttribute('属性');
<body>
<!-- div 为元素 element,id 和 index 都为 div 元素的属性 -->
<div id="demo" index="1" class="nav"></div>
<script>
// 移除属性
// element.removeAttribute('属性');
div.removeAttribute('index');
// <div id="test" class="nava"></div>
</script>
</body>
tab 栏切换(重点案例)
- 当鼠标点击上面相应的选项卡(tab),下面的内容跟随变化
案例分析
- tab 切换有两个大的模块
- 上面的模块选项卡,点击某一个,当前选项卡的背景颜色变为红色,其他不变(排他思想),修改类名的方式
- 下面的模块内容,会跟随上面的选项卡变化。所以下面模块变化应写到点击事件中
- 规律:下面的模块显示内容和上面的选项卡一一对应,相匹配
- 核心思路:给 tab_list 里面的所有 li 添加自定义属性,属性值从 0 开始
- 当我们点击 tab_list 里面的某个 li ,让 tab_con 里面对应序号的内容显示,其余隐藏(排他思想)
<body>
<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格和包装</li>
<li>售后保障</li>
<li>商品评价(5000+)</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab_con">
<div class="item">商品介绍模块内容</div>
<div class="item">规格与包装模块内容</div>
<div class="item">售后保障模块内容</div>
<div class="item">商品评价(5000+)模块内容</div>
<div class="item">手机社区模块内容</div>
</div>
</div>
<script>
// 获取元素
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
var items = document.querySelectorAll('.item');
// for 循环绑定点击事件
for (var i = 0; i < lis.length; i++) {
// 最开始就给 li 设置索引号
lis[i].setAttribute("index", i);
lis[i].onclick = function() {
// 干掉所有人
for (var i = 0; i < lis.length; i++) {
lis[i].className = '';
}
// 设置自己
this.className = 'current';
// 下面模块内容显示
var index = this.getAttribute('index');
// 干掉所有人
for (var i = 0; i < items.length; i++) {
items[i].style.display = 'none';
}
items[index].style.display = 'block';
}
}
</script>
</body>
H5 自定义属性
自定义属性目的:保存并使用数据
- 某些数据可以直接保存到页面中而不用保存到数据库中
- 自定义属性通过 getAttribute('属性') 获取
- 但有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性
- H5 新增了自定义属性
设置 H5 自定义属性
- H5 规定凡是以 data- 开头作为属性名并赋值的都是自定义属性
- 比如 <div data-index = "1"></div>
- 或者使用 JS 设置
- element.setAttribute('data-index', 2)
获取 H5 自定义属性
- 兼容性获取:element.getAttribute('data-index');
- H5 新增 element.dataset.index 或者 element.dataset['index']。IE11 才开始支持
<body>
<div getTime="20" data-index="0"></div>
<script>
var div = document.querySelector('div');
// 通过 getAttribute() 获取自定义属性
console.log(div.getAttribute('getTime'));
// 设置自定义属性
// 通过 setAttribute() 设置自定义属性
div.setAttribute('data-time', 20);
// 获取 H5 自定义属性
// 1.兼容性获取自定义属性
console.log(div.getAttribute('data-index'));
// 2.H5 新增的获取自定义属性的方法
// 只能获取 data- 开头的属性
console.log(div.dataset.index);
console.log(div.dataset['index']);
// dataset 是一个集合,里面存放了所有以 data 开头的自定义属性
console.log(div.dataset); // DOMStringMap {index: "0", time: "20"}
// 若新增属性名为 多个字符和 两个以上的 '-'或者'_' 等类似字符连接
// 使用 dataset.属性 获取时,应该去掉字符,并用驼峰命名法获取
div.setAttribute('data-list-name', 'age');
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
</script>
</body>
总结
获取元素的自定义属性有两种方法
1. element.getAttribute('属性')
- 兼容性好
2. element.dataset.index 或者 element.dataset['index']
- IE11 才开始支持
- 只能获取 data- 开头的自定义属性
- dataset 是一个集合,里面存放了该元素所有以 data- 开头的自定义属性
- 当新增属性名为 多个字符与两个以上的 '_' 或者 '-' 等类似字符连接时,如 data-list-name
- 使用 dataset 获取元素时,属性名应该去掉这些连接符,并使用驼峰命名法