原生js练习题---第六课

0x1圆满拖拽

完成结果:
6-01圆满拖动

这里没有运用h5的拖动,毕竟原题也是考核借助鼠标事宜完成自定义的拖动,所以就自创了《js高等程序设计》里的自定义拖动本身封装了个拖动api,固然由于做这个系列题目运用的都是es5的语法,所以IE8往下就兼容不到了(有兴致的可以本身一试)。

起首有一个自定义的事宜对象组织函数EventTarget,内部封装了事宜的监听、触发、移除监听三个基础操纵。再由EventTarget拓展一个和拖动操纵有关的单例对象,这个对象是的主要任务就是把指定元素上的触发的鼠标事宜转换为触发我们自定义的拖动事宜,该对象接口要领引见以下:

  • enable():开启全部文档上拖动事宜与鼠标事宜的关联

  • disable():封闭拖动事宜与鼠标事宜的关联,也就是点击时不再触发自定义的拖动操纵

  • addHandler(eventName, handler):给响应拖动事宜增加处置惩罚函数。注重由于拖动事宜是全局关联,所以若处置惩罚函数是针对指定元素的操纵,不仅要先在该元素上增加class="draggable",而且在处置惩罚函数里还要推断触发事宜的就是该元素才行

  • removeHandler(eventName, handler):移除指定的拖动事宜上的某个处置惩罚函数

再引见下三个自定义的拖动事宜:

  • dragstart:由mousedown转换而来,事宜对象的属性有:

    • type: ‘dragstart’

    • target: 鼠标点击的draggable元素

    • clientX, clientY: 同mousedown

  • drag:由mousemove转换而来,事宜对象的属性有:

    • type: ‘drag’

    • target: 鼠标点击的draggable元素

    • clientX, clientY: 同mousemove

    • diffX, diffY: 用于校订clientX, clientY与现实要到达的拖动位置的误差。需在dragstart做指定,不然默认值为0

  • dragend:由mouseup转换而来,事宜对象的属性有:

    • type: ‘dragend’

    • target: 鼠标点击的draggable元素

    • clientX, clientY: 同mouseup

api有了,我们就可以挪用enable开启拖动,再和原生的事宜一样给题目中的拖动块增加三个事宜处置惩罚函数即可。只是要注重由于addHandler要领不能指定元素,所以还得在拖动块上增加class="draggable"、并在处置惩罚函数里做个推断才行。利器在手,接下来要做的限定挪动局限、展示坐标、回放拖动等都是小case啦,这题的代码就当是这套api的示例了。

0x2仿腾讯微博结果

完成结果:
6-02仿腾讯微博结果

此次来个大制造,只需再搭个背景弄点数据交互,险些就是一个完全的webApp了。就页面而言,主要就是完成表单猎取数据和数据列表的展示,所以这里离别封装了两个单例MsgFormMsgList对应表单和展示列表,来完成相干的功用。

MsgForm只提供了init要领来增加各个表单组件的事宜监听。该部件最主要的就是对表单的考证了,既要有提交时的考证,也要保证能在输入时立即给出字数提示。正则用的溜的话实在也不难。

至于MsgList则主要完成增删DOM的操纵,难点就是显现和隐蔽两个动画的完成。这里应用setTimeout手动调治出了结果,写得照样比较ugly的,拓展性还不强。

末了注重几个语法上的题目,一是键盘事宜也是可以运用辅佐按键属性:ctrlKey, altKey, shiftKey, metaKey,而不必像第五课做过的一题那样去缓存按键了。第二就是用js猎取的css属性值,不论是经由过程element.style照样window.getComputedStyle(),返回的都是字符串,所以要举行运算只能手动转为数字;这一点和js中猎取宽高、位置的属性如offsetWidth等直接返回数字差别。

0x3自定义多级右键菜单

完成结果:
6-03自定义多级右键菜单

第五课第六题中已经由过程contextmenu事宜完成了一级右键菜单,所以这题只需在上面再增加事宜唤出子菜单即可。

起首处理第五课第六题题在完成时留下的一个bug:菜单有时会显现到容器外。缘由很简单,由于是先定位菜单再显现菜单,致使要依托宽高的定位并不能起作用;所以这里保证菜单先显现出来具有宽高即可。

然后就是完成多级子菜单了,这里直接运用css的hover伪类掌握显隐,只把定位交给mouseover事宜来做即可。由于假如运用mouseovermouseout掌握显隐,由于冒泡的特征会致使移到子菜单前父菜单就已消逝的题目,虽然前面做过的题目有用过setTimeout耽误消逝来处理这一题目的,但如许写起来实在太貌寝了,不斟酌兼容老旧浏览器状况下照样用css做更清楚高效。

至于怎样定位,也是相沿第五课的思绪:设置各级子菜单相对定位;显现菜单时先盘算容器右边和底部的盈余空间;再离别推断可否容得下子菜单的宽高,若容得下则子菜单出现在父元素右下角,不然就做出响应的变化。

末了再总结碰到的几个题目:

  • 子菜单定位时碰到的题目:js的offsetTop, offsetLeft属性取得的都是相对父容器的位置而不是相对位置,要猎取相对位置必需举行向上遍历。

  • 子菜单li元素的宽度不能容得下其文本内容,致使文本摺叠:不设置宽度的相对定位元素,其宽度是由最长的文本内容决议的。若文本自动换行那最长文本就是最长单词罢了,所以得设置white-space: nowrap;使文本不换行,才保证li元素的宽度可以容得下其所有文本内容。而详细关于元素宽高为auto时其宽高在差别状况会遭到什么影响,我会特地写一篇文章来剖析剖析~

—第六课完—

    原文作者:Levon
    原文地址: https://segmentfault.com/a/1190000005117235
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞