一、preventDefault()和stopPropagation()区分
事件捕获阶段:1、2、3
处于目标阶段:4
事件冒泡阶段:5、6、7
1.preventDefault()表示阻止特定事件的默认行为。例如链接的导航行为,submit提交表单的行为。preventDefault()不阻止事件进一步捕获或冒泡,也不阻止自定义事件。
2.”DOM2级事件”定义了addEventListener(“click”,function(){},false)方法。第三个参数为true表示在捕获阶段处理事件;为false表示在冒泡阶段处理事件。
3.e.stopPropagation()会阻止事件进一步捕获或冒泡,当前事件会执行完,后续事件将不会被触发。但是如果对元素分别定义了捕获阶段(第三个参数为true)和冒泡阶段(第三个参数为false)的事件,则这两个事件都会执行。
二、弹出内容显示不全完美解决方案
问题描述:在项目中遇到靠近屏幕底部列表项点击时弹出内容显示不全的问题。如下图所示,点击该条持仓记录时,弹出的“开仓-平仓-行情”栏显示不全。
要保证底部有可能被挡住的弹出栏在任何情况下都能正常显示,需要经过一些计算处理,详细的页面高度十分复杂,详情可见该条底部的分析图,此处只介绍用的到的高度值。下面详细介绍处理方法。实现效果可看“牛倍”期货和A股的持仓盈亏列表。
1.判断被点击的列表项的弹出栏是否会显示不全:
列表项的顶部偏移+列表项的高度+弹出栏的高度>窗口底部偏移
2.如果1为false,那么让弹出栏默认向下弹出(这种默认弹出方式符合用户使用习惯)。
3.如果1为true,那么让列表项向上滚动,同时弹出栏弹出,并让弹出栏底部刚好贴住窗口底部,计算向上滚动的距离:
向上滚动距离=列表项的顶部偏移+列表项的高度+弹出栏的高度-窗口底部偏移
4.将公式中的变量全部使用实际属性来代替:
列表项的顶部偏移:$listitem.offset().top;
(注:offset()为jquery计算元素偏移的方法)
列表项的高度:$listitem.offset().height;
弹出栏的高度:$outitem.offset().height;
窗口底部偏移:$("body").scrollTop()+document.documentElement.clientHeight;
(注:窗口底部偏移=窗口向下滚动偏移+窗口高度)
(tips:页面的总高度: document.body.clientHeight;)
5.得到最终的相关代码如下:
//计算窗口底部偏移 var page_top=$("body").scrollTop()+document.documentElement.clientHeight; //计算列表项顶部偏移 var element_top=$n.offset().top; //计算列表项高度 var element_height=$n.offset().height; //计算滚动距离,40为弹出栏的高度 var distance=40+element_height+element_top-page_top; //滚动距离<0说明能够完整显示,无需滚动;滚动距离>0需要滚动 if(distance>0){ //进行向上滚动操作,滚动距离为distance }
三、$(this)和this的区别
this指向调用该方法的对象,可以调用js方法,可以获取HTML元素属性;不能调用jQuery方法。
$(this)将this封装成为jQuery对象,从而能够调用jQuery方法;不能直接获取HTML元素属性,不能调用js方法。
四、线程怪象,简单的处理使用setTimeout()
浏览器有三个基本的线程:js线程,gui线程,请求线程。js本身是单线程的,ajax实现的异步请求是基于浏览器本身的机制,而js线程和gui线程互斥(未来将详细分析浏览器堆栈、线程关系)。在项目中遇到过两个奇怪的问题,这两个问题的原因至今也只停留在推测阶段。第一个是有些输入法存在确认输入的阶段,在此阶段使用js执行基于输入内容的视图操作就会出现二次刷新的怪象;另一个问题为在A股渲染“暂无持仓”内容后20%的几率会覆盖渲染,导致“暂无持仓”消失,目前考虑为使用的框架中某些异步操作引起。这类奇怪问题目前我给出的解决方案都是setTimeout()延时执行,在设定定时器在一个时间段(大约300毫秒)以外时,操作将不会被覆盖。问题虽然暂时解决了,但是,使用setTimeout()将会使程序的时序更加混乱,导致未来出现错误更加难以分析和捕捉,因此长远角度考虑并不推荐使用。
五、手机端三等分按钮兼容性问题小结
问题描述:相关bug:22990,24476,24842最原始的切图css样式为:
.ranking-tab{ position: relative; width: 5.97rem; height: 0.58rem; margin: 0.15rem auto; line-height: 0.58rem; text-align: center; border: 1px solid #fa5d5d; } .ranking-tab li{ position: relative; height: 100%; float: left; background: #fff; border-right:1px solid #fa5d5d; box-sizing: border-box; } .ranking-tab li:last-child{ border-right: none; } .am-grid-item-33{width:33.333%}
这样的设计下,“本日”、“本周”、“总”排行按钮分别占据行宽的33.333%,在部分小屏幕手机上都能够正常显示,但是在类似于iphone6、三星s6这样的大屏幕手机上就会出现下图所示问题,右边出现一条细小的白色边线,原因为填充不全。
1.第一次修改方案为将“总排行”按钮的宽度设置为33.334%,这样三个按钮加起来就沾满了100%的宽度。
2.但是问题并没有解决。安卓大屏手机经过这样的修改之后能够正常显示,而iphone6仍然没有变化,右边依然会出现白色边线。经测试,发现iphone6无法识别css样式小数点3位(包括第3位)以后的数字,因此这里讲“总排行”按钮的宽度再修改为33.34%,大屏手机全部正常显示(虽然三个按钮的总宽度超过100%,但是通过box-sizing属性使他们仍在一行显示)。
3.iphone4出现右部白色边线问题,尝试将总宽度设置成6em,每个按钮设置为2em宽度,和全部33.333%并没有任何区别,也采用过flex布局方案,但仍然存在兼容性问题。采用折中的办法,将背景色设置为红色,但是并没有从根本解决问题,效果如图:
4.最终这样缝缝补补的修改通不过测试,还是从最基本的底层来分析css代码。大千世界有许多类型的手机,要想基于三等分来布局,使用33.333%就很有风险,也许有的手机只支持33%,那么右边就会出现1%的边线。因此将原来ul的border设置到li上,这样即使li并没有在某些特殊机型上100%填充满ul,我们看到的效果仍然是正常的,背景色将和ul融为一体。最终布局方案如下:
.ranking-tab{ position: relative; width: 5.97rem; height: 0.58rem; margin: 0.15rem auto; line-height: 0.58rem; text-align: center; } .ranking-tab li{ position: relative; height: 100%; float: left; background: #fff; border:1px solid #fa5d5d; border-right: none; box-sizing: border-box; } .ranking-tab li:last-child{ border-right:1px solid #fa5d5d;} .am-grid-item-33{width:33.333%}
其中值得讲解的一点是必须设置:
li{ border-right:none; } li:last-child{ border-right:1px solid #fa5d5d; }
如果不这样处理,前一个按钮的右边界将会和后一个按钮的左边界重合,变成2px。
至此,走了一大圈弯路之后,排名页按键兼容性问题彻底解决。