`
换个号韩国红果果
  • 浏览: 48033 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类

滑过导航时出现描述框的制作

 
阅读更多

当滑过左边导航栏时右边出现描述框的制作。
1.  hover时如何把右边的边框去掉。
2.如何让 外部右边3px的border在hover时变成1px 。
3.如何让列表项在没有hover时显示的下边框没有到达两边。而在hover时却能到达两边。
导航栏用ul 来制作。右边的描述性边框防止ul下面的li元素里面。
html代码
下面只用一个li来说明,其他一样的。
<div class="in-sub-nav">
					<ul>
						<li>
						<!-- 为何此时设置in-nav-wrap 的margin值后它没有自动填充?? -->
							<div class="margin-wrap"> 
							<div class="in-nav-wrap">
								<h3>周边游</h3>
								<p>
									<a href="#">峨眉山</a>
									<a href="#">青城山</a>
									<a href="#">金沙江</a>
								</p>
								<s><i></i></s>
							</div>
							</div>
							<div class="in-detail">
								
							</div>
							<div class="in-line-right"></div>
						</li>
</ul>

css代码

//先限制外层/.in-sub-nav的宽,它的高由里面的元素自动填充。
.in-sub-nav{width: 300px;border: 4px solid #77EFD3;position: relative;float: left;}//使它浮动到左边布局。

//里面元素的布局。
.in-sub-nav a{text-decoration: none;color: #888;}
.in-nav-wrap p {padding-bottom: 15px;}
.in-nav-wrap h3{padding-bottom: 10px;}
.in-nav-wrap s,.in-nav-wrap i{height: 0px; width: 0px;border: 8px solid;display: inline-block;}
.in-nav-wrap s{position: absolute;border-color: transparent transparent transparent lightblue;top: 20px;left: 240px;}
.in-nav-wrap i{position: absolute;border-color: transparent transparent transparent #fff;left: -10px;top: -8px;}

下面来布局描述框.in-detail,设置宽高使它能够撑起来,设置border,然后再以.in-sub-nav作为父元素进行绝对定位,则可以知道,.in-detail一定是在.in-sub-nav之上的,先解决开始提出的第二个问题,想要使父元素的右边边框变为1px,其实我想到有两种方法,第一种,当父元素hover时使它变为1px或者0px,然后再将.in-detail的左边框绘制在这个边框上(对于1px),两种方式都变成了1px。第二种方法。前面提到过 .in-detail一定是在.in-sub-nav之上的,现在利用下这个结论,直接让.in-detail的左边框定位在.in-sub-nav的右边框3px的开始处,这样刚好把3px给覆盖掉了,结果是只有.in-detail的1px,这样第2个问题被解决了。所以left值为300,(说明,它的定位是以包含块的边框内侧为起点开始定位,则它的border是从301px处开始render的,刚好覆盖3px)但是又要设置background-color: #fff;因为框是透明的,要看不见还要设置它。z-index: 5;后面再说明。
.in-sub-nav .in-detail{width: 500px;height: 500px;border: 1px solid rgb(119, 239, 211);
	position: absolute;top: -30px;left: 300px;background-color: #fff;display: none;z-index: 5;}

第3个问题.margin-wrap下边框效果怎么做出来?
.margin-wrap {
    padding: 15px 0px 15px;
    border-bottom: 1px solid #ddd;
    margin: 0px 8px 0px 15px;//这样做到。
    position: relative;
    z-index: 10;
}

第1个问题.hover时的各种问题解决。首先解决.margin-wrap,下边框要饱满。必须重新设置padding,即将没有hover时的margin变成padding,同时设置左上下边框但是现在要保证它的父元素li在hover时能够将右边.in-detail的那1px边框覆盖住,先设置背景background-color: #fff;然后,它是.in-sub-nav的子元素(没有绝对定位)所以由上面的结论,它的层是处于.in-detail的下面的。要让它处于.in-detail的上面以此来盖住.in-detail,则设置它的z-index:>.in-detail的z-index:即可。解决掉了这个问题,但是又为了让它的高度宽度不发生变化设置负值的margin(对不起我这里也没搞懂,对负的margin不熟悉),代码如下
.in-sub-nav li:hover .margin-wrap{
	border: 1px solid #77EFD3;//
	padding: 15px 10px 16px 15px;//避免宽高变化
	margin: -1px;
	background: #fff;
	border-right: 0px;
}
.in-sub-nav li:hover .in-detail{display: block;}//使它显示

.in-sub-nav a:hover {//链接样式
    text-decoration: underline;
    color: orange;
}

.in-nav-wrap:hover s{border-color: transparent transparent transparent rgb(79, 190, 226);}//设置右箭头样式


再解决一个问题,注意到hover时.in-detail可能会在窗口显示区之外并且是固定位置的,为了用户体验,现在用js实现如何让.in-detail始终在显示窗口以内进行显示?先设定每个.in-detail高度都是502px;
先解决第一个问题,怎么让它定位在窗口可视区?
由上面的定位可知,.in-detail是以.in-sub-nav为父元素进行定位的,即它的参考系为.in-sub-nav。
但是现在要让它定位在窗口可视区,即以可视区进行定位,换句话说就是参考系变为可视区而不再是它的父元素。
现在改为将整个窗口作为参考系,另外,是鼠标移到每个li上面就触发,然后又不同的位置,
故跟鼠标有关,想法是用鼠标指针位置来做,将鼠标的坐标映射到.in-sub-nav里面,再根据这个坐标来获得.in-detail的top值,prearr是用里存储前一个设置了top值的li元素,当在可视区内部时,一旦鼠标移动,则.in-detail会跟着一起运动,它是通过检查是否与prearr中最后一个元素相同,一旦相同,则返回不再设置top值,这样就不会跟着鼠标运动了
js代码如下
var in_sub_nav=document.getElementsByClassName('in-sub-nav')[0];
			var li= in_sub_nav.getElementsByTagName('li');
			var prearr=[];//
			in_sub_nav.onmouseout=function(e){
				
				// prearr=[];
			}
			in_sub_nav.onmousemove=function(e){
				function css(obj,name,value){
						if (arguments.length==2)// 获取
						{
						   return obj.style[name];
						 }
						else 
						  obj.style[name]=value;

					}
			var sTop=document.body.scrollTop;
			var offLeft=this.offsetLeft;
			var mx=e.clientX;var my=e.clientY;
			
			var cx=mx-offLeft-this.clientLeft;//获取.in-sub-nav内鼠标x y值的转换值。cx,cy
			var cy=my+sTop-this.offsetTop-this.clientLeft;
			var top= getPosition(cx,cy);
			var whichOne;//y现在已经映射到in_sub_nav内部
			//每个li的高度是96,下面的代码判断位于哪个li中,以此来设置它的in-detail的top属性
			
			
				
				if( cy>0 && cy <=96) whichOne=0;
				if( cy>96 && cy <=192) whichOne=1;
				if( cy>192 && cy <=288) whichOne=2;
				if( cy>288 && cy <=384) whichOne=3;
				if( cy>384 && cy <=480) whichOne=4;
				if( cy>480 && cy <=576) whichOne=5;
				
				
				if(prearr.length>10)//不超过10个元素
					prearr.shift();
				// console.log(prearr);
				if(whichOne==prearr[prearr.length-1])//持续在一个li内运动,那么不再更改top值,否则in-detail会随鼠标运动,影响体验
					return;
				var aim=li[whichOne].getElementsByClassName('in-detail')[0];
				aim.style.top=top+'px';
				prearr.push(whichOne);//把已经设置top的当前元素存入prearr中
			
		}
		function  getPosition(x,y){//502指的是in-detail的高度。因为此时它还处于none状态,无法获取它的offsetHeight值
			var top=y-110;//初步在当前鼠标指针y上110px处‘
			var clientTop=-document.body.scrollTop+in_sub_nav.offsetTop;
			var t=clientTop+top;//以窗口上边框为参考系计算此时.in-detail的top值
			var clientH=document.documentElement.clientHeight//获取当前可视区的高度。
			if(t<=0)//如果.in-detail定位在窗口上边框以上,则另t=0;即in-detail的上边框刚好与窗口的上边框对其。
				top=-clientTop;
			else if(t+502>clientH)//如果.in-detail定位在窗口下边框以外,则另top上移(t+502-clientH)的距离;即in-detail的上边框刚好与窗口的上边框对其。
				top=top-(t+502-clientH);
			return  top;//否则不做出理,事实上后面要处理
		}

  • 大小: 7.5 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics