之前写过两篇开发中遇到的问题和解决方案。
当时是css和JavaScript分开写的。
现在写这篇文章的时候感觉很多内容都是有内在联系的,所以不好分开。
给大家分享一下这半年来的感受吧:知道和理解之间是有很大距离的。
别人谈到一个知识点,能接上嘴并且能发表一下自己的意见,这叫知道。
遇到问题能够想到用什么知识点解决问题,这叫理解。
所以有很多知识点自己确实在书上都看到过但是在平时遇到问题的时候却不知道怎么去用或者说想到去用,有时候会有同事给一下指导说用什么解决问题。
关键时候还是多看(看书,看别人的代码)和多用。
1.display:none;
和visibility:hidden;
的区别display:none关闭一个元素的显示(对布局没有影响);其所有后代元素都也被会被关闭显示。
文档渲染时,该元素如同不存在。(不会显示在文档流中的位置,但是DOM节点仍会出现在文档流中)visibility:hiddenvisibility属性让你能够控制一个图形元素的可见性,但是仍会占用显示时候在文档流中的位置。
使用display:none的时候虽然元素不会显示,但是DOM节点仍会出现,所以我们就可以使用选择器对该元素进行操作。
如下图中的示例:2.事件冒泡引发的问题这个问题是发生在自己上篇文章《HTML5端呼起摄像头扫描二维码并解析》中的。
详细的代码可以看那篇文章。
问题发生的场景先看一段html代码:
<
divclass=”qr-btn”
node-type=”qr-btn”>扫描二维码1<inputnode-type=”jsbridge”
type=”file”
name=”myPhoto”
value=”扫描二维码1″/></div>123<divclass=”qr-btn”node-type=”qr-btn”>扫描二维码1<inputnode-type=”jsbridge”type=”file”name=”myPhoto”value=”扫描二维码1″/></div>之前我的想法是这个样子的:1.我先触发qr-btn的click事件,在回调中触发input的click事件click事件2.然后触发input的change事件,获取上传图片的信息。
按照我的思路代码应该是下面的这个样子的点击父级元素的事件$(‘.qr-btn’).bind(‘click’,function(){
触发子元素的事件$(‘[node-type=jsbridge]’).trigger(“click”);
});
$(‘[node-type=jsbridge]’).bind(‘change’,function(){
做一些事情
});
12345678点击父级元素的事件$(‘.qr-btn’).bind(‘click’,function(){
触发子元素的事件$(‘[node-type=jsbridge]’).trigger(“click”);
});
$(‘[node-type=jsbridge]’).bind(‘change’,function(){
做一些事情
});
上面的代码,按照正常的思路应该是没有问题的,但是,在实际的运行过程中却发生了问题。
浏览器的报错信息如下:这是因为堆栈溢出的问题。
那么为什么会出现这样的问题呢?我把断点打在了以下的位置,然后点击子元素发生的情况是:代码无限次的触发$(‘.qr-btn’).bind(…),就出现了上面的报错信息。
那么是什么原因导致的呢?思考一下发现:是因为事件冒泡的问题。
我单击父元素触发子元素的click事件,子元素的click事件又冒泡到父元素上,触发父元素的click事件,然后父元素再次触发了子元素的click事件,这就造成了事件的循环。
问题解决办法:尝试阻止事件的冒泡,看能够解决问题?那我们尝试在触发子元素的click的时候,尝试组织子元素的冒泡,看能否解决我的问题?添加如下的代码:$(‘[node-type=jsbridge]’).bind(‘click’,function(e){
console.log(e.type);
e.stopPropagation();
});
1234$(‘[node-type=jsbridge]’).bind(‘click’,function(e){
console.log(e.type);
e.stopPropagation();
});
经过我的测试,代码是能够正常的运行的。
那么我们有没有更好的方法来解决上面的问题呢?请看接下来的内容3.lable标签的
for属性先来看lable标签的定义:标签为input元素定义标注(标记)。
label元素不会向用户呈现任何特殊效果。
不过,它为鼠标用户改进了可用性。
如果您在label元素内点击文本,就会触发此控件。
就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。
标签的
for属性应当与相关元素的id属性相同。
看想一下w3school的示例代码和效果:<form><label
for=”male”>Male</label><inputtype=”radio”
name=”sex”
id=”male”/><br/><label
for=”female”>Female</label><inputtype=”radio”name=”sex”id=”female”/></form>12345<form><labelfor=”male”>Male</label><inputtype=”radio”
name=”sex”
id=”male”/><br/><label
for=”female”>Female</label><inputtype=”radio”name=”sex”id=”female”/></form>效果如下图:到这里应该之道我们该怎么改进我们的代码了,<lableclass=”qr-btn”node-type=”qr-btn”for=”qr-input”>扫描二维码1<inputnode-type=”jsbridge”id=”qr-input”type=”file”name=”myPhoto”value=”扫描二维码1″/></lable>123<lableclass=”qr-btn”node-type=”qr-btn”for=”qr-input”>扫描二维码1<inputnode-type=”jsbridge”id=”qr-input”type=”file”name=”myPhoto”value=”扫描二维码1″/></lable>除了lable标签的样式我们自己需要自己定义外,还有两个优点:减少了JavaScript的书写;lable标签和input标签没有必要是包含关系4.“弹层盒”布局和普通盒模型布局的优缺点对比最近做了一个抽奖的活动,其中就有一个轮盘的旋转的动画效果(注意啦,中间的那个卡顿是gif图片又重新开始播放了)。
效果如下图:关于动画实现在下一篇文章中会继续介绍,这里主要来关注下布局的问题。
因为我们页面会在pc和移动移动各出一套。
所以在pc和移动我分别用了两种方案,pc传统布局实现,HTML5“弹性盒”实现。
1.弹性盒实现九宫格外围的那些灯是使用绝对定位来做的,就不过过多的介绍,主要的是看中间的奖品九宫格的部分。
html代码如下:<divclass=”re-middle”><divclass=”row-a”
node-type=”row-a”><div>macpro</div><div>扫地机器人</div><div>iphone6s</div></div><divclass=”row-b”
node-type=”row-b”><div>20积分</div><div></div><div>优惠券</div></div><divclass=”row-c”
node-type=”row-c”><div>ps4</div><div><p>猴年限定</p>公仔</div><div>祝福红包</div></div><divnode-type=”reward-layer”></div></div>12345678910111213141516171819<divclass=”re-middle”><divclass=”row-a”
node-type=”row-a”><div>macpro</div><div>扫地机器人</div><div>iphone6s</div></div><divclass=”row-b”
node-type=”row-b”><div>20积分</div><div></div><div>优惠券</div></div><divclass=”row-c”
node-type=”row-c”><div>ps4</div><div><p>猴年限定</p>公仔</div><div>祝福红包</div></div><divnode-type=”reward-layer”></div></div>css代码如下:.re-middle{position:absolute;width:28.3rem;height:16rem;top:0;left:0;right:0;bottom:0;margin:auto;background-color:#f69f75;color:#ffdece;font-size:1.8rem;}.row-a,.row-b,.row-c{height:5.3rem;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:rownowrap;-ms-flex-flow:rownowrap;flex-flow:rownowrap;}.row-adiv,.row-bdiv,.row-cdiv{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;text-align:center;line-height:5.3rem;background-color:#f69f75;}123456789101112131415161718192021222324252627282930313233343536.re-middle{position:absolute;width:28.3rem;height:16rem;top:0;left:0;right:0;bottom:0;margin:auto;background-color:#f69f75;color:#ffdece;font-size:1.8rem;}.row-a,.row-b,.row-c{height:5.3rem;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:rownowrap;-ms-flex-flow:rownowrap;flex-flow:rownowrap;}.row-adiv,.row-bdiv,.row-cdiv{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;text-align:center;line-height:5.3rem;background-color:#f69f75;}由上面的css代码可以看出来我仅仅是在水平方向上使用了“弹性盒”,而在竖直的方向上,还是使用了固定高度(因为我是用的rem单位,这里的固定也是不准确的,高度会根据fontsize值进行计算。)那么可不可以在竖直和水平都是用“弹性盒”呢?来看一下下面的css代码:.re-middle{position:absolute;width:28.3rem;height:16rem;top:0;left:0;right:0;bottom:0;margin:auto;background-color:#f69f75;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:#ffdece;font-size:1.8rem;}.row-a,.row-b,.row-c{/*height:5.3rem;*/-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:rownowrap;-ms-flex-flow:rownowrap;flex-flow:rownowrap;}.row-adiv,.row-bdiv,.row-cdiv{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;text-align:center;line-height:5.3rem;background-color:#f69f75;/*position:relative;*/-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354.re-middle{position:absolute;width:28.3rem;height:16rem;top:0;left:0;right:0;bottom:0;margin:auto;background-color:#f69f75;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:#ffdece;font-size:1.8rem;}.row-a,.row-b,.row-c{/*height:5.3rem;*/-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:rownowrap;-ms-flex-flow:rownowrap;flex-flow:rownowrap;}.row-adiv,.row-bdiv,.row-cdiv{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;text-align:center;line-height:5.3rem;background-color:#f69f75;/*position:relative;*/-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;}周末的时候关于这个布局自己又翻书看了下“弹性盒”的文档,终于实现了在竖直和垂直方向上都实现内容的水平垂直居中内部元素。
其实上面的代码只需要把内容的父级元素再次定义为display:flex再添加两个属性justify-content和align-items就可以了。
前者是控制弹性盒的内容垂直方向居中,后者控制内容水平方向居中。
详细代码如下:.row-adiv,.row-bdiv,.row-cdiv{
-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;
flex:1;
border:1pxsolid#000;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}123456789101112131415161718192021.row-adiv,.row-bdiv,.row-cdiv{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;border:1pxsolid#000;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;
align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;
justify-content:center;
display:-webkit-box;
display:-webkit-flex;
display:-ms-flexbox;
display:flex;
}
2.传统方式实现与HTML5端相比,我在pc端的实现是传统的浮动方式.我的html代码如下:<divclass=”re-middle”><divclass=”row-a”><div>macpro</div><divclass=”row-a-sec”>祝福红包</div><divclass=”row-a-last”>iphone6s</div></div><divclass=”row-bclearfix”><div>优惠券</div><divclass=”row-b-sec”></div><divclass=”row-b-last”>20积分</div></div><divclass=”row-c”><div>扫地机器人</div><divclass=”row-c-sec”>猴年限定<p>公仔</p></div><divclass=”row-c-last”>ps4</div></div><divclass=”reward-btn”></div></div>1234567891011121314151617181920<divclass=”re-middle”><divclass=”row-a”><div>macpro</div><divclass=”row-a-sec”>祝福红包</div><divclass=”row-a-last”>iphone6s</div></div><divclass=”row-bclearfix”><div>优惠券</div><divclass=”row-b-sec”></div><divclass=”row-b-last”>20积分</div></div><divclass=”row-c”><div>扫地机器人</div><divclass=”row-c-sec”>猴年限定<p>公仔</p></div><divclass=”row-c-last”>ps4</div></div><divclass=”reward-btn”></div></div>css代码如下:.re-middle{
background-color:#f89f71;
width:530px;
height:320px;
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
margin:auto;
}.row-a,.row-b,.row-c{
/*height:106px;*/
font-size:0;
overflow:hidden;
}.row-a>div,.row-c>div{
float:left;width:176px;height:106px;text-align:center;
}.row-bdiv{
float:left;width:176px;height:106px;text-align:center;line-height:106px;background-color:#f69f75;
}
123456789101112131415161718192021222324252627282930313233.re-middle{
background-color:#f89f71;
width:530px;
height:320px;
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
margin:auto;
}.row-a,.row-b,.row-c{
/*height:106px;*/
font-size:0;
overflow:hidden;
}.row-a>div,.row-c>div{
float:left;width:176px;height:106px;text-align:center;
}.row-bdiv{
float:left;width:176px;height:106px;text-align:center;line-height:106px;background-color:#f69f75;
}
由上面的css代码对比看我们可以显然看出传统的浮动方式的布局和“弹性盒”布局的一些优缺点:float布局代码简洁,但是必须确定的指定盒子的宽度和高度,多屏幕的适配上会差一些(rem动态计算除外)。
布局代码简洁,但是必须确定的指定盒子的宽度和高度,多屏幕的适配上会差一些(rem动态计算除外)。“弹性盒”布局代码使用新的css3属性,需要添加额外的厂商前缀,增加了代码的复杂度(添加厂商前缀可以使用sublime插件,一键完成,推荐我的文章前端开发工程师的sublime配置)“弹性盒”为多屏幕的适配提供了便利性。
我不用去关心子元素的宽度和高度是多少,或者是屏幕的宽度是多少,都会根据实际请款flex自身会去适配。
遇到的一个小问题,多行文本的处置居中:这个九宫格内的文本元素,如果只是单行的话,只要使用line-height就可以解决问题,但是如果多行呢?会出什么情况呢,看下图:所以这里只能考虑不使用line-height,使用padding来解决问题,尝试padding后的效果。
如下图:可以看到容器的下面多出了一部分。
那也是我们使用的padding的问题,那么怎么解决这个问题呢?这就要用到之前提到过的box-sizing来解决问题。
.row-c-sec{
color:#ffdece;font-size:30px;padding-top:17px;background-color:#f69f75;
/*使容器的高=内容高度+padding+border*/
box-sizing:border-box;
}
12345678.row-c-sec{
color:#ffdece;font-size:30px;padding-top:17px;background-color:#f69f75;
/*使容器的高=内容高度+padding+border*/
box-sizing:border-box;
}
5.按钮多次提交的解决方案在做“跑马灯”插件的时候遇到了一个问题,就是用户点击开始抽奖按钮以后在还没有返回结果的时候用户又第二次点击抽奖按钮,那个时候机会出现“奇葩”的问题。
比如说:第一次请求和第二次请求重合返回的结果显示哪一个,就算允许用户进行二次抽奖,交互也不友好。而且如果前端页面不做限制的话,显示也会出现奇葩的问题。
比如下面这样:这样是不是很糟糕啊。
那么我是怎么解决这个问题呢?答案很简单,我就是在点击按钮之后,使用绝对定位弹起了一个透明的弹层,将按钮给覆盖,等结果返回并显示以后,我在同时去掉弹层。
这样就避免了用户的重复提交。
详细看一下代码:<divnode-type=”cover_layer”></div>1<divnode-type=”cover_layer”></div>cover-layer{
width:100%;height:100%;top:0;position:absolute;z-index:9999;
}
1234567cover-layer{
width:100%;height:100%;top:0;position:absolute;z-index:9999;
}
这里保证我的这个透明的弹层能够覆盖在抽奖按钮的上面。
当然这个class是我通过JavaScript动态的添加和删除的。
$(node).on(‘clcik’,’.reward-btn’,function(){
呼起弹层$(‘[node-type=cover_layer]’,node).addClass(‘cover-layer’);…..返回结果以后去掉弹层$(‘[node-type=cover_layer]’,node).removeClass(‘cover-layer’);…..
});
12345678$(node).on(‘clcik’,’.reward-btn’,function(){
呼起弹层$(‘[node-type=cover_layer]’,node).addClass(‘cover-layer’);…..返回结果以后去掉弹层$(‘[node-type=cover_layer]’,node).removeClass(‘cover-layer’);…..
});
这次的分享就到这里,下一次会分享“轮盘”抽奖效果的JavaScript开发过程。
评论前必须登录!
注册