实现元素居中的多种方案

最近学习flex弹性布局,新了解了几种元素居中方案,所以来做个总结 , 如果后续有比较实用的方案,我会继续追加到文章后面, 代码已经上传至Github

web_center_demo

1. margin:0 auto;实现水平居中

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>margin_0_auto</title>
<style>
body{margin: 0;padding: 0}
/*要使用margin:0 auto实现居中, 这个元素就必须有固定的宽度 , 并且不能有position这个属性 ,不然都使用无效(不受float的影响)*/
.father{width: 900px;
height: 900px;
margin: 0 auto;
background-color: pink;
}
</style>
</head>
<body>

<div class="father">

</div>

</body>
</html>

2.flex实现水平居中或者垂直居中(CSS3属性,完美兼容移动端)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flexbox</title>

<style>
body{margin: 0;}

.father{
position:fixed;
width:100%;
height:100%;
background:rgba(0,0,0,0.5);
left:0px;
top:0px;
display:flex;
/*子元素水平居中*/
justify-content:center;
/*子元素垂直居中*/
align-items:center;
}

</style>

</head>
<body>

<div class="father">
<img src="1.jpg">
</div>

</body>
</html>

3.vertical-align:middle实现水平垂直居中

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
body{margin: 0;}
.father{width: 100%;height: 100%;position: fixed;left: 0;top: 0;text-align: center;font-size: 0;/*设置font-size为了消除代码换行所造成的空隙*/background:rgba(0,0,0,0.5); }
.daughter{vertical-align: middle;}/*实现daughter居中*/
.son{vertical-align: middle;display:inline-block;height: 100%;}
</style>
</head>
<body>
<div class = "father">
<div class="son"></div>
<img class = "daughter" src="1.jpg" alt="我要居中">
</div>
</body>
</html>

4.定位和需要定位的元素的margin减去宽高的一半

这种方法的局限性在于需要知道需要垂直居中的宽高才能实现,经常使用这种方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>one half</title>
<style>
*{
padding: 0;
margin: 0;
}
.box{
width: 300px;
height: 300px;
background:#e9dfc7;
border:1px solid red;
position: relative;
}
img{
width: 100px;
height: 150px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -75px;
margin-left: -50px;
}
</style>
</head>
<body>

<!--html -->
<body>
<div class="box" >
<img src="1.jpg" alt="">
</div>
</body>

</body>
</html>

5.使用transform实现居中

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>transform</title>
<style>
body{margin: 0;}

.father {
/*绝对定位*/
position: absolute;
left:50%;
top:50%;
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
background:rgba(0,0,0,0.5);
}

</style>
</head>
<body>
<div class="father">
<img src="1.jpg">
</div>
</body>

</html>

6.使用text-align=center实现居中

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>text_align</title>

<style>

*{
padding: 0;
margin: 0;
}
.box{
width: 300px;
height: 300px;
border: 3px solid red;
text-align: center;
}
img{
/*指定对象为内联块元素*/
display: inline-block;
width: 100px;
height: 100px;
/*margin: 0 auto;*/
}

</style>
</head>
<body>
<div class="box">
<img src="1.jpg" alt="">
</div>
</body>

</html>

(完)

分享到

关于HTML5

关于HTML5

HTML5 中的一些有趣的新特性:

1、用于绘画的 canvas 元素
2、用于媒介回放的 video 和 audio 元素

demo:

<video width="320" height="240" controls="controls">
可以写多个...当当第一个不支持的话用第二个
第二个.......
直到显示不支持
你浏览器不支持video
</video>

同理:
<audio controls="controls">

你浏览器不支持audio
</audio>
3、对本地离线存储的更好的支持
4、地理定位 navigator.geolocation.getCurrentPosition(callback,error,options)
5、新的特殊内容元素,比如 article、footer、header、nav、section
6、新增XmlHttpRequest level 2 , 可以更好的解决跨域问题 (IE10以上兼容)
7、WebSocket 协议
8、新的表单控件:
email
url
number
range (滑动条)
Date pickers (date, month, week, time, datetime, datetime-local)
search
color

后续了解新的HTML5知识会继续补充

(完)

分享到

XmlHttpRequest发送请求与得到响应

XmlHttpRequest,中文可以解释为可扩展超文本传输请求。Xml可扩展标记语言,Http超文本传输协议,Request请求。

XMLHTTP是一组API函数集,可被JavaScript、JScript、VBScript以及其它web浏览器内嵌的脚本语言调用,通过HTTP在浏览器和web服务器之间收发XML或其它数据。XMLHTTP最大的好处在于可以动态地更新网页,它无需重新从服务器读取整个网页,也不需要安装额外的插件。该技术被许多网站使用,以实现快速响应的动态网页应用。例如:Google的Gmail服务、Google Suggest动态查找界面以及Google Map地理信息服务。

XMLHTTP是AJAX网页开发技术的重要组成部分。

除XML之外,XMLHTTP还能用于获取其它格式的数据,如JSON或者甚至纯文本。

(来自维基百科)

XHR发送请求

1、open方法:

参数:

  1. method:发送请求方法,get方式还是post方式,不区分大小写,一般使用大写。
  2. url:请求地址,可以使用相对地址,也就是相对文档的地址,也可以使用绝对地址。
  3. async:请求同步/异步,一般使用异步请求,这个参数就是true,如要使用同步的话,就是false。默认的是true(异步),所以,如果是异步请求的话,这个参数可以不写。

2、send方法:

send方法将请求发送到服务器上

参数:

string:

  • 使用get请求时,实际是没有主体的,所有的参数都拼在url中,所以send参数可以不填,或者填写null。

  • post请求时,send请求一定要有参数。

XHR获取服务器的响应

一个标准的获取服务器响应的实例

if (xmlHttp) {
xmlHttp.open('GET', the_request_url, true);
xmlHttp.onreadystatechange=function(){
if (xmlHttp.readyState==4) {
if (xmlHttp.status==200) {
<!--dosomething.... 比如xmlHttp.responseText-->
}
}
};
xmlHttp.send(null);
}

onreadystatechange事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。

readyState属性

此属性的变化代表了服务器的响应变化

0:没初始化,open没调用

1:服务器连接已建立,open已经调用

2:服务器已经接收到头信息了

3:服务器接收到响应主体了

4:响应完成

  • responseText:获得字符形式的响应数据
  • responseXML:获得XML形式的响应数据
  • status和statusText:以数字和文本形式返回HTTP状态码
  • getAllResponseHeader():获取所有的响应报头
  • getResponseHeader():查询响应中的某个字段的值

当 readyState 等于 4 且状态为 200 时,表示响应已就绪

典型的XHR建立一个ajax请求(异步请求)
1、var request=new XMLHttpRequest():
2、构造方法request.open("GET","get.php",true);
3、send一些数据request.send();
4、对过程监听
if(request.readyState===4&&request.status===20){
//做一些事情request.responseText
}
}

(完)

分享到

HTTP协议学习总结

什么是协议

  • 现实生活中的协议,相互遵守,单方面违背,协议不成立; (停战协议,全球贸易协议)

  • 互联网中的协议,ftp、http、stmp、TCP/IP…

什么是HTTP

HTTP-Hypertext transfer protocol:超文本传输协议,详细的规定了万维网服务 器与客户端之间数据传送的通信规则

当你在浏览器输入一个网址并敲下回车键的一刻,发生了什么?

image

HTTP属于无状态连接,有状态连接(持续连接) 比如有qq,微信等等,使用的是不同的协议

一次完整的HTTP请求, 通常有下面七个步骤

  1. 建立TCP连接
  2. web浏览器向web服务器发送请求命令
  3. web浏览器发送请求头信息
  4. web服务器应答
  5. web服务器发送应答头信息
  6. web服务器向浏览器发送数据

HTTP请求一般由四个部分组成:

  1. HTTP请求的方法或动作,比如GET或者POST请求
  2. 正在请求的URL
  3. 请求头,包含一些客户端环境信息,身份验证信息等
  4. 请求体,也就是请求正文,请求正文中可以包含客户提交的查询字符串信息,表单信息等等

格式如下图

image

HTTP的请求方法

  • GET:获取一个URL指定的资源,即资源实体
  • HEAD:获取一个指定资源的信息
  • POST:向服务器提交数据
  • PUT:向服务器提交资源
  • DELETE:请求源服务器删除Request-U RI 标识的资源
  • TRACE:网络跟踪
  • CONNECT:与PROX Y之间的连接管理
  • OPTIONS:查询服务器支持的方法

注:这些方法虽然在HTTP协议里的,但是,服务器并不会对这些方法全部实现

我们常用的请求方法有两种, GET与POST
  • GET: 一般用于信息获取, 使用URL传递参数,对所发送信息的数量也有限制, 一般在2000个字符

  • POST:一般用于修改服务器上的资源,对所发送信息的数量无限制

GET与POST的区别

区别不大,只不过是语义上有区别,所谓的一些什么安全的区别只不过是针对浏览器而言

HTTP中的状态码

由3位数字组成, 其中首位数字定义了状态码的类型, 作用就是提高我们web调试的效率

如图所示

image

推荐书:《HTTP权威指南》

(完)

分享到

Angular双向绑定

angularJS中, 核心是数据, 数据的改变可以导致视图的改变 . 并且视图是局部刷新的,angular会自动识别哪里用到了这个更新的数据, 这个叫做脏检查

在angular中, 最简单的更新视图的方法就是通过表单元素 , 所有的表单控件都可以使用ng-model指令与控制器中的某一个值进行双向数据绑定, 当控制器中的数据改变时, 视图也就改变了 , 视图值变化,又影响了控制器中的值 ….

image

最简单的双向绑定demo
<!DOCTYPE html>
<html lang="en" ng-app='myapp'>
<head>
<meta charset="UTF-8">
<title>easyDemo</title>
<script src="js/lib/angular.js"></script>
</head>
<body>
<!--实例化控制器中的MianCtrl-->
<div ng-controller='MainCtrl as mainctrl'>
<!--使用ng-model通过表单元素实现数据双向绑定-->
<input type="text" ng-model='mainctrl.a'>
<!--MVVM-->
{{mainctrl.a}}
</div>
</body>
<script type="text/javascript">
<!--入口-->
var oMyApp = angular.module('myapp',[]);
<!--创建控制器-->
oMyApp.controller('MainCtrl',[function(){
self=this;
self.a=100;
}]);

</script>
</html>

(完)

分享到

jQuery大纲

jQuery是目前使用最广泛的javascript函数库。
据统计,全世界排名前100万的网站,有46%使用jQuery,远远超过其他库。微软公司甚至把jQuery作为他们的官方库。

【目录】

  •   选择网页元素
  •   改变结果集
  •   链式操作
  •   元素的操作:取值和赋值
  •   元素的操作:移动
  •   元素的操作:复制、删除和创建
  •   工具方法
  •   事件操作
  •   特殊效果   

【正文】

一、选择网页元素

jQuery的基本设计思想和主要用法,就是”选择某个网页元素,然后对其进行某种操作”。这是它区别于其他Javascript库的根本特点。
使用jQuery的第一步,往往就是将一个选择表达式,放进构造函数jQuery()(简写为$),然后得到被选中的元素。
选择表达式可以是CSS选择器:

  

$(document) //选择整个文档对象

  

$('#myId') //选择ID为myId的网页元素

 

$('div.myClass') // 选择class为myClass的div元素

 

$('input[name=first]')//选择name属性等于first的input元素

  
也可以是jQuery特有的表达式:

  

$('a:first') //选择网页中第一个a元素

 

$('tr:odd') //选择表格的奇数行

  

$('#myForm :input') // 选择表单中的input元素

  

$('div:visible') //选择可见的div元素

  

$('div:gt(2)') // 选择所有的div元素,除了前三个

  

$('div:animated') // 选择当前处于动画状态的div元素

  

二、改变结果集

jQuery设计思想之二,就是提供各种强大的过滤器,对结果集进行筛选,缩小选择结果。

  

$('div').has('p'); // 选择包含p元素的div元素

  

$('div').not('.myClass'); //选择class不等于myClass的div元素

  

$('div').filter('.myClass'); //选择class等于myClass的div元素

  

$('div').first(); //选择第1个div元素

  

$('div').eq(5); //选择第6个div元素

  
有时候,我们需要从结果集出发,移动到附近的相关元素,jQuery也提供了在DOM树上的移动方法:
  

$('div').next('p'); //选择div元素后面的第一个p元素

 

$('div').parent(); //选择div元素的父元素

  

$('div').closest('form'); //选择离div最近的那个form父元素

  

$('div').children(); //选择div的所有子元素

  

$('div').siblings(); //选择div的同级元素

三、链式操作

jQuery设计思想之三,就是最终选中网页元素以后,可以对它进行一系列操作,并且所有操作可以连接在一起,以链条的形式写出来,比如:
  

$('div').find('h3').eq(2).html('Hello');

分解开来,就是下面这样:  

$('div') //找到div元素
.find('h3') //选择其中的h3元素
.eq(2) //选择第3个h3元素
.html('Hello'); //将它的内容改为Hello

这是jQuery最令人称道、最方便的特点。它的原理在于每一步的jQuery操作,返回的都是一个jQuery对象,所以不同操作可以连在一起。
jQuery还提供了.end()方法,使得结果集可以后退一步:
 

$('div')
   .find('h3')
   .eq(2)
   .html('Hello')
   .end() //退回到选中所有的h3元素的那一步
   .eq(0) //选中第一个h3元素
   .html('World'); //将它的内容改为World

四、元素的操作:取值和赋值

操作网页元素,最常见的需求是取得它们的值,或者对它们进行赋值。
jQuery设计思想之四,就是使用同一个函数,来完成取值(getter)和赋值(setter),即”取值器”与”赋值器”合一。到底是取值还是赋值,由函数的参数决定。

 

$('h1').html(); //html()没有参数,表示取出h1的值

 

$('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值

  
常见的取值和赋值函数如下:

.html()    取出或设置html内容
  .text() 取出或设置text内容
  .attr() 取出或设置某个属性的值
  .width() 取出或设置某个元素的宽度
  .height() 取出或设置某个元素的高度
  .val() 取出某个表单元素的值

需要注意的是,如果结果集包含多个元素,那么赋值的时候,将对其中所有的元素赋值;取值的时候,则是只取出第一个元素的值(.text()例外,它取出所有元素的text内容)。

五、元素的操作:移动

jQuery设计思想之五,就是提供两组方法,来操作元素在网页中的位置移动。一组方法是直接移动该元素,另一组方法是移动其他元素,使得目标元素达到我们想要的位置。
假定我们选中了一个div元素,需要把它移动到p元素后面。

  • 第一种方法是使用.insertAfter(),把div元素移动p元素后面:   

    $('div').insertAfter($('p'));
  • 第二种方法是使用.after(),把p元素加到div元素前面:   

    $('p').after($('div'));

表面上看,这两种方法的效果是一样的,唯一的不同似乎只是操作视角的不同。但是实际上,它们有一个重大差别,那就是返回的元素不一样。第一种方法返回div元素,第二种方法返回p元素。你可以根据需要,选择到底使用哪一种方法。
使用这种模式的操作方法,一共有四对:
  

.insertAfter()和.after():在现存元素的外部,从后面插入元素

  .insertBefore()和.before():在现存元素的外部,从前面插入元素
  
  .appendTo()和.append():在现存元素的内部,从后面插入元素
  
  .prependTo()和.prepend():在现存元素的内部,从前面插入元素

六、元素的操作:复制、删除和创建

除了元素的位置移动之外,jQuery还提供其他几种操作元素的重要方法。
复制元素使用.clone()。
删除元素使用.remove()和.detach()。两者的区别在于,前者不保留被删除元素的事件,后者保留,有利于重新插入文档时使用。
清空元素内容(但是不删除该元素)使用.empty()。
创建新元素的方法非常简单,只要把新元素直接传入jQuery的构造函数就行了:
  

$('<p>Hello</p>');
  $('<li class="new">new list item</li>');
  $('ul').append('<li>list item</li>');

七、工具方法

jQuery设计思想之六:除了对选中的元素进行操作以外,还提供一些与元素无关的工具方法(utility)。不必选中元素,就可以直接使用这些方法。

如果你懂得Javascript语言的继承原理,那么就能理解工具方法的实质。它是定义在jQuery构造函数上的方法,即jQuery.method(),所以可以直接使用。而那些操作元素的方法,是定义在构造函数的prototype对象上的方法,即jQuery.prototype.method(),所以必须生成实例(即选中元素)后使用。如果不理解这种区别,问题也不大,只要把工具方法理解成,是像javascript原生函数那样,可以直接使用的方法就行了。

常用的工具方法有以下几种:
  

$.trim() 去除字符串两端的空格。
  $.each() 遍历一个数组或对象。
  $.inArray() 返回一个值在数组中的索引位置。如果该值不在数组中,则返回-1。
  $.grep() 返回数组中符合某种标准的元素。
  $.extend() 将多个对象,合并到第一个对象。
  $.makeArray() 将对象转化为数组。
  $.type() 判断对象的类别(函数对象、日期对象、数组对象、正则对象等等)。
  $.isArray() 判断某个参数是否为数组。
  $.isEmptyObject() 判断某个对象是否为空(不含有任何属性)。
  $.isFunction() 判断某个参数是否为函数。
  $.isPlainObject() 判断某个参数是否为用"{}""new Object"建立的对象。
  $.support() 判断浏览器是否支持某个特性。

八、事件操作

jQuery设计思想之七,就是把事件直接绑定在网页元素之上。
  

$('p').click(function(){
    alert('Hello');
  });

目前,jQuery主要支持以下事件:
 

.blur() 表单元素失去焦点。
  .change() 表单元素的值发生变化
  .click() 鼠标单击
  .dblclick() 鼠标双击
  .focus() 表单元素获得焦点
  .focusin() 子元素获得焦点
  .focusout() 子元素失去焦点
  .hover() 同时为mouseenter和mouseleave事件指定处理函数
  .keydown() 按下键盘(长时间按键,只返回一个事件)
  .keypress() 按下键盘(长时间按键,将返回多个事件)
  .keyup() 松开键盘
  .load() 元素加载完毕
  .mousedown() 按下鼠标
  .mouseenter() 鼠标进入(进入子元素不触发)
  .mouseleave() 鼠标离开(离开子元素不触发)
  .mousemove() 鼠标在元素内部移动
  .mouseout() 鼠标离开(离开子元素也触发)
  .mouseover() 鼠标进入(进入子元素也触发)
  .mouseup() 松开鼠标
  .ready() DOM加载完成
  .resize() 浏览器窗口的大小发生改变
  .scroll() 滚动条的位置发生变化
  .select() 用户选中文本框中的内容
  .submit() 用户递交表单
  .toggle() 根据鼠标点击的次数,依次运行多个函数
  .unload() 用户离开页面

以上这些事件在jQuery内部,都是.bind()的便捷方式。使用.bind()可以更灵活地控制事件,比如为多个事件绑定同一个函数:
 

$('input').bind(
    'click change', //同时绑定click和change事件
    function() {
      alert('Hello');
    }
  );

有时,你只想让事件运行一次,这时可以使用.one()方法。
 

$("p").one("click", function() {
    alert("Hello"); //只运行一次,以后的点击不会运行
  });

.unbind()用来解除事件绑定。

 

$('p').unbind('click');

所有的事件处理函数,都可以接受一个事件对象(event object)作为参数,比如下面例子中的e:
 

$("p").click(function(e) {
    alert(e.type); // "click"
  });

这个事件对象有一些很有用的属性和方法:
  


event.pageX 事件发生时,鼠标距离网页左上角的水平距离
  event.pageY 事件发生时,鼠标距离网页左上角的垂直距离
  event.type 事件的类型(比如click)
  event.which 按下了哪一个键
  event.data 在事件对象上绑定数据,然后传入事件处理函数
  event.target 事件针对的网页元素
  event.preventDefault() 阻止事件的默认行为(比如点击链接,会自动打开新页面)
  event.stopPropagation() 停止事件向上层元素冒泡

  
在事件处理函数中,可以用this关键字,返回事件针对的DOM元素:

$('a').click(function(e) {
    if ($(this).attr('href').match('evil')) { //如果确认为有害链接
      e.preventDefault(); //阻止打开
      $(this).addClass('evil'); //加上表示有害的class
    }
  });

有两种方法,可以自动触发一个事件。一种是直接使用事件函数,另一种是使用.trigger().triggerHandler()
  

$('a').click();

  $('a').trigger('click');

九、特殊效果

最后,jQuery允许对象呈现某些特殊效果。
  

$('h1').show(); //展现一个h1标题

常用的特殊效果如下:
 

.fadeIn() 淡入
  .fadeOut() 淡出
  .fadeTo() 调整透明度
  .hide() 隐藏元素
  .show() 显示元素
  .slideDown() 向下展开
  .slideUp() 向上卷起
  .slideToggle() 依次展开或卷起某个元素
  .toggle() 依次展示或隐藏某个元素

除了.show().hide(),所有其他特效的默认执行时间都是400ms(毫秒),但是你可以改变这个设置。

  

$('h1').fadeIn(300); // 300毫秒内淡入
  $('h1').fadeOut('slow'); // 缓慢地淡出

在特效结束后,可以指定执行某个函数。
  

$('p').fadeOut(300, function() { $(this).remove(); });

更复杂的特效,可以用.animate()自定义。
 

$('div').animate(
    {
      left : "+=50", //不断右移
      opacity : 0.25 //指定透明度
    },
    300, // 持续时间
    function() { alert('done!'); } //回调函数
  );

.stop().delay()用来停止或延缓特效的执行。
$.fx.off如果设置为true,则关闭所有网页特效。

分享到

Angular小试牛刀(最新版本)

AngularJS 是由 Miško Hevery 从 2009 年开始着手开发。
该项目目前已由 Google收购,有一个全职的开发团队继续开发和维护这个库。 已经被用于 Google Gamil, Google Docs ….等等网页中

MVVM模式小试牛刀

<!DOCTYPE html>
<!-- myApp模块 -->
<html lang="en" ng-app='myApp'>
<head>
<meta charset="UTF-8">
<title>helloworld</title>
<!-- 引入angular库 , 在head里面或者body后面都可以写 -->
<script type="text/javascript" src="js/lib/angular.js"></script>
</head>
<body>
<!-- 实例化定义的控制器 -->
<div ng-controller='MainCtrl as mainctrl'>
<!-- 调用这个对象定义的值 -->
{{mainctrl.a}}
</div>
<!-- 普通模版 -->
<h1>{{1+2}}</h1>

</body>
<script type="text/javascript" >
//创建一个angular的模块 , 数组里面表示模块的依赖 , 以后学习了ui-router等等插件, 将会写一些内容
var oMyApp= angular.module('myApp',[]);
//创建一个控制器(装饰者模式)
oMyApp.controller('MainCtrl',[function(){
alert('你好,我是控制器');
// 给实例添加一个属性
this.a = 1000;
}]);
// console.log(oMyApp);
</script>
</html>

从上面可以看出, angular的核心是在数据上, 而不是视图, 数据变了, 视图自然就变了 , angular给了世界一个惊喜 , 以上就是一个mvvm最简单的实例

(完)

分享到

sublime text3 报错 There Are No Packages Available For Instal

真的是哔了狗了, 凌晨3点,才解决这个问题,网上的方法大部分无效

点击 Preferences > Package Settings > Package Control > Settings - User
添加

{"channels": [ "https://packagecontrol.io/channel_v3.json", "https://web.archive.org/web/20150905194312/https://packagecontrol.io/channel_v3.json" ]}

原文链接 : There are no packages available for installation - Package Control of Sublime Text 3

完美解决

(完)

分享到

学习Javascript闭包(Closure)

作者: 阮一峰
日期: 2009年8月30日
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

转自阮一峰博客,点击阅读原文

一、变量的作用域

要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。
 

var n=999;
  function f1(){
    alert(n);
  }
  f1(); // 999

另一方面,在函数外部自然无法读取函数内的局部变量。

function f1(){
    var n=999;
  }
  alert(n); // error

这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

function f1(){
    n=999;
  }
  f1();
  alert(n); // 999

二、如何从外部读取局部变量?

出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
那就是在函数的内部,再定义一个函数。

function f1(){
    var n=999;
    function f2(){
      alert(n); // 999
    }
  }

在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。这就是Javascript语言特有的”链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!
 

function f1(){
    var n=999;
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999

三、闭包的概念
上一节代码中的f2函数,就是闭包。
各种专业文献上的”闭包”(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成”定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

四、闭包的用途

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
怎么来理解这句话呢?请看下面的代码。
 

function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000

在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

为什么会这样呢?原因就在于f1f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

这段代码中另一个值得注意的地方,就是

"nAdd=function(){n+=1}"

这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

五、使用闭包的注意点

  • 1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
  • 2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

    六、思考题

    如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。
代码片段一

 

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());

解析代码片段一:

getNameFunc: function() {//假设函数名为A
return function()/*假设函数名为B*/ { return this.name; };
}

在函数里面构建函数的时候,闭包产生。
在函数B内调用函数A的this.name,由于函数A没有name属性,所以就去找全局变量name,找到了,所以返回“The Window”,要是没有找到,则返回“undefined”

代码片段二。
var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());

解析代码片段二:

object.getnameFunc()

在返回闭包函数前,将this赋给that,此时getnameFunc是由
object调用的,故而this指向object,当内部函数被返回时,由于闭包的特性,仍然
能访问到外部函数中的值,当执行打印My Object

(完)

分享到

移动开发XX问题解决

关于meta

(一) 常用的公共meta属性

1.viewport

<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />

width=device-width 宽度是设备屏幕的宽度(像素)
height=device-width 高度是屏幕的高度
initial-scale 初始缩放比例
minimum-scale 允许用户缩放最小比例
maximum-scale 允许用户缩放的最大比例
user-scalable 用户是否可以手动缩放

2.format-detection

format-detection翻译成中文的意思是“格式检测”,顾名思义,它是用来检测html里的一些格式的,那关于meta的format-detection属性主要是有以下几个设置:

meta name="format-detection" content="telephone=no"
meta name="format-detection" content="email=no"
meta name="format-detection" content="adress=no"

也可以连写:

meta name="format-detection" content="telephone=no,email=no,adress=no"

下面具体说下每个设置的作用:

一、telephone

你明明写的一串数字没加链接样式,而iPhone会自动把你这个文字加链接样式、并且点击这个数字还会自动拨号!想去掉这个拨号链接该如何操作呢?这时我们的meta又该大显神通了,代码如下:
telephone=no就禁止了把数字转化为拨号链接!
telephone=yes就开启了把数字转化为拨号链接,要开启转化功能,这个meta就不用写了,在默认是情况下就是开启!

二、email

告诉设备不识别邮箱,点击之后不自动发送
email=no禁止作为邮箱地址!
email=yes就开启了把文字默认为邮箱地址,这个meta就不用写了,在默认是情况下就是开启!

三、adress

adress=no禁止跳转至地图!
adress=yes就开启了点击地址直接跳转至地图的功能,在默认是情况下就是开启!

3.http-equiv

这个属性html5并不能很好的支持, 一般手机网页都是有一定缓存的, 所以这个一般不用设置.

(二) iOS私有属性

<meta name="apple-mobile-web-app-title" content="标题">添加到主屏后的标题(iOS 6 新增)
<meta name="apple-mobile-web-app-capable" content="yes" />是否启用 WebApp 全屏模式
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />设置状态栏的背景颜色

只有在 “apple-mobile-web-app-capable” content=”yes” 时生效

content 参数:

default 默认值。

black 状态栏背景是黑色。

black-translucent 状态栏背景是黑色半透明。

设置为 default 或 black ,网页内容从状态栏底部开始。

设置为 black-translucent ,网页内容充满整个屏幕,顶部会被状态栏遮挡

IOS主屏幕图标设置
<link href="apple-touch-icon" href="touch-icon-iphone.png"/>
<link href="apple-touch-icon-precomposed" href="touch-icon-iphone.png"/>

两者的区别是第二种有IOS6那种半透明样式

启动画面的设置
<link rel="apple-touch-startup-image" href="xxx.png"/>

二、关于样式

1、上下拉动滚动条时卡顿、慢
body {
-webkit-overflow-scrolling: touch;
overflow-scrolling: touch;
}
2、禁止复制、选中文本
Element {
-webkit-user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
}
解决移动设备可选中页面文本(视产品需要而定)
3、长时间按住页面出现闪退
element {
-webkit-touch-callout: none;
}
4、iphone及ipad下输入框默认内阴影
Element{
-webkit-appearance: none;
}
5、ios和android下触摸元素时出现半透明灰色遮罩
Element {
-webkit-tap-highlight-color:rgba(255,255,255,0)
}
设置alpha值为0就可以去除半透明灰色遮罩,备注:transparent的属性值在android下无效。
6、active兼容处理
7、动画定义3D启用硬件加速
Element {
-webkit-transform:translate3d(0, 0, 0)
transform: translate3d(0, 0, 0);
}
注意:3D变形会消耗更多的内存与功耗
8、Retina屏的1px边框
Element{
border-width: thin;
}
9、旋转屏幕时,字体大小调整的问题
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {
-webkit-text-size-adjust:100%;
}
10、transition闪屏
/设置内嵌的元素在 3D 空间如何呈现:保留3D /

-webkit-transform-style: preserve-3d;
/ 设置进行转换的元素的背面在面对用户时是否可见:隐藏 /

-webkit-backface-visibility:hidden;
11、圆角bug

某些Android手机圆角失效

background-clip: padding-box;
分享到