慕课 京东实现无延迟菜单效果

开发普通的二级菜单效果+加入延迟解决移动问题+解决延迟引入的新问题

二级菜单的每一项需和一级菜单一一对应,用id实现对应关系

display:none;和visibility: hidden;都可以隐藏元素。区别是display:none彻底不显示元素,元素不占空间,跟完全没有一样。visibility: hidden只是把元素隐藏不显示,但还是占有原来的位置空间的。


data-id: id是选择器,data-id只是行内存放数据的一个标签,就跟input里面value是一样的

HTML data-* 属性  https://blog.csdn.net/jx950915/article/details/78931509  

下面就详细介绍四种方法获取data-*属性的值

<li id="getId" data-id="122" data-vice-id="11">获取id</li>1

需要获取的就是data-id 和 dtat-vice-id的值

一:getAttribute()方法

const getId = document.getElementById('getId');
// //getAttribute()取值属性
console.log(getId.getAttribute("data-id"));//122
console.log(getId.getAttribute("data-vice-id"));//11
// //setAttribute()赋值属性
getId.setAttribute("data-id","48");
console.log(getId.getAttribute("data-id"));//48

二:dataset()方法

//data-前缀属性可以在JS中通过dataset取值,更加方便
console.log(getId.dataset.id);//112
//data-vice-id连接取值使用驼峰命名法取值 
console.log(getId.dataset.viceId);//11

//赋值
getId.dataset.id = "113";//113
getId.dataset.viceId--;//10

//新增data属性
getId.dataset.id2 = "100";//100

//删除,设置成null,或者delete
getId.dataset.id2 = null;//null
delete getId.dataset.id2;//undefind123456789101112131415

三:jquery data()方法

var id = $("#getId").data("id"); //122
var viceId = $("#getId").data("vice-id"); //11
//赋值
$("#getId").data("id","100");//1001234

四:jquery attr()方法

var id = $("#getId").attr("data-id"); //122
var viceId = $("#getId").attr("data-vice-id"); //11
//赋值
$("#getId").attr("data-id","100");//100


有一个问题,当鼠标进入一级菜单,二级菜单就会显示;这时我让鼠标向左进入侧边广告栏,就会出现广告栏弹出的.ad-r和菜单重叠的现象,怎么解决?让.ad-r的z-index大于二级菜单的?不对,因为二级菜单盒子的长度大于.adr。

==》一个对象同时绑定多个事件,怎么只触发其中的一个?

==》思路: (以下思路是错的,无法显示预期的结果)

var ads=$("#ads")
var adShow=true

$("#test")
	 .on("mouseenter",function(e){
		adShow=true
	}).on("mouseleave",function(e){
		adShow=false
	})

	 .on("mouseenter",function(e){                                                  
             if(adShow){
			 activeMenu.addClass("none")
			 }return
	 })

上面思路为什么错了呢,因为当鼠标从一级菜单进入#ads时,生成二级菜单这个事件已经被触发了,我们是无法阻止一个正在

发生的事件停止的。

==》解决了,思路是,当鼠标进入到一级菜单左侧时,就addClass("none")

ads.on("mouseenter",function(e){   //鼠标进入#ads
		sub.addClass("none")
	})

activeMenu=$("#"+activeRow.data("id")); 选中和一级菜单对应的二级菜单,为什么这样表示呢?因为activeRow.data("id")的返回值是与activeRow对应的id,不是一个对象!

jQuery.data(),data() 方法向被选元素附加数据,或者从被选元素获取数据:$(selector).data(name)      $(selector).data(name,value)

<i>&gt;</i>  表示箭头>

box-shadow属性:box-shadow: h-shadow v-shadow blur spread color inset;

手动设置变量的值或者对象某一个属性值为null(此时不赋值,会在后面的代码中进行赋值,相当于初始化。)

https://www.jb51.net/article/113680.htm   实现简易菜单下拉功能

思路:先给左侧一级菜单.grid-col1的li设置鼠标进入时li的样式,后面再通过js设置。(to be continue)

待确定的问题:当鼠标进入.grid-col1时触发二级菜单#sub,但是.ads也是.grid-col1的后代。所以就会有鼠标经过.ads时,也会触发#sub

之前出现一个问题,当页面一刷新,.grid-col1就带上了.active的效果,这个应该是在mouseenter事件中实现。原来是我错误地在HTML文件中把class="active"添加在了.grid-col1的li标签中。

activeRow = null;//不将activeRow置于null 的话,就不能再一次的激活背景色(只能激活一次)

当鼠标在一级菜单上的时候,设定一个定时器,这个定时器是判断鼠标离开一级菜单0.5S后是否移动到二级菜单里边,如果移动到二级菜单里边,取消定时器,二级菜单不消失;如果没有进入到二级菜单里边则二级菜单消失。

为什么activeRow为true,就代表存在激活?因为这个判断语句在.on方法的“mouseleave"事件下面。意思:如果鼠标离开一级菜单时,存在激活的话,就……;前面undefined时,if默认判定为false不执行操作。

事件代理方式的选择:为什么用mouseenter/mouseleave,而不是mouseover/mouseout?   因为使用mouseover/mouseout时,如果鼠标移到子元素上,即便没有离开父元素,也会触发父元素的mouseout事件;mouseenter/mouseleave没有冒泡属性。

当我们从一个已经激活的一级菜单中的列表项移到另一个列表项时,要把上一次的状态清除。然后指向当前的。

为什么第一次刷新的页面,默认显示的是带有.active效果的?.css文件设置了.active为显示,jq设置了当鼠标进入时才为显示。引用顺序?不是。那么怎样消除呢?或者阻止.ads的冒泡事件?嘿嘿,是阻止冒泡事件哦。

event.stopPropagation() 方法阻止事件冒泡到父元素,阻止任何父事件处理程序被执行。

切换子菜单时,用setTimeot设置延迟

debounce去抖技术:在事件被频繁触发时,只执行一次处理

设置一个计时器,当计时器触发的时候并没有执行,就清掉。clearTimeout()

基于用户行为预测的切换技术:跟踪鼠标移动,用鼠标当前位置和鼠标上一次位置与子菜单上下边缘形成的三角形区域进行比较

向量:Vab=Pb-Pb

二维向量叉乘公式:a(x1,y1)*b(x2,y2)=x1*y2-x2*y1,用叉乘法判断点在三角形内

不加return也可以正常运行,因为if里面的代码和if下面的代码做的是一样的事情,但这样的话,即使activeRow为null,也会把mouseenter事件里所有的代码全部运行一遍,会降低运行效率

当鼠标指针在指定的元素中移动时,就会发生 mousemove 事件。

为什么要解绑在document上的moveHanlder()事件:这样防止一个事件重复绑定多次造成多次触发

    var activeRow   //当前激活的一级菜单中的行
当鼠标离开一级菜单时,如果存在激活,要把激活的样式去掉,并把变量置空。

e.currentTarget和e.target的区别:

  • e.target 指向的是触发事件监听的对象。即被鼠标点击的元素。
  • e.currentTarget 指向的是添加监听事件的对象
  • ul绑定了事件处理函数,在函数里获取到的e.currentTarget对象就是ul元素,
  • 点击时,实际点击到了li元素,然后冒泡到了ul元素,触发ul的事件处理函数执行,事件对象最开始是从li元素向上冒泡到ul的,说明实际的源头即任务源头就是li元素

this和e.targrt的区别:

$("ul").on('click',function(e){

            //这里this是指ul;如果是$(e.target),指的就是ul里面被点击的子元素这个节点。

 $(this).css('border','1px solid blue')   

})

一个事件触发多次,只执行最后一次的方法:clearTimeout() 方法可取消由 setTimeout() 方法设置的 timeout。

var iTime;
clearTimeout(iTime);

iTime=setTimeout(function(){

  //事件

},100);

猜你喜欢

转载自blog.csdn.net/Lakeson/article/details/84203080