DOM(二):几个NB案例、属性操作(自定义属性)、tab栏切换(重难点)

本文通过具体案例详细介绍了前端JavaScript的应用技巧,包括按钮高亮、浏览器换肤、表格隔行变色等功能实现方法,并深入探讨了全选框和复选框的逻辑处理。此外,文章还讲解了自定义属性及H5自定义属性的使用。
摘要由CSDN通过智能技术生成

一、几个案例:

案例1:如何实现点击一个按钮亮,其余按钮全灭?

这里用到排他思想的算法,也就是点击一个按钮,先把所有的按钮变成原来的颜色,然后再把当前点击的按钮变成亮色。这里用到两个for循环,要好好体会一下。

	<!-- 如何实现点击一个按钮亮,其余按钮全灭? -->
	<button>按钮1</button>
	<button>按钮2</button>
	<button>按钮3</button>
	<button>按钮4</button>
	<button>按钮5</button>
	
	<script>
	    //通过for循环首先给所有的按钮点击事件
	    var btns = document.getElementsByTagName('button');
	    //上面返回的是伪数组,我们对其遍历
	    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
	            this.style.backgroundColor = 'pink';
	        }
	    }
	</script>

案例2:浏览器换肤效果

思路:点击某个图片,把该图片的地址赋给body
这里的几个注意点:
1.body元素和html元素的获取方法,要多复习复习
2.给多个相同元素添加事件可以用for循环
3.修改样式,赋值要加引号,如果其中有变量,要单独拿出来,用+拼接就欧了

   * {
        box-sizing: border-box;
    }

    body {
        background: url(./images/1.jpg) no-repeat center top;
    }

    .box {
        text-align: center;
        width: 600px;
        height: 112px;
        line-height: 50px;
        margin: 200px auto;
        border: 1px solid #ccc;
    }

    .box img {
        margin: 5px 0;
        padding: 0 5px;
        float: left;
        width: 25%;
        height: 90%;
        border: 1px solid transparent;
    }

    .box img:hover {
        border: 1px solid red;
    }
	<div class="box">
	    <img src="./images/1.jpg" alt="">
	    <img src="./images/2.jpg" alt="">
	    <img src="./images/3.jpg" alt="">
	    <img src="./images/4.jpg" alt="">
	</div>
	<script>
	    var imgs = document.querySelector('.box').querySelectorAll('img');
	    var body = document.body;
	    for (var i = 0; i < imgs.length; i++) {
	        imgs[i].onclick = function () {
	            // 别忘了获取body元素的方法,document.body
	            body.style.backgroundImage = 'url(' + this.src + ')';
	        }
	    }
	</script>

案例3:表格隔行变色

其实这个效果类似css的hover
1.用到的事件:鼠标经过onmouseover,鼠标离开onmouseout
2.核心思路:鼠标经过当前行,背景颜色改变,鼠标离开当前行就去掉背景颜色
代码:

<table>
    <thead>
        <tr>
            <th>名字</th>
            <th>性别</th>
            <th>年龄</th>
            <th>身高</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>张三</td>
            <td></td>
            <td>21</td>
            <td>185cm</td>
        </tr>
        <tr>
            <td>张三</td>
            <td></td>
            <td>21</td>
            <td>185cm</td>
        </tr>
        <tr>
            <td>张三</td>
            <td></td>
            <td>21</td>
            <td>185cm</td>
        </tr>
    </tbody>
</table>

<script>
    var trs = document.querySelector('tbody').querySelectorAll('tr');
    for (var i = 0; i < trs.length; i++) {
        //css的hover效果
        trs[i].onmouseover = function () {
            this.style.backgroundColor = 'pink';
        }
        trs[i].onmouseout = function () {
            this.style.backgroundColor = '';
        }
    }
</script>

案例4:全选框和复选框(难的一塌糊涂)

先写html

<div class="box">
    <table>
        <thead>
            <tr>
                <th>
                    <input type="checkbox" id="select_all">
                </th>
                <th>名称</th>
                <th>价格</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    <input type="checkbox">
                </td>
                <td>手机</td>
                <td>10000</td>
            </tr>
            <tr>
                <td>
                    <input type="checkbox">
                </td>
                <td>手机</td>
                <td>9999</td>
            </tr>
            <tr>
                <td>
                    <input type="checkbox">
                </td>
                <td>手机</td>
                <td>8888</td>
            </tr>
            <tr>
                <td>
                    <input type="checkbox">
                </td>
                <td>手机</td>
                <td>7777</td>
            </tr>
        </tbody>
    </table>
</div>

再写JavaScript

我自己的逻辑:

1.全选框这块儿,点击事件,让所有小弟变成和全选框一样就行,这个比较简单
2.小弟们这里需要点逻辑,所有小弟全选时,全选框全选,有一个小弟不选时,全选框就不选。
首先把所有小弟选出来,给它们一个点击事件,每点击一个小弟,就对所有小弟循环,判断该小弟是否已经打勾,只有四个小弟都打勾,全选框才打勾。
3.小弟这里可以设置一个变量flag,初始置为0,如果小弟有一个打勾的,就加一次1
4.每次循环结束判断flag是否等于全部的小弟数,如果等于,全选框变成true,否则变为false

var s_all = document.getElementById('select_all');
var s_tds = document.querySelector('tbody').querySelectorAll('input');
//1.操作全选框
s_all.onclick = function () {
    for (var i = 0; i < s_tds.length; i++) {
        // 多选框默认选定状态是checked='checked'
        s_tds[i].checked = this.checked;
    }
}

//2.操作全选框的小弟们,首先把元素全选出来
for (var i = 0; i < s_tds.length; i++) {
    s_tds[i].onclick = function () {
        //每次点击一个框,就对所有的框进行循环,判断是全选还是全取消
        var flag = 0;  //定义一个变量来判断下面是否全部选中
        for (var i = 0; i < s_tds.length; i++) {
            if (s_tds[i].checked == true) {
                flag++;
            }
        }
        if (flag == s_tds.length) {
            s_all.checked = true;
        }
        else {
            //这里的true和false不用加引号,因为本身就是boolean类型
            //这个地方有点奇怪,上面true加引号不影响,下面这个false就不行
            s_all.checked = false;
        }
    }
}

老师操作小弟的逻辑:

除了操作小弟的逻辑,其他地方都差不多。这个是真的难想,把flag初始值置为true,然后每点击一次就循环
如果有一个没点的,那么就把flag变成false,最后让全选框=flag的值
这里不太好想到的是if里的判断条件,如果有一个没选的,那么s_tds[i].checked肯定就是false,然后取反就是true,当条件为true的时候执行if里的条件执行体,因为只要有一个false全选框就是false,所以如果有一个没选,循环就可以break结束了。如果全选了,if就不会执行,flag还是true。

for (var i = 0; i < s_tds.length; i++) {
    s_tds[i].onclick = function () {
        //每次点击一个框,就对所有的框进行循环,判断是全选还是全取消
        var flag = true;  //定义一个变量,默认为true
        for (var i = 0; i < s_tds.length; i++) {
            //只要有一个没有选中,全选框就不选
            if (!s_tds[i].checked) {
                flag = false;
                break;
            }
        }
        s_all.checked = flag;
    }
}

二、自定义属性

这里最需要注意的地方就是,自定义属性只能用第二种方式操作,这个太容易忘了

1.获取属性值的方法:

在这里插入图片描述
区别:
在这里插入图片描述
比如我这里自定义了一个div,里面id是共有的,my是我自己定义的

	<div id="zzy" my='1' class='zzy'></div>

那我使用第一种就不能获取我自定义的my,我用第二种就可以

	var div = document.querySelector('div');
	console.log(div.id); //zzy
	console.log(div.getAttribute('id'));  //zzy
	console.log(div.getAttribute('my'));  //1
	console.log(div.my);  //undefined

2.修改属性值的方法:

在这里插入图片描述
比如还是这个div,我想改变id和class

	<div id="zzy" my='1' class='zzy'></div>

使用第一种方法这么改:
注意必须是className

	div.id = 'ht';
	div.className = 'ht';

使用第二种这么改:

    div.setAttribute('id', 'ht');
    div.setAttribute('class', 'ht');

但是如果想改自定义属性,只能用第二个:

  div.setAttribute('my', '2');

2.移除属性用removeAttribute(‘属性’)

div.removeAttribute('index');

三、tab栏切换(重点中的重点)

在这里插入图片描述

先写html,css这里就不写了
这个思路真的是男上加男,强人锁男,且听我细细道来

<div class="box">
    <div class="box_hd" id="box_hd">
        <ul>
            <li class="bhd_first">商品介绍</li>
            <li>规格与包装</li>
            <li>售后保障</li>
            <li>商品评价(5000)</li>
            <li>手机社区</li>
        </ul>
    </div>
    <div class="box_bd" id="box_bd">
        <div class="item" style="display:block">
            商品介绍模块内容
        </div>
        <div class="item">
            规格与包装模块内容
        </div>
        <div class="item">
            售后保障模块内容
        </div>
        <div class="item">
            商品评价(5000)模块内容
        </div>
        <div class="item">
            手机社区模块内容
        </div>
    </div>
</div>

代码逻辑:
1.这里我们要实现的主要功能就是,点击头部的模块,身子能显示到相对应的内容上,这里要分为两步来做,第一步就是头部区域,点谁谁就变红,这里用到排他思想,比较简单不再赘述。第二步就是点击哪块儿头部,就显示哪块儿身子,其他的身子隐藏
2.第二步也是用到排他思想,但是它的难点在于,我怎么保证身子的索引和头部一样呢?That is a question,用i吗?你会发现实际上这里面两个for循环已经改变了i的值,每次循环结束,i都会变为lis或divs的长度(本例中是5),这样的话,如果我们最后一句直接写divs[i].style.display = ‘block’;肯定会报错,因为divs[5]是不存在的,最后一个是divs[4](本例中)
3.在这种情况下,就用到了上面我们提到的自定义属性,在我们准备给每个li添加点击事件时(也就是for循环的开始),可以使用setAttribute给每个li添加一个自定义属性,名字随便取,这里我叫index,属性值就是i的值
4.后面呢再定义一个变量来接收当前点击事件的index,这样就能够有一个值,和头部的值相对应,就可以操作了

	//1.先使用排他思想设置头部的区域
	var box_hd = document.getElementById('box_hd'); //id选择器别对应class!!
	var lis = box_hd.getElementsByTagName('li');
	var box_bd = document.getElementById('box_bd');
	var divs = box_bd.getElementsByTagName('div');
	for (var i = 0; i < lis.length; i++) {
	    //通过下面这行代码,给每个li添加一个index的自定义属性,让index的值和索引号i对应
	    lis[i].setAttribute('index', i);
	    lis[i].onclick = function () {
	        for (var i = 0; i < lis.length; i++) {
	            lis[i].className = '';
	        }
	        //从上面这个循环出来,i的值变成了5(lis的长度)
	        this.className = 'bhd_first';
	
	        //2.设置点击哪个头部显示哪块儿身子,剩下的身子隐藏
	        for (var i = 0; i < divs.length; i++) {
	            divs[i].style.display = 'none';
	        }
	        //从上面这个循环出来,i的值也变成了5(divs的长度)
	        var index = this.getAttribute('index');  //通过自定义属性,得到当前点击事件的index
	        //这样的话,就可以选择到和当前点击相对应的div,把它的display属性改为block显示
	        divs[index].style.display = 'block';
	    }
	}

四、H5自定义属性

1.自定义属性的目的

实际上就是把数据保存到页面中而不是保存到数据库中,就像上面这个tab栏切换的例子,一开始其实我是手动给每个li添加了index属性,但是听老师讲后发现,lis[i].setAttribute(‘index’, i);这一句代码就可以直接给每个li添加index属性,而且页面刷新就没了,还是非常不错的。

2.我tm怎么知道哪个是自定义属性,哪个不是自定义属性

H5规定,自定义属性以data-开头作为属性名并赋值

<li data-index="1">规格与包装</li>

也可以用下面这种方式添加

li.setAttribute('data-time', '20');

添加之后就成了:

<li data-index="1" data-time="20">规格与包装</li>

3.H5新增使用dataset对象获取自定义属性

除了li.getAttribute(‘data-index’);获取自定义属性外,H5还新增了li.dataset.index或者li.dataset[‘index’]
这个要注意点后面是index而不是data-index,就是只写data-index后面的部分,很奇怪,记住就行了,而且这个只有ie11及以上才兼容,大多数还是使用getAttribute比较多

<li data-index="1" data-time="20">规格与包装</li>
获取上面这个的data-index:li.dataset.index

如果li.dataset,就是把所有的自定义属性都显示出来(去掉data-),以对象的方式,因为dataset是一个对象。
这里还有个比较恶心的地方就是,如果我属性名叫:data-index-name
那么在获取时就要遵循驼峰命名法,这么写:

li.dataset.indexName
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值