原生JS实现新闻列表展开与收起功能:DOM操作详解
本文详解如何使用原生JavaScript实现新闻列表的展开与收起功能。核心原理是通过点击事件控制div的display属性。重点解析parentNode、nextSibling及previousSibling等DOM操作方法,并针对浏览器差异,利用nodeType过滤非元素节点(如换行符)。此外,文章提供了自定义siblings函数以获取同级元素,并附完整代码示例,帮助开发者掌握相关技巧。
功能原理与DOM操作基础
知识要点
实现该功能的原理较为直观:通过监听a标签的点击事件,动态设置对应div元素的display属性,从而控制内容的隐藏或显示。
这主要考察对DOM(文档对象模型)操作的熟练程度。
在实现过程中,需要用到以下关键DOM操作方法:
parentNode:用于获取当前元素的父级元素。
nextSibling:用于获取紧跟在当前节点之后的下一个节点。
previousSibling:用于获取紧跟在当前节点之前的上一个节点。
关键注意事项与节点类型判断
在编码时需特别注意以下事项:
当用户点击“展开全文”时,逻辑上应确保其他已经展开的内容自动收起,保持列表整洁。
使用nextSibling获取下一个节点时,不同浏览器的行为存在差异。
部分浏览器会返回元素节点,而另一些则可能返回换行符或空格文本节点。因此,必须利用nodeType属性来判断节点类型,因为nodeType仅返回数字(如1、2、3)。
只有当nodeType返回1时,表示获取到的是元素节点,这才是我们需要的目标。
在实际开发中,若忽略此问题,可能导致逻辑错误且难以排查。
封装获取同级元素函数
由于原生JavaScript中没有像jQuery那样直接获取所有同级元素的便捷方法,因此需要手动封装一个siblings(elm)函数。
该函数可用于遍历同级节点并筛选出元素节点,封装后可复用,提高开发效率。
完整代码实现
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>demo</title>
<style>
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{margin:0;padding:0;}
h1,h2,h3,h4,h5,h6{font-size:100%;}
address,cite,dfn,em,var{font-style:normal;}
code,kbd,pre,samp{font-family:courier new,courier,monospace;}
ul,ol{list-style:none;}
a{text-decoration:none;}
a:hover{text-decoration:none;}
sup{vertical-align:text-top;}
sub{vertical-align:text-bottom;}
legend{color:#000;}
fieldset,img{border:0;}
button,input,select,textarea{font-size:100%;}
table{border-collapse:collapse;border-spacing:0;}
.clear{clear: both;float: none;height: 0;overflow: hidden;}
body{color:#333; font: 12px/1.3 'Arial','Microsoft YaHei';}
#pn{width: 650px; height: auto; background: #fff; margin: 0 auto; padding: 5px;}
#list0{margin-bottom: 10px;}
.title{ font-weight: bold; font-size: 14px; margin-bottom: 7px;}
.time{color: #808080; margin-bottom: 2px;}
.content{display: none; padding: 1px 0 3px; line-height: 23px; font-size: 14px; }
.btm{text-align: right; height: 30px; }
.hidd{ color: #eb7350; margin-left: 5px; }
.show{ color: #eb7350; margin-left: 5px; }
.zy{padding: 1px 0 3px; line-height: 23px; font-size: 14px;}
</style>
</head>
<body>
<div id="pn">
<div id="list0">
<p class="title">Jackie吉吉</p>
<p class="time">12月3日 20:49 来自 +niPhone 6s</p>
<p class="zy">感谢@马路口的YY 今天的款待!一直觉得你们两口子颜值又高人又有趣,又都是高材生,认识你们真的很是很幸运的一件事!~ 终于修成正果了呀~祝福你们新婚快乐白头偕老~ 感谢...<a class="show" href="#">展开全文</a></p>
<div class="content">感谢@马路口的YY 今天的款待!一直觉得你们两口子颜值又高人又有趣,又都是高材生,认识你们真的很是很幸运的一件事!~ 终于修成正果了呀~祝福你们新婚快乐白头偕老~ 感谢@SNH48-杨韫玉-- 让我们相识[偷乐]以后也一起去看公演呀~ 哪个队都成。
<a href="#" class="hidd">收起全文</a>
</div>
</div>
<div id="list0">
<p class="title">高晓松</p>
<p class="time">44分钟前 来自 微博 weibo.com</p>
<p class="zy">波澜壮阔的独立斗争,风起云涌的解放运动,卡斯特罗泼墨挥毫一人写就半部古巴史。戴名表开豪车上名校,亲美富二代卡斯特罗早早走上革命之路竟是由基因决定?艳福不浅,老卡又如何能在有生之年睡完传闻中的35000个女人?高晓松用数据还原真实的古巴,看今日...<a class="show" href="#">展开全文</a></p>
<div class="content">波澜壮阔的独立斗争,风起云涌的解放运动,卡斯特罗泼墨挥毫一人写就半部古巴史。戴名表开豪车上名校,亲美富二代卡斯特罗早早走上革命之路竟是由基因决定?艳福不浅,老卡又如何能在有生之年睡完传闻中的35000个女人?高晓松用数据还原真实的古巴,看今日的它究竟是落后贫穷还是盛世繁华:L晓松奇谈之革命领袖卡斯特罗的传奇一生
<a href="#" class="hidd">收起全文</a>
</div>
</div>
<div id="list0">
<p class="title">王尼玛</p>
<p class="time">12月7日 12:30 来自 微博weibo.com</p>
<p class="zy">已退役的美国休斯顿德州人橄榄球队的外接手安德烈·约翰逊,为12位由儿童保护服务组织选出的孩子买圣诞节玩具,孩子们可以在80秒内...<a class="show" href="#">展开全文</a></p>
<div class="content">已退役的美国休斯顿德州人橄榄球队的外接手安德烈·约翰逊,为12位由儿童保护服务组织选出的孩子买圣诞节玩具,孩子们可以在80秒内选择他们喜欢的任何玩具,最终这些玩具花费19144.58美元,慷慨!好了好了别闹了,论飙车还是应该老司机出马!
<a href="#" class="hidd">收起全文</a>
</div>
</div>
</div>
<script type="text/javascript">
//在页面加载完后立即执行多个函数方案。
function addloadEvent(func){
var oldonload=window.onload;
if(typeof window.onload !="function"){
window.onload=func;
}
else{
window.onload=function(){
if(oldonload){
oldonload();
}
func();
}
}
}
addloadEvent(b);
//在页面加载完后立即执行多个函数方案结束。
//获取同级所有元素开始
function siblings(elm) {
var a = [];
var p = elm.parentNode.children;
for(var i =0,pl= p.length;i<pl;i++){
if(p[i] !== elm) a.push(p[i]);
}
return a;
}
//获取同级所有元素结束
function b(){
//获取查看全文的a标签
var show=document.getElementsByClassName("show");
//遍历a
for(var i=0;i<show.length;i++){
show[i].onclick=function(){
//找到a的父级
var father=this.parentNode;
//设置隐藏
father.style.display="none";
//找到父级的下一个节点
var next=father.nextSibling;
//判断下一个节点的数据类型,如果不是1(元素节点),那就接着往下找
if(next.nodeType!=1){
next=next.nextSibling;
}
//正文显示
next.style.display="block";
//获取整个list0
var ff=this.parentNode.parentNode;
//获取除去list0的所有同级元素
var bro=siblings(ff);
for(var y=0;y<bro.length;y++){
//获取每个list0里的第一个content类名
var w=bro[y].getElementsByClassName("content")[0];
//获取content类名的前一个节点
var wt=w.previousSibling;
//判断前一个节点的数据类型,如果不是1(元素节点),那就接着往上找
if(wt.nodeType!=1){
wt=wt.previousSibling;
}
//同级摘要部分显示
wt.style.display="block";
//同级全文部分隐藏
w.style.display="none";
}
}
}
//下面就是点击收回全文的部分与展开原理一样
var hidd=document.getElementsByClassName("hidd");
for(var i=0;i<hidd.length;i++){
hidd[i].onclick=function(){
var fafa=this.parentNode;
fafa.style.display="none";
var pre=fafa.previousSibling;
if(pre.nodeType!=1){
pre=pre.previousSibling;
}
pre.style.display="block";
}
}
}
</script>
</body>
</html>
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持本站!
JavaScript零基础入门:从环境搭建到运行第一段代码
2026-11-05 15:29:58
HTML链接中javascript:void(0)的作用及现代替代方案
2026-11-05 10:07:47
在线调试 JS 时怎么引入 jQuery 或 Vue 等第三方库
2026-11-05 08:53:56
原生JavaScript实现简易颜色选择器原理与代码
2026-11-03 23:22:19
JS原生表单序列化:FormData与URLSearchParams用法详解
2026-11-03 23:13:21
