js高级之作用域

作用域

先来看一段代码

在js中,函数嵌套是非常普遍的, 那么在函数嵌套中,对变量是如何寻找的呢?
答:首先在函数内寻找, 寻找不到, 则在外层寻找 …直到…全局(window)区域

<script>
var a = 1;
function fun1() {
var b = 2;
<!--声明c变量-->
var c = 3
function fun2() {
var c = 4;
alert(a + b + c);
}
return fun2();
}
fun1();
// 结果为7 (c已经找到, 所以不往上寻找)
</script>

声明var的作用

var是在函数运行的上下文中,声明一个变量 , 如果不加var , 则是一个赋值操作,
不要片面的理解为这是个全局变量, 比如下面的代码: (函数f2内的e往上找,当找到f
1内的 var e时 , 使得 var e = 2 , 不再往上寻找, 所以e与ee都为undefined )

<script>


function f1() {

var e;

function f2() {
e = 2;
var ee = 2;
}
return f2();
}

f1();
console.log(e);
console.log(ee);


// 结果为 : e is not undefined , ee is not undefined

</script>

下面代码中e没有加var ,仅仅是一个赋值操作 , 它开始在f2函数中寻找这个变量 , 一直没找到, 直到找到最外面的window , 于是就就window.e=2 .

<script>
function f1() {
function f2() {
e = 2;
var ee = 2;
}
return f2();
}
f1();
console.log(e);
console.log(ee);
// 结果为 2 , ee is not undefined
</script>

js作用域面试题

第一题

    <script>
var a = 'one';
function f1() {
console.log(a); //one
console.log(b); // b is not undefined

// 实际上出错, 并没有执行到这
b = 'two'; //此时b并没有加var
// 若执行完,则才把全局的b赋上值
}
f1();
// 结果为 one , b is not undefined
</script>

再比如, 把b加var之后

<!--这里涉及到词法分析, js代码在整体运行分-->
<!--1.词法分析期-->
<!--2.运行期-->
<!--js代码从上往下执行,我们知道, 一个声明变量, 是存在函数的运行上下文中-->
<!--1.词法分析期:以下面代码为例, 先分析f1函数, 函数内有 b 这个局部变量, 但此时函数未执行, 因此a,b的值都为undefined-->
<!--2.运行期: 运行期时, 最后才真正的是声明了b变量-->
<script>
var a = 'one';

function f1() {
console.log(a); //one
console.log(b); // b is not undefined


var b = 'two'; // 声明b变量

}

f1();
// 结果为 one , b is not undefined
</script>
分享到

安卓与IOS浏览器常见bug

一、IOS自带safari浏览器

1、safari不支持fixed+input输入框。

解决方案:
http://www.haorooms.com/post/ios_fixed_input

2、safari图片加载失败,默认图片过大。

解决方案:
http://www.haorooms.com/post/img_faile_jiangrong

3、ios默认safari浏览器对齐问题解决

二、安卓UC浏览器

1、安卓UC为代表的浏览器不支持部分css3属性,例如calc等 width:90%;width:calc(sdadas);

2、滚动事件不会触发touchmove事件

三、手机浏览器通用问题

1、弹出层touchmove滚动,会触发body滚动(出现前提是body中有滚动轴)

http://www.haorooms.com/post/webapp_bodyslidebcdiv

2、假如你整个网页用rem字体,部分安卓浏览器出现字体过大的情况。

3、部分安卓浏览器对margin要求比较苛刻。

分享到

canvas使用

canvas属于HTML5中的一个新标签,canvas中文翻译过来就是画布的意思 , 我们可以在canvas上面画各种各样的图形, 也可以将图片放在canvas上面,以及做一些渐变效果 ,等等.

一个最简单的canvas画矩形

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas画矩形</title>
</head>
<body>
<!--定义一个canvas标签-->
<canvas id="myCanvas" width="500px" height="200px"></canvas>
</body>
<script type="text/javascript">
// 找到canvas元素
var objCanvas = document.getElementById("myCanvas");
// 通过找到的canvas元素创建一个2dcanvas对象
var objGc2d = objCanvas.getContext("2d");
// 填充颜色
objGc2d.fillStyle = "#FF0000";
// 0,0 代表x与y轴的坐标(与background-position中x,y用法一致) , 150代表宽度, 75为长度
objGc2d.fillRect(0, 0, 150, 75);
</script>
</html>

将图像写入canvas中

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas</title>
</head>
<body>
<canvas id="myCanvas" width="200px" height="100px" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
</body>
<script>
var objCanvas = document.getElementById('myCanvas');
// 通过找到的canvas元素创建一个2dcanvas对象
var objGc2d = objCanvas.getContext("2d");
// 实例化Image, 得到一个img对象
var objImg = new Image();
// 给这个img对象设置图像
objImg.src='../Html/bg.png';
// 将图像写入画布中 , 0,0 分别代表x与y轴的坐标
objGc2d.drawImage(objImg,0,0);
</script>
</html>

使用canvas实现文字渐变效果

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>shadow</title>
</head>
<body>
<canvas id="canvasis"></canvas>
<script>

var objCanvas = document.getElementById("canvasis");
var objGc2d = objCanvas.getContext("2d");
objGc2d.font = "30px Microsoft YaHei";
// Create gradient(创建渐变)渐变开始点的 x 坐标,渐变开始点的 y 坐标 , 渐变结束后的x坐标与渐变结束后的y坐标
var gradient = objGc2d.createLinearGradient(0, 0, objCanvas.width, 0);
// 在不同的位置添加不同的颜色
gradient.addColorStop("0", "magenta");
gradient.addColorStop("0.5", "blue");
gradient.addColorStop("1.0", "red");
// 填充渐变
objGc2d.strokeStyle = gradient;
// 10 与 50 分别代表相当于画布x与y轴的坐标
objGc2d.strokeText("OSganping.github.io", 10, 50);

</script>
</body>
</html>
实现效果如下

image

分享到

requireJS使用

模块化编程之requirejs

requirejs的好处

  1. 声明不同js文件之间的依赖
  2. 可以按需.并行.延时载入js库(延时加载)
  3. 可以让我们的代码以模块化的方式组织
  4. 代码的管理和性能优化.提高代码的速度和质量
  5. 相对简单,不复杂

AMDCMD的区别

AMD:提前执行, 推崇依赖就近(requireJS在推广中对模块化定义的规范化产出)
CMD:延迟执行, 推崇依赖前置(SeaJS在推广过程中对模块定义的规范化产出)

不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

// CMD  需要A模块就requireA模块 ,需要B模块就requireB模块
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ...
})
// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
})

虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。

我们还可以使用 optimize 进行代码(JS,CSS)压缩,使用optimize代码压缩前 ,我们需要完成这些事情
1.下载r.js
2. 新建一个配置文件, 例如build.js(推荐使用这种方式),这样配置更方便, 具体配置可以自行百度.

当配置完成后,进入需要压缩的文件目录 , 运行

node tools/r.js -o tools/build.js

就开始代码压缩了, 压缩完成后, 会在当前目录生成一个www-built文件, 里面有个app.js , 这个app.js里面就是所有项目文件中的js与css代码压缩后的样子了.

分享到

函数与对象的关系

var fn = function () { };
console.log(fn instanceof Object); // true

首先,从上面可以看出,函数是引用类型,是对象,
再比如:

function Fn() {
this.name = 'Pray';
this.year = 1988;
}
var fn1 = new Fn();

从上面可以看出,对象可以通过new一个函数来创建

但是,我要说明, 对象都是由函数创建的, 有些人可能会反驳, 比如

var obj = { a: 10, b: 20 };
var arr = [5, 'x', true];

这些json对象,数组难道也是由函数创建的???
我的回答是,yes.
看下面的代码:

//var obj = { a: 10, b: 20 };
//var arr = [5, 'x', true];

var obj = new Object();
obj.a = 10;
obj.b = 20;

var arr = new Array();
arr[0] = 5;
arr[1] = 'x';
arr[2] = true;

怎么样,是不是看的很清楚

对象是函数创建的, 而函数又是一种对象,那么函数与对象到底有什么关系呢???

这就涉及到js中比较高级的东西 – prototype原形
(完)

分享到

JS中对象的特点

JS中有6种数据类型

  1. Int
  2. String
  3. Boolean
  4. Null
  5. Undefined
  6. Object

值类型与引用类型两大类

值类型(不是对象)

  1. Int
  2. String
  3. Boolean
  4. Undefined

引用类型

  1. Null
  2. Object

据我所知,共有五种属性可以判断数据的类型

  1. typeof 会返回一个字符串,适合函数判断和基本类型的判断(特殊null返回的数据类型是“object”)
  2. instanceof判断对象类型,但是不同的Window和iframe对象类型检测不能用(原型链中)
  3. Object.prototype.toString.apply([]) === "[object.Array]"//在IE6,7,8下,对null和undefined检测失效
  4. constructor
  5. duck type

一般来说, 常用的就两种, typeofinstanceof

typeof主要判断普通的值类型,如string,int,boolean,undefined

instanceof主要判断一些函数,数组,对象,null…引用类型

例如:

var fn = function () { };
console.log(fn instanceof Object); // true

js的对象与java,c#不一样, js的对象没有方法, 只有属性, 那些方法也都是属性,都表示为键值对的形式.并且js中对象属性是动态的, 可以添加, 删除.等等…

自定义对象属性里面可以添加函数,甚至一个对象

例如:

添加

var isObj = { 
name:'GanPing',
age:18,
eat:function(){}, //一个函数
Obj={name:'对象',age:20} //一个对象
};

删除

delete isObj.name;
console.log(isObj.name); // undefined

那么,函数呢,数组呢, 它们也可以和自定义对象一样,添加属性与方法吗?

答:当然可以,只不过与自定义对象的方式不同

例如:

var fn = function () {
alert(100);
};
fn.a = 10;
fn.b = function () {
alert(123);
};
fn.c = {
name: "PRAY",
year: 1988
};

总之,只要是对象,它就是属性的集合
再比如

console.log($ instanceof Object ); //true
console.log(typeof ($.trim('GanPing'))); // 返回为一个string 类型

所以, 在JavaScript中, 一切(引用类型)都是对象,对象也就是属性的集合罢了
(完)

分享到

sass的基本用法

sass介绍

Sass 扩展了 CSS3,增加了规则、变量、混入、选择器、继承等等特性。Sass 生成良好格式化的 CSS 代码,易于组织和维护。
SASS是对CSS3(层叠样式表)的语法的一种扩充,它可以使用巢状、混入、选择子继承等功能,可以更有效有弹性的写出Stylesheet。Sass最后还是会编译出合法的CSS让浏览可以使用,也就是说它本身的语法并不太容易让浏览器识别(虽然它和CSS的语法非常的像,几乎一样),因为它不是标准的CSS格式,在它的语法内部可以使用动态变量等,所以它更像一种极简单的动态语言。

使用sass前, 必须先安装Ruby, 其次安装sass (sass依赖于Ruby环境)

变量

SASS允许使用变量,所有变量以$开头。

$blue : #1875e7; 
div {
color : $blue;
}

如果变量需要镶嵌在字符串之中,就必须需要写在#{}之中。

$side : left;
 .rounded {
border-#{$side}-radius: 5px;
}

计算功能

SASS允许在代码中使用算式:

body {
    margin: (14px/2);
    top: 50px + 100px;
    right: $var * 10%;
  }

嵌套

SASS允许选择器嵌套。比如,下面的CSS代码:

div h1 {
    color : red;
  }
//可以写成:
  div {
    hi {
      color:red;
    }
  }

//属性也可以嵌套,比如border-color属性,可以写成:

p {
    border: {
      color: red;
    }
  }

//注意,border后面必须加上冒号。
在嵌套的代码块内,可以使用$引用父元素。比如a:hover伪类,可以写成:

a {
    &:hover { color: #ffb3ff; }
  }

注释

SASS共有两种注释风格。

标准的CSS注释 / comment / ,会保留到编译后的文件。

单行注释 // comment,只保留在SASS源文件中,编译后被省略。

在/*后面加一个感叹号,表示这是"重要注释"。即使是压缩模式编译,也会保留这行注释,通常可以用于声明版权信息。

/*!
    重要注释!
*/

代码的重用

继承

SASS允许一个选择器,继承另一个选择器。比如,现有class1:

.class1 {
    border: 1px solid #ddd;
  }

class2要继承class1,就要使用@extend命令:

.class2 {
    @extend .class1;
    font-size:120%;
  }
分享到

移动主流框架

web开发的多种方式

touchweb 手机网站

web-app (phoneGap , H5builde , appcan打包为IOS,Android)

hybrid-app(主流)(开发周期短,性能好)

native-app(原生)

性能原生最好, 后面依次排序

移动端主流CSS框架

  1. bootstrap
  2. 动画:Animate.css, NEC, impress
  3. 字体:iconfont,fontawesome
  4. CSS管理:SASS, Less

移动端主流js框架

  1. zeptio.js(和jquery差不多,比jquery功能多,速度快,轻量级,缺点是不兼容IE)
  2. jGestures(手势,摇一摇呀什么的,都可以做)
  3. swiper(触摸,手势)
  4. iscroll

移动开发流行框架

1. jqueryMobile(用户体验较差)
2. app framework
3. senchtouch
4. moblieangularui
5. phonegap
6. appcan
7. 妹子ui
8. 百度GMU
分享到

CSS3 Media Query详解

首先,做响应式布局, 第一要做的就是在网页头部添加 meta 属性

<head>
<meta charset="UTF-8">
<!--viewport 意思是网页的默认高度-->
<!--width=device-width 意思是网页宽度默认等于屏幕宽度-->
<!--initial-scale=1 意思是原始缩放比例为 1.0-->
<meta name="viewport" content="width=device-width , initial-scale=1"/>
<!--IE9以下不支持这些属性, 需要使用CSS3属性来处理-->
<!-[if IE 9]>
<!--处理代码.....-->
<![endif]->
<title>响应式</title>
</head>

其次, 我们可以使用 CSS3 中的 Media Query来处理不同分辨率下的代码,其作用就是允许添加表达式用以确定媒体的环境情况,以此来应用不同的样式表。换句话说,其允许我们在不改变内容的情况下,改变页面的布局以精确适应不同的设备。

那么,Media Query是如何工作的?

两种方式,一种是直接在link中判断设备的尺寸,然后引用不同的css文件:

<link rel="stylesheet" type="text/css" href="styleA.css" media="screen and (min-width: 400px)">

意思是当屏幕的宽度大于等于400px的时候,应用styleA.css

在media属性里:

screen 是媒体类型里的一种,CSS2.1定义了10种媒体类型
and 被称为关键字,其他关键字还包括 not(排除某种设备),only(限定某种设备)
(min-width: 400px) 就是媒体特性,其被放置在一对圆括号中。完整的特性参看 相关的Media features部分

<link rel="stylesheet" type="text/css" href="styleB.css"  media="screen and (min-width: 600px) and (max-width: 800px)">

意思是当屏幕的宽度大于600小于800时,应用styleB.css

其它属性可看这里:http://www.swordair.com/blog/2010/08/431/

另一种方式,即是直接写在<style>标签里:

@media screen and (max-width: 600px) { /*当屏幕尺寸小于600px时,应用下面的CSS样式*/
.class {
background: #ccc;
}
}

写法是前面加@media,其它跟link里的media属性相同

其实基本上就是样式覆盖,判断设备,然后引用不同的样式文件覆盖。

要注意的是由于网页会根据屏幕宽度调整布局,所以不能使用绝对宽度的布局,也不能使用具有绝对宽度的元素。这一条非常重要,否则会出现横向滚动条。

分享到