以前写过两篇开发中遇到的问题和解决方案。当时是CSS 和 JavaScript 分开写的。如今写这篇文章的时候感受不少内容都是有内在联系的,因此很差分开。javascript
给你们分享一下这半年来的感觉吧:css
知道和理解之间是有很大距离的。别人谈到一个知识点,能接上嘴而且能发表一下本身的意见,这叫知道。遇到问题可以想到用什么知识点解决问题,这叫理解。html
因此有不少知识点本身确实在书上都看到过可是在平时遇到问题的时候殊不知道怎么去用或者说想到去用,有时候会有同事给一下指导说用什么解决问题。关键时候仍是多看(看书,看别人的代码)和多用。前端
display:none
关闭一个元素的显示(对布局没有影响);其全部后代元素都也被会被关闭显示。文档渲染时,该元素如同不存在。(不会显示在文档流中的位置,可是 DOM 节点仍会出如今文档流中)visibility:hidden
visibility属性让你可以控制一个图形元素的可见性,可是仍会占用显示时候在文档流中的位置。java
使用 display:none
的时候虽然元素不会显示,可是DOM 节点仍会出现,因此咱们就可使用选择器对该元素进行操做。以下图中的示例:node
这个问题是发生在本身上篇文章《h5端呼起摄像头扫描二维码并解析》中的。详细的代码能够看那篇文章。css3
先看一段html 代码:git
<div class="qr-btn" node-type="qr-btn">扫描二维码1 <input node-type="jsbridge" type="file" name="myPhoto" value="扫描二维码1" /> </div>
以前个人想法是这个样子的:
1.我先触发qr-btn
的 click
事件,在回调中触发 input
的 click
事件click
事件
2.而后触发 input
的 change
事件,获取上传图片的信息。github
按照个人思路代码应该是下面的这个样子的web
//点击父级元素的事件 $('.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(); });
通过个人测试,代码是可以正常的运行的。
那么咱们有没有更好的方法来解决上面的问题呢?请看接下来的内容
先来看 lable
标签的定义:
<label>
标签为input
元素定义标注(标记)。
label
元素不会向用户呈现任何特殊效果。不过,它为鼠标用户改进了可用性。若是您在 label 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。<label>
标签的 for
属性应当与相关元素的 id 属性相同。
看想一下 w3school 的示例代码和效果:
<form> <label for="male">Male</label> <input type="radio" name="sex" id="male" /> <br /> <label for="female">Female</label> <input type="radio" name="sex" id="female" /> </form>
效果以下图:
到这里应该之道咱们该怎么改进咱们的代码了,
<lable class="qr-btn" node-type="qr-btn" for="qr-input">扫描二维码1 <input node-type="jsbridge" id="qr-input" type="file" name="myPhoto" value="扫描二维码1" /> </lable>
除了 lable 标签的样式咱们本身须要本身定义外,还有两个优势:
减小了 JavaScript 的书写;
lable
标签和 input
标签没有必要是包含关系
最近作了一个抽奖的活动,其中就有一个轮盘的旋转的动画效果(注意啦,中间的那个卡顿是 gif 图片又从新开始播放了)。,效果以下图:
关于动画实如今下一篇文章中会继续介绍,这里主要来关注下布局的问题。由于咱们页面会在 pc 和移动移动各出一套。因此在 pc 和移动我分别用了两种方案,pc 传统布局实现,h5 "弹性盒"实现。
外围的那些灯是使用绝对定位来作的,就不过过多的介绍,主要的是看中间的奖品九宫格的部分。html 代码以下:
<div class="re-middle"> <div class="row-a" node-type="row-a"> <div>mac pro</div> <div>扫地机器人</div> <div>iphone6s</div> </div> <div class="row-b" node-type="row-b"> <div>20积分</div> <div></div> <div>优惠券</div> </div> <div class="row-c" node-type="row-c"> <div>ps4</div> <div> <p>猴年限定</p>公仔</div> <div>祝福红包</div> </div> <div node-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: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; } .row-a div, .row-b div, .row-c div { -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: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; } .row-a div, .row-b div, .row-c div { -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-a div, .row-b div, .row-c div { -webkit-box-flex: 1; -webkit-flex: 1; -ms-flex: 1; flex: 1; border: 1px solid #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; }
与 h5 端相比,我在 pc 端的实现是传统的浮动方式.个人 HTML 代码以下:
<div class="re-middle"> <div class="row-a"> <div>mac pro</div> <div class="row-a-sec">祝福红包</div> <div class="row-a-last"> iphone 6s</div> </div> <div class="row-b clearfix"> <div>优惠券</div> <div class="row-b-sec"></div> <div class="row-b-last">20积分</div> </div> <div class="row-c"> <div>扫地机器人</div> <div class="row-c-sec">猴年限定 <p>公仔</p> </div> <div class="row-c-last">ps4</div> </div> <div class="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-b div { float: left; width: 176px; height: 106px; text-align: center; line-height: 106px; background-color: #f69f75; }
由上面的 css 代码对比看咱们能够显然看出传统的浮动方式的布局和“弹性盒”布局的一些优缺点:
float
布局代码简洁,可是必须肯定的指定盒子的宽度和高度,多屏幕的适配上会差一些(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; }
在作“跑马灯”插件的时候遇到了一个问题,就是用户点击开始抽奖按钮之后在尚未返回结果的时候用户又第二次点击抽奖按钮,那个时候机会出现“奇葩”的问题。好比说:第一次请求和第二次请求重合返回的结果显示哪个,就算容许用户进行二次抽奖,交互也不友好。并且若是前端页面不作限制的话,显示也会出现奇葩的问题。好比下面这样:
这样是否是很糟糕啊。。。
那么我是怎么解决这个问题呢?
答案很简单,我就是在点击按钮以后,使用绝对定位弹起了一个透明的弹层,将按钮给覆盖,等结果返回并显示之后,我在同时去掉弹层。这样就避免了用户的重复提交。详细看一下代码:
<div node-type="cover_layer"></div>
.cover-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'); ..... });
此次的分享就到这里,下一次会分享“轮盘”抽奖效果的 JavaScript 开发过程。