JavaScript编程实现tab选项卡切换的效果+1

news2025/6/18 22:25:09

之前在“圳品”信息系统使用了tab选项卡来显示信息,详见:

JavaScript编程实现tab选项卡切换的效果

在tab选项卡中使用其它<div>来显示信息就出现了问题,乱套了,比如下面的这段代码:

<!DOCTYPE html>
<html>
<head>
  <meta name="Author" content="PurpleEndurer">
  <title>“圳品”信息系统</title>
    <style type="text/css">
        *{padding:0px;margin: 0px;font:12px normal "microsoft yahei";}
        #tabs {width:1024px; padding:5px; height:850px; margin:20px;}
        #tabs ul {list-style:none; display: block; height:30px; line-height:30px; border-bottom:2px #33ffff solid;}
        #tabs ul li {background:#eee; cursor:pointer; float:left; list-style:none; height:28px; line-height:28px; margin:0px 3px; border:1px solid #aaaaaa; border-bottom:none; display:inline-block; width:180px; text-align: center; font-size: 15px;}
        #tabs ul li.show {background:#fff;border-top:2px solid #33ffff; border-left:2px solid #33ffff; border-right:2px solid #33ffff; border-bottom: 2px solid #fff; font-weight:bold; font-size: 20px;}
        #tabs div {height:800px; line-height: 25px; border:1px solid #33ffff; border-top:none; padding:5px;}
        .hide{display: none;}
 	.blue{color:blue;}
    </style>
    <script type="text/javascript">
	function initTab()
	{
		var oTab = document.getElementById("tabs");
		var oUl = oTab.getElementsByTagName("ul")[0];
		var oLis = oUl.getElementsByTagName("li");
		var oDivs= oTab.getElementsByTagName("div");
 
		for (var i= 0; i<oLis.length; i++)
		{
			oLis[i].index = i;
			oLis[i].onmousemove = oLis[i].onclick = function (){activeTab(this.index);};
		}
	}//initTab()
 
 
	function activeTab(a)
	{
		var oTab = document.getElementById("tabs");
		var oTabUl = oTab.getElementsByTagName("ul")[0];
		var oTabLis = oTabUl.getElementsByTagName("li");
		var oTabDivs = oTab.getElementsByTagName("div");
		for (var n= 0; n < oTabLis.length; n++)
		{
			oTabLis[n].className = "";
			oTabDivs[n].className = "hide";
		}//for()
		oTabLis[a].className = "show";
        oTabDivs[a].className = "";
	} //activeTab(a)
 
         window.onload = function()
	 {
		 initTab();
	 }
    </script>
 
</head>
<body>
<p>JavaScript编程实现tab选项卡切换的效果 @Edge浏览器</p>
<div id="tabs">
    <ul>
        <li class="show" title="符合条件的产品清单">清单</li>
        <li>区域分布分析</li>
        <li>产品类别分析</li>
    </ul>
    <div id="divZpList">
	符合条件的产品清单
	<div id="div1" class="blue">选项卡1</div>
    </div>
    <div class="tabHide" id="divZpAreaDistNow"><!-- Area distribution //-->
	区域分布分析
	<div id="div2" class="blue">选项卡2</div>
    </div>
    <div class="tabHide" id="divZpTypeDistNow"><!-- Type distribution //-->
	 产品类别分析
     <div id="div3" class="blue">选项卡3</div>
</div>
 
</body>
</html>

运行效果如下:

可以看到,第1张选项卡中的<div id="div1" class="blue">选项卡1</div>消失了,而第2张和第3张选项卡的内容对调了。

导致问题的原因在于activeTab()函数中,根据函数参数a传递进来的活动选项卡的indax,默认为选项卡组中的每个项目卡里一对<li>的<div>的index是相同的,即第a个<li>对默认匹配第a个<div>,并将第a个<li>和第a个<div>设置为当前活动选项卡:

	oTabLis[a].className = "show";
    oTabDivs[a].className = "";

在选项卡组中的<div>与<li>数量相同时,这样默认是可以的,如<li>区域分布分析</li>与 <div class="tabHide" id="divZpAreaDistNow">匹配,这也是 ​​JavaScript编程实现tab选项卡切换的效果​​ 可以正常工作的原因。

但我们在选项卡组的<div>内引入其它的<div>,比如上面代码中的:

    <div id="divZpList">
	      符合条件的产品清单
	      <div id="div1" class="blue">选项卡1</div>
    </div>

这时选项卡组中的<div>数量大于<li>数量时,第a个<li>对匹配第a个<div>的这种默认关系就不一定准确了。在上面的演示代码中,第2个选项卡中的<li>(即<li>区域分布分析</li>)将会与第2个<div>(即<div id="div1" class="blue">选项卡1</div>)匹配,而不是与第3个<div>(即<div class="tabHide" id="divZpAreaDistNow">)匹配。

找到了原因后,就要想解决问题的办法。解决问题的关键是在进行选项卡切换时如何找到或确定与选项卡组中的与<li>匹配的<div>。

解决这个问题的方法有很多,最直接的办法是定义一个全局的二维数组,把每个选项卡中的<li>和与之匹配的<div>的id保存下来,再用一个全局变量来存放当前活动选项卡的index。但是这样做的话,使用全局变量太多,耦合度低,不够通用。

我使用的解决办法是,先为选项卡中与<li>匹配的<div>设置一个特定的id特征码,比如id都是以"ZpDiv"来开头,然后遍历选项卡中的<div>,并把id中具有id特征码的<div>筛选出来,将其id值保存在一维数组aDivs中,这样第i个<li>就与aDivs[i]存储的id所指向的<div>匹配,然后可以进行相应的操作了。

如果我们在activeTab()中实现上述遍历、筛选和匹配工作的话,每次选项卡切换都要重复进行一次,不划算。

如果我们在选项卡组初始化阶段initTab()完成实现上述遍历、筛选和匹配工作,再把这种匹配关系传递到activeTab()中,就方便多了。

那么如何把这种匹配关系传递到activeTab()中呢?

既然我们先前是通过给选择卡的<li>增加index属性来确定当前活动选项卡的,那么我们再给<li>再增加两个属性,一个是.linkedDivID 用来存与它匹配的<div>的id,另一个是.TabsID ,用来保存<li>所在选项卡组的id。

具体实现起来,我使用的解决办法是,分三步:

第一步,为选项卡中与<li>匹配的<div>设置一个特定的id特征码,比如id都是以"ZpDiv"来开头。

第二步,在选项卡组初始化阶段initTab(),我们先遍历选项卡中的<div>,并把id中具有id特征码的<div>筛选出来,将其id值保存在一个一维数组aDivs中;然后遍历选项卡中的<li>,为每个<li>增加index、.linkedDivID 和.TabsID属性并赋值,并把TabsID和index属性作为参数传递给activeTab(tabsId, a)。

第三步,在activeTab(tabsId, a)中,先根据tabsId建立选项卡中的<li>数组oTabLis ,然后遍历<li>数组oTabLis,将所有的选项卡设置为非活动状态,接着修改oTabLis[a]的className,把它设置为活动选项卡的<li>,最后修改oTabLis[a].linkedDivID指向的<div>的ClassName,把它设置为活动选项卡的<div>。

完整的代码如下,其中增加了一个<textarea>来显示程序运行数据,方便了解代码内部的运行情况:

<!DOCTYPE html>
<html>
<head>
  <meta name="Author" content="PurpleEndurer">
  <title>“圳品”信息系统</title>
    <style type="text/css">
        *{padding:0px;margin: 0px;font:12px normal "microsoft yahei";}
        #tabsId {width:800px; padding:5px; height:300px; margin:20px;}
        #tabsId ul {list-style:none; display: block; height:30px; line-height:30px; border-bottom:2px #33ffff solid; }
        #tabsId ul li {background:#eee; cursor:pointer; float:left; list-style:none; height:28px; line-height:28px; margin:0px 3px; border:1px solid #aaaaaa; border-bottom:none; display:inline-block; width:180px; text-align: center; font-size: 15px; border-radius: 5px;}
        #tabsId ul li.tabShow {background:#fff;border-top:2px solid #33ffff; border-left:2px solid #33ffff; border-right:2px solid #33ffff; border-bottom: 2px solid #fff; font-weight:bold; font-size: 20px; border-radius: 5px;}
        #tabsId div {height:280px; line-height: 25px; border:1px solid #33ffff; border-top:none; padding:5px;}
        div.tabHide {display: none;}
		    .blue {color:blue;}
    </style>

</head>
<body>
<p>JavaScript编程实现tab选项卡切换的效果 @Edge浏览器</p>
<div id="tabsId">
    <ul>
        <li id="liZpList" class="tabShow" title="符合条件的产品清单">清单</li>
        <li id="liZpAreaDist">区域分布分析</li>
        <li id="liZppTypeDist">产品类别分析</li>
    </ul>
    <div id="divZpList">
	符合条件的产品清单
	<div id="div1"  class="blue">选项卡1</div>
    </div>
    <div class="tabHide" id="divZpAreaDistNow"><!-- Area distribution //-->
	区域分布分析
	<div id="div2" >选项卡2</div>
    </div>
    <div class="tabHide" id="divZpTypeDistNow"><!-- Type distribution //-->
	 产品类别分析
	 <div id="div3">选项卡3</div>
    </div>
</div>
<textarea border="1" id="taDebug"  cols="180" rows="15">debug</textarea>

<script type="text/javascript">
	var taDbg = document.getElementById("taDebug");
	const tabsIdZp = "tabsId";		//选项卡组(tabs)的id
	const tabDivIdTagZp = "divZp";//选项卡组(tabs) 中 与 <li> 配对的<div>的id特征码

	// 设置当前活动的选项卡
	//参数说明:tabsId:选项卡组(tabs)的id, a: 当前活动的选项卡中<li>的index
	function activeTab(tabsId, a)
	{
		taDbg.value += '\n\n activeTab begin------';
		taDbg.value += '\n activeTab.index=' + a;
		var oTab = document.getElementById(tabsId);

		var oTabUl = oTab.getElementsByTagName("ul")[0];
		var oTabLis = oTabUl.getElementsByTagName("li");

		//将所有选项卡设置为非活动状态
		var i; //divID
		for (var n = 0; n < oTabLis.length; n++)
		{
			oTabLis[n].className = "";
			i = oTabLis[n]. linkedDivID;
			taDbg.value += '\n oTabLis[' + n + ']. linkedDivID=' + i + '   .className=' + oTabLis[n].className;
			document.getElementById(i).className = "tabHide";
			taDbg.value += '\n oTabLis[' + n + '].id=' + oTabLis[n].id + '   .className=' + oTabLis[n].className;
			i = document.getElementById(i);
			taDbg.value += '\n Divs.id=' + i.id + '   .className=' + i.className;
		}//for()

		//设置当前活动的选项卡
		oTabLis[a].className =   "tabShow";
		i = oTabLis[a]. linkedDivID;
		document.getElementById(i).className = "";

		taDbg.value += '\nactiveTab end------';
	} //activeTab() 

	
	//初始化选项卡
	//参数说明:tabsId: 选项卡组(tabs) id, tabDivIdTag:选项卡组(tabs) 中与<li>配对的<div>的id特征码
	function initTab(tabsId, tabDivIdTag)
	{
		taDbg.value += '\n initTab() begin------';
		var oTab = document.getElementById(tabsId);

		var oTabUl = oTab.getElementsByTagName("ul")[0];
		var oTabLis = oTabUl.getElementsByTagName("li");

		var oTabDivs= oTab.getElementsByTagName("div");
		taDbg.value += '\n oTabDivs.length=' + oTabDivs.length;

		var aDivs = new Array();//用来存放选项卡组(tabs)中与<li>配对的<div>的id
		var iDividTagLen = tabDivIdTag.length;
		if (iDividTagLen==0)
		{
			//与<li>配对的<div>的id特征码为"",直接从oTabDivs生成
			aDivs = Array.from(oTabDivs);
		}
		else
		{
			//遍历所有的<div>
			for (var i = 0; i<oTabDivs.length; i++)
			{
				//检查<div>的id是否符合与<li>配对<div>的id特征码
				if (oTabDivs[i].id.substr(0, iDividTagLen) == tabDivIdTag)
				{
					//保存符合与<li>配对<div>的id特征码的<div> 的id
					aDivs.push(oTabDivs[i].id);
				}
			}
		}

		if (aDivs.length < oTabLis.length)
		{
			alert("<div>数量小于<li>数量,不能完成初始化");
		}
		else
		{
			//初始化
			for (var i = 0; i < oTabLis.length; i++)
			{
				oTabLis[i].index = i; //设置选项卡中<li>的index属性,用于确定当前活动选项卡
				oTabLis[i].linkedDivID = aDivs[i]; //设置选项卡中<li>的linkedDivID属性,保存与该<li>配对的<div>的id
				oTabLis[i].TabsID = 	tabsId;	//设置选项卡中<li>的TabsID属性,保存选项卡组的id
				taDbg.value += '\n oTabLis[' + i + '].id=' + oTabLis[i].id + '   linkedDivID=' + oTabLis[i].linkedDivID;
				oTabLis[i].onclick = function() {activeTab(this.TabsID, this.index);};
				//oTabLis[i].onmousemove = oTabLis[i].onclick = function() {activeTab(this.TabsID, this.index);};
			}   //for			
		}//if

		taDbg.value += '\n initTab() end------'
	}//initTab()

   
	window.onload = function()
	{
		 //initTab(tabsId, tabLiId, tabDivId);
		  initTab(tabsIdZp, tabDivIdTagZp);  
	}
</script>          
</body>
</html>          

代码运行效果如下:

 

嵌套的<div>内容都能正常显示出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/411738.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c/c++:for循环语句,分号不可省略,表达式可以省略,猜数字游戏,跳转语句continue,break,避免写goto

c/c:for循环语句&#xff0c;分号不可省略&#xff0c;表达式可以省略&#xff0c;猜数字游戏&#xff0c;跳转语句continue&#xff0c;break&#xff0c;避免写goto 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;此时学…

树莓派 QT项目开机自启动

我自己用qt设置了一个界面&#xff0c;如何让他开机自启动呢&#xff1f; 目录 1.生成qt项目的可执行文件 2. 编写一个自启动脚本 3.重启树莓派 1.生成qt项目的可执行文件 QT项目的可执行文件就是.exe文件。首先在qt中打开&#xff0c;点击红色方框图标&#xff0c;选择Re…

vue+springboot 上传文件、图片、视频,回显到前端。

效果图 预览&#xff1a; 视频&#xff1a; 设计逻辑 数据库表 前端vue html <div class"right-pannel"><div class"data-box"><!--上传的作业--><div style"display: block" id""><div class"tit…

C++编程法则365条一天一条(359)认识各种初始化术语

文章目录Default initialization默认初始化Copy initialization拷贝初始化Aggregate initialization聚合初始化Direct initialization直接初始化list_initialization列表初始化value_initialization值初始化参考&#xff1a; https://en.cppreference.com/w/cpp/language/copy_…

【unity learn】【Ruby 2D】角色发射飞弹

前面制作了敌人的随机运动以及动画控制&#xff0c;接下来就是Ruby和Robot之间的对决了&#xff01; 世界观背景下&#xff0c;小镇上的机器人出了故障&#xff0c;致使全镇陷入了危机&#xff0c;而Ruby肩负着拯救小镇的职责&#xff0c;于是她踏上了修复机器人的旅途。 之前…

同步I/O实现Reactor和Proactor的差异

有两种高效的事件处理模式&#xff1a;Reactor模式和Proactor模式 Reactor模式 主线程只负责监听socket上是否有事件发生&#xff0c;当有事件发生时&#xff0c;主线程就将该事件放进请求队列&#xff0c;通知工作线程进程处理&#xff1b;主线程不做实质性的工作&#xff0c…

使用颜色检测有向图中的循环

给定一个有向图,检查该图是否包含循环。如果给定的图形至少包含一个循环,您的函数应返回 true,否则返回 false。 例子: 输入: n = 4, e = 6 0 -> 1, 0 -> 2, 1 -> 2, 2 -> 0, 2 -> 3, 3 -> 3 输出:是 解释: <

计网之HTTP协议和Fiddler的使用

文章目录一. HTTP概述和fidder的使用1. 什么是HTTP2. 抓包工具fidder的使用2.1 注意事项2.2 fidder的使用二. HTTP协议格式1. HTTP请求格式1.1 基本格式1.2 认识URL1.3 方法2. 请求报头关键字段3. HTTP响应格式3.1 基本格式3.2 状态码一. HTTP概述和fidder的使用 1. 什么是HTT…

VueRouter路由模式解析

VueRouter路由模式解析 前端路由的实现方式主要有两种&#xff1a;hash模式和history模式。 hash模式 在window.location对象中有一个hash字段&#xff0c;可以获取地址栏中#字符及后边的所有字符。 hash也称作锚点&#xff0c;本身是用来做页面定位的&#xff0c;可以使对…

BGP联邦实验

实验目的&#xff1a; 实验拓扑&#xff1a; IP地址规划&#xff1a; AS2内部&#xff1a; 172.16.0.0/16 172.16.0.0/24---P2P网络 172.16.1.0/24----MA网络 172.16.1.0/29 172.16.1.8/29 172.16.1.16/29 172.16.1.24/29 172.16.1.32/29 172.16.1.40/29 172.16.2.0/24--…

Golang每日一练(leetDay0032) 二叉树专题(1)

目录 94. 二叉树的中序遍历 Binary Tree Inorder Traversal &#x1f31f; 95. 不同的二叉搜索树 II Unique Binary Search Trees II &#x1f31f;&#x1f31f; 96. 不同的二叉搜索树 Unique Binary Search Trees &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷…

基于 FPGA+DSP 的冲击波超压测试系统设计与实现-系统测试(二)

5 系统功能测试及仿真 在完成系统硬件电路板的设计和软件程序的开发后&#xff0c;本章分别对 A/D 采集模块、 DDR3 SDRAM 存储模块的读写波形进行了测试&#xff0c;并对千兆网卡传输模块通过 Wireshark 软件进行抓包测速&#xff0c;调试成功并确认无误后将各模块组装起来对系…

Unity之ASE实现根据ScreenPosition改变渲染效果

前言 我们知道ScreenPosition节点,代表了屏幕空间的坐标,那么它有哪些用处呢?今天我们就来给大家演示一个效果,如下图所示:我们拉远拉进摄像机的位置,任务的渲染会根据不同距离有一定变化。 ScreenPosition介绍 Screen Position 节点输出当前像素的屏幕位置。根据所选…

7nm+跨域计算+极致性价比,这家芯片厂商助攻车企「降本增效」

汽车芯片赛道的「卷」&#xff0c;或许超出了所有人的预期。对于单纯TOPS算力的比拼&#xff0c;已经翻篇&#xff0c;如何让车企有的用&#xff0c;用得上&#xff0c;还要用得好&#xff0c;已经是新风向。 实际上&#xff0c;在汽车智能化刚刚开始的2018年&#xff0c;彼时类…

2.4 随机变量函数的分布

学习目标&#xff1a; 学习随机变量函数的分布&#xff0c;我会采取以下步骤&#xff1a; 熟悉随机变量的基本概念和分布&#xff1a;在学习随机变量函数的分布之前&#xff0c;需要先掌握随机变量的基本概念和分布&#xff0c;包括离散型随机变量和连续性随机变量的概率密度…

《Java8实战》第4章 引入流

集合是 Java 中使用最多的 API。 4.1 流是什么 流是 Java API 的新成员&#xff0c;它允许你以声明性方式处理数据集合&#xff08;通过查询语句来表达&#xff0c;而不是临时编写一个实现&#xff09;。可以看作是遍历数据集的高级迭代器&#xff0c;而且还可以并行的处理。…

语音识别实战(python代码)(一)

语音识别实战 &#xff08;python &#xff1a;pyttsx、SAPI、SpeechLib实例代码&#xff09;(一&#xff09; 本文目录&#xff1a; 一、语音识别的基本原理 &#xff08;1&#xff09;、语音识别的起源与发展 &#xff08;2&#xff09;、语音识别的基本原理 &#xff0…

吸烟行为检测系统(Python+YOLOv5深度学习模型+清新界面)

摘要&#xff1a;吸烟行为检测软件用于日常场景下吸烟行为监测&#xff0c;快速准确识别和定位吸烟位置、记录并显示检测结果&#xff0c;辅助公共场所吸烟安全报警等。本文详细介绍吸烟行为检测系统&#xff0c;在介绍算法原理的同时&#xff0c;给出Python的实现代码、训练数…

BGA封装与PCB差分互连结构的设计与优化

摘要&#xff1a;随着电子系统通信速率的不断提升&#xff0c;BGA封装与PCB互连区域的信号完整性问题越来越突出。 针对高速BGA封装与PCB差分互连结构进行设计与优化&#xff0c;着重分析封装与PCB互连区域差分布线方式&#xff0c;信号布局方式&#xff0c;信号孔/地孔比&…

Unity编写Shader内置各种矩阵和方法介绍

返回目录 大家好&#xff0c;我是阿赵。 这里记录一下Unity编写Shader内置各种矩阵和方法 一、Unity内置转换矩阵 1、MVP类矩阵 UNITY_MATRIX_MVP:Current model * view * projection matrix. UNITY_MATRIX_MV:Current model * view matrix. UNITY_MATRIX_V:Current view m…