Yearly Archive 2016

By柏小白

快速激活webstorm JetBrains系列产品

随着 JetBrains 新版本的发布,注册机已然不行了。

 

注册时选择 License server,填 http://idea.xn--w0sz4as21fs7k.com/,然后点击 OK,就搞定了。如有异常联系我

License server分享:

http://www.qidianban.site:1203/

http://idea.enjoysala.top/

http://idea.lianghongbo.com/license
http://idea.qinxi1992.cn
http://idea.lanyus.com/

 

 

使用网上传统的那种输入网址的方式激活不了,使用http://idea.lanyus.com/这个网站提供的工具进行,有效期已经更新了

1、进入hosts文件中:C:\Windows\System32\drivers\etc\hosts

2、将“0.0.0.0 account.jetbrains.com”添加到hosts文件中

注意:添加只有重新打开hosts文件进行确认之后在进行下一步操作。

修改成功后如图所示:

注:将这条数据加入之后会提示保存,然后确认之后,重新打开hosts文件确认是否添加成功,有时候会提示确认两次。

另可以直接将hosts文件复制到桌面,然后就可以直接进行编辑,保存操作,编辑之后再复制到原地址中,然后在cmd命令窗口执行: ipconfig /flush dns即可。

3、进入http://idea.lanyus.com/站点,点击获得注册码,然后将注册码复制,粘贴到IDEA中

 

注:爱前端 || 爱老婆

 

By柏小白

js面向对象学习

对象

JavaScript本身是一门面向对象的语言,JavaScript所有变量都可以当作对象使用(这里是说可以当对象使用,并不是说均是对象,应该理解为可以通过点操作符来调用一些属性方法),除了两个例外 null 和 undefined。

beauty.jpg

对象使用和属性

看到这个描述的时候,我果断尝试了一下 number 类型的数字字面值( literals ),敲下回车的一瞬间笑了,这话写错了啊。查阅了JavaScript 秘密花园的内容才知道问题所在,原来是JavaScript解析器把点操作符解析为了浮点字面量。可以通过一些方法让数字字面值看起来像对象,终究而言还是不能被称为对象。

1
2
3
4
5
6
1.toString(); // Uncaught SyntaxError: Invalid or unexpected token
// 数字字面量
1..toString(); // “1”
1 .toString(); // “1”
(1).toString(); // “1”

再尝试一些其他的类型作为对象的使用

1
2
3
4
5
6
7
8
9
10
11
12
// Boolean
false.toString(); // “false”
// Array
[1, 2, 3].toString(); // 1, 2, 3
// String
“string”.match(‘s’); // [“s”]
// Function
function D() {}
D.toString(); // “function D() {}”

原型

JavaScript没有类继承模型,而是使用 prototype 原型模型。虽然在ES6中增加了 class 关键字,但只是语法糖,仍旧是基于原型。
JavaScript对象有一个指向一个原型对象的链。当试图访问一个对象上的属性时,会先搜寻该对象的属性,再搜寻该对象的原型以及原型的原型,依次网上搜索,直到找到一个名字匹配的属性或者达到原型链的末尾。

  • 原型的使用方式一
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var F = function(x) {
    this.x = x || 1;
    }
    F.prototype = {
    add: function(y) {
    return this.x + y;
    }
    }
    var f = new F();
    f.add(2); // 3
    var f1 = new F(2);
    f1.add(4); // 6

定义了函数F模拟类,其函数表达式相当于构造函数 constructor 。函数也是对象,通过给F对象的 prototype 属性赋值对象字面量来设定F的原型。通过关键字new来实例化函数F,返回实例化对象, x 为f对象的属性, add 为f对象的方法。

  • 原型的使用方式二
    赋值原型的时候立即执行函数表达式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    var F = function() {};
    F.prototype = function() {
    var add = function(x, y) {
    return x+y;
    };
    var test = function() {
    console.log(‘private’);
    };
    return {
    add: add
    }
    }()
    var f = new F();
    f.add(3, 3); // 6
    f.test(); // f.test is not a function

给F函数的 prototype 属性赋值了一个立即执行函数表达式,函数表达式返回需要暴露的方法的一个对象,这种方式可以实现方法public/private。

原型链

JavaScript使用原型链的继承方式,如下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function Foo() {
this.name = ‘unofficial’;
}
Foo.prototype.who = function() {
return this.name;
}
function Bar() {}
// 设置Bar的prototype属性值为Foo的实例化对象
Bar.prototype = new Foo();
Bar.prototype.foo = ‘Hello world!’;
// 修正Bar.prototype.constructor为Bar本身 ?
Bar.prototype.constructor = Bar;
var b = new Bar();
/*
* 原型链为
b [Bar的实例]
bar.prototype [Foo的实例]
{ foo: ‘Hello world’, name: ‘unofficial’ }
Foo.prototype
{method: …}
Object.prototype
{toString: …}
*/

实例b对象从Bar.prototype和Foo.prototype继承下来,因为b能访问自身原型属性foo,以及Foo原型方法who,也能访问Foo上的原型属性name。需要注意的是new Bar()不会重新创造出一个Foo实例,而是重复使用原型上的实例。

如果直接 Bar.prototype = Foo.prototype; 将会导致两个对象共享相同的原型。改变一个对象的原型将会影响到另外一个对象的原型。

属性查找

在查找一个属性的时候,JavaScript会向上遍历原型链,直到找到给定名称位置或者到达原型链的顶部Object.prototype,如果仍然没找到即返回undefined。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Foo = function() {
this.add = function(x, y) {
return x + y;
}
}
Foo.prototype.add = function(x, y) {
return x + y;
}
Foo.prototype.test = function() {
console.log(‘来源于prototype的test方法’);
}
var f = new Foo();
console.log(f.add(1, 3)); // 4
f.test(); // 来源于prototype的test方法

调用f.add方法的后首先会在Foo中找add方法,找到了直接就调用add方法。test方法在实例中没有找到,就在原型链上找,能找到直接就执行,如果找不到会继续Object的原型上找,找不到才返回undefined

原型属性

当原型属性创建原型链的时候,任何类型都可以为它赋值,然而将原子类型的值赋值给它是被忽略。

1
2
3
4
5
6
// 用代码解释上面的话
function Foo() {}
// 可以赋值任何类型,比如说
Foo.prototype = 1; // 但是直接赋值类型值只是会被忽略,不会报错,相应的如果后面继续给原型赋值也会被忽略。原型直接是赋值为Object.prototype
console.log(new Foo()); // function Foo() {}

如果直接赋值对象就会像上面的应用一样,创建原型链。通过这种方法可以创建私有方法与公共方法。

性能

由于上文提到的属性查找会从当前对象一直沿着原型链查找,如果找寻一个不存在的问题是需要遍历整个原型链。
for in 循环遍历对象的属性时,原型链上的所有属性也都会被遍历。

扩展内置类型

虽然目前涉及到的应用环境不够复杂,对于复杂引用更多的类或者框架对于相应模块的封装的时候就需要用到原型来实现继承等等,但是不建议扩展内置类型的原型对象,这样会存在性能问题。

isPrototypeOf vs hasOwnProperty

  • isPrototypeOf() 方法测试一个对象是否存在于另一个对象的原型链上。
    prototype.isPrototypeOf(object) 检查prototype对象是否存在object的原型链上
1
2
3
4
5
6
7
8
9
var Foo = function() {};
var Bar = function() {};
Bar.prototype = new Foo();
var b = new Bar();
Foo.prototype.isPrototypeOf(new Foo()); // true
// 在b的原型链上查找对象Foo.prototype
Foo.prototype.isPrototypeOf(b); // true
  • isPrototypeOf vs instanceof
    instanceof运算符可以用来判断某个构造函数的prototype属性所指向的對象是否存在于另外一个要检测对象的原型链上。
    object instanceof constructor
    检查构造函数constructor的原型属性是不是存在object对象的原型链上

    Code one:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var Foo = function() {};
    var Bar = function() {};
    var f = new Foo();
    var b = new Bar();
    f instanceof Foo; // true
    Foo.prototype.isPrototypeOf(f); // true
    f instanceof Bar; // false
    Bar.prototype = new Foo();
    var b1 = new Bar();
    b1 instanceof Foo; // true
    Foo.prototype.isPrototypeOf(b1); // true

    Code two:

    1
    2
    3
    4
    var human = {mortal: true};
    var socrates = Object.create(human);
    human.isPrototypeOf(socrates); //=> true
    socrates instanceof human; //=> ERROR!

    综上所述:在存在构造函数的时候,instanceof 与 isPrototypeOf 是没有区别的,在没有构造函数的时候只能使用isPrototypeOf

  • hasOwnProperty
    hasOwnProperty用于判断一个对象上是否包含自定义属性,而不是原型链上的属性。hasOwnProperty继承自Object.prototype。

    注意不能通过判断值为undefined来判断属性是否存在,因为该属性的值可能就是undefined

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var Foo = function() {
this.name = ‘unofficial’;
}
Foo.prototype = function() {
return {
getName: function() {
return this.name;
},
age: undefined
};
}()
Foo.prototype.color;
var f = new Foo();
f.color; // undefined
f.hasOwnProperty(‘color’); // false
f.hasOwnProperty(‘age’); // false
f.hasOwnProperty(‘name’); // true

可以在循环遍历的时候用来判断属性是不是是当前对象的属性,而不是继承自原型链

hasOwnProperty可以在当前对象中重写,如果如下例子:

1
2
3
4
5
6
7
8
9
10
11
12
var Foo = function() {
this.hasOwnProperty = function() {
return false;
}
this.name = ‘unofficial’;
}
var f = new Foo();
f.hasOwnProperty(‘name’); // false
// 通过其他对象继承的Object.prototype的hasOwnProperty方法
({}).hasOwnProperty.call(f, ‘name’); //true

ES6中方法如何实现类呢?

以下内容均是在chrome最新版本中测试

ES6中添加了关键字 class ,表面上是的写法和其他语言的类是一样的写法,实际上只是实现了prototype的语法糖。

1
2
3
4
5
6
7
8
9
10
11
‘use strict’;
class Foo {
constructor() {
this.name = ‘unofficial’;
}
getName() {
return this.name;
}
}
let f = new Foo();
console.log(f.getName());

当我们使用 console.log(‘%O’, f) ;时,返回的Foo对象和之前ES5通过function模拟的类实例的对象是一致的。
ES6

  • use strict
    必须在严格模式下执行
  • constructor
    例子中已经使用了 constructor ,实例化Foo类的时候自动执行构造方法。构造方法必须唯一
  • 原型方法
    关键字 get , set 的使用。
1
2
3
4
5
6
7
8
9
10
11
12
class Foo {
set username(value) {
this.name = value;
}
get username() {
return ‘my name is ‘ + this.name;
}
}
let f = new Foo();
f.username = ‘unofficial’;
console.log(f.username);
  • 静态方法
    静态方法指不需要对类进行实例化就可以使用类名直接访问类里面的方法, static 关键字用来定义类的静态方法。
1
2
3
4
5
6
class Foo {
static info() {
console.log(‘随意写的内容’);
}
}
Foo.info(); // 随意写的内容
  • 继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ‘ 发了个声’);
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ‘说自己饿了’);
}
}
let cat = new Animal(‘kitty’);
cat.speak(); // Kitty 发了个声
new Dog(‘哮天犬’).speak(); // 哮天犬说自己饿了

dog 类继承了 Animal 类,重写了父类的 speak 方法。

  • super 调用父类方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    ‘use strict’;
    class Animal {
    constructor(obj) {
    var {name, food} = obj;
    this.name = name;
    this.food = food;
    }
    speak() {
    console.log(this.name + ‘ 发了个声’);
    }
    eat() {
    console.log(this.name + ‘喜欢’ + this.food);
    }
    }
    class Dog extends Animal {
    speak() {
    console.log(this.name + ‘说自己饿了’);
    }
    eat() {
    super.eat();
    if(this.food == ‘耗子’) {
    console.log(‘又闲的蛋疼了吧’);
    }
    }
    }
    new Dog({name: ‘哮天犬’, food: ‘耗子’}).eat(); // 哮天犬喜欢耗子 又闲的蛋疼了吧
  • isPrototypeOf 的使用
    就上面的例子使用 isPrototypeOf

    1
    2
    let dog = new Dog({name: ‘哮天犬’, food: ‘耗子’});
    console.log(Animal.prototype.isPrototypeOf(dog));
  • hasOwnProperty 的使用
    1
    2
    console.log(dog.hasOwnProperty(‘name’)); // true
    console.log(dog.hasOwnProperty(‘speak’)); // false

prototy.js是怎么做的?

参考github上prototype.js的文档以及class.js可以学习到,如何创建一个类?

1
2
3
4
5
var Humen = Class.create();
// or
var Humen = Class.create({
// 这里可以自定义类方法
});

理解class.js时,Class是一个 立即执行的函数表达式 ,不成名的规定就是函数名大写作为类名。

1
2
3
4
5
6
7
8
9
var Class = (function() {
// 返回Class的方法
return {
create: create,
Methods: {
addMethods: addMethods
}
};
})();

这一个需要学习的点,闭包的立即执行的匿名函数中返回一个对象,对象中包含一个create的方法,以及Methods方法对象。

  • 创建类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    function create() {
    // 可能会有两个参数
    // 第一个参数是父类,需要被继承的类 var gay = Class.create(‘Humen’);
    // 第二个参数是当前类的方法
    /*
    * 判断传入的参数
    * 1. $A方法处理arguments类数组对象为数组,这里使用了[].slice.call(arguments)来代替数组浅复制
    * 2. 判断第一个参数是不是类,如果是赋值给parent
    */
    var parent = null, properties = $A(arguments);
    if (Object.isFunction(properties[0]))
    parent = properties.shift();
    // 自定义Klass类,create函数最后返回的也是创建的Klass类
    /*
    * Klass为 Class.create 创建的类
    * initialize 为自定义构造方法
    * this.initialize 中的this指当前对象
    * apply(this, arguments) 参数this指实例化对象
    * new 实例化对象的时候,Klass函数会自动执行,其中的this.initialize.apply(this, arguments);也就执行了,即属性初始化了
    */
    function Klass() {
    this.initialize.apply(this, arguments);
    }
    // 当前类添加属性 superclass 存放父类;subclass 存放子类
    // 如果父类存在,父类的原型赋值给子类的原型,并初始化子类赋值给当前原型,添加当前类到父类的子类中
    // 将传入的当前类的方法添加到当前类的原型上
    /*
    * 继承addMethods方法
    * 设置父类 superclass
    * 设置子类 subclass
    */
    Object.extend(Klass, Class.Methods);
    Klass.superclass = parent;
    Klass.subclasses = [];
    /*
    * 如果父类存在
    * Subclass是一个类,父类的原型赋值给这个子类的原型
    * 实例化子类赋值给当前类的原型
    * 添加当前类到父类的子类数组中
    */
    if (parent) {
    Subclass.prototype = parent.prototype;
    Klass.prototype = new Subclass;
    parent.subclasses.push(Klass);
    }
    /*
    * 循环添加方法给当前类
    */
    for (var i = 0, length = properties.length; i < length; i++)
    Klass.addMethods(properties[i]);
    // 如果当前类方法中没有initialize方法,使用默认的空函数作为构造方法
    if (!Klass.prototype.initialize)
    Klass.prototype.initialize = function() { };
    // 重置当前类的constructor函数为自身
    Klass.prototype.constructor = Klass;
    // 返回构造的类Klass
    return Klass;
    }
  • 自定义方法,添加传入的参数方法作为当前类的方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    function addMethods(source) {
    // 判断父类是不是存在
    // 获取参数的键名
    var ancestor = this.superclass && this.superclass.prototype,
    properties = Object.keys(source);
    // 循环数组
    for (var i = 0, length = properties.length; i < length; i++) {
    var property = properties[i], value = source[property];
    // 这里主要是对于继承父类方法的调用的处理
    // 如果父类存在,并且是方法,方法的第一个参数必须是$super,如果是重写value
    if (ancestor && Object.isFunction(value) && value.argumentNames()[0] == “$super”) {
    var method = value;
    // 处理当前方法
    // wrap()
    value = (function(m) {
    return function() { return ancestor[m].apply(this, arguments); };
    })(property).wrap(method);
    // 新增valueOf
    value.valueOf = (function(method) {
    return function() { return method.valueOf.call(method); };
    })(method);
    // 新增toString
    value.toString = (function(method) {
    return function() { return method.toString.call(method); };
    })(method);
    }
    // 直接赋值给当前类的原型
    this.prototype[property] = value;
    }
    }

到这里基本上就学习完了prototype.js创建类的方法,但是如果需要融会贯通自己来实现一次,我想过程肯定还是会比较艰辛,继续加油。

面向对象是什么?

面向对象编程最美的调侃就是,“我还是单身,我是不是不适合面向对象编程”。也许是的,但是如果你能在脑海中抽象出类,需要的时候撸一发,对象迟早会有的。
OOP
面向对象是一种编程的范式方法,面向对象中的对象是类的实例,类是属性,方法的集合,对于一类对象可能有公共的行为与样式, 封装 在一起就形成了类。如果具体到这个类的一个子类型(狗与阿拉斯加雪橇犬),阿拉斯加肯定是狗,,既有狗的特性,但是同时他又有自己的特点,于是乎 继承 了狗类的一些行为。这是如果在拿来一直猫,猫和狗又都属于动物类,这事又可以抽象出一个动物类,他们都会叫,狗是汪汪汪,猫是喵喵喵,这个是叫的多种表现形式,被称为 多态

面向对象提高了程序的重用性,对于模块化开发以及重构等都带来很多好处。

实践 – 坦克大战游戏

坦克大战在玩小霸王卡版的时候经常约上邻居家的伙伴一起,其实最多的玩的还是雪人兄弟,这个是记忆比较深刻的。不扯远了,今天主要来实现一个简单的坦克大战游戏。
截止目前,还是没能还好的实现坦克大战,保留这个版本,再继续学习学习。

参考资料

JavaScript 秘密花园
强大的原型和原型链
JavaScript isPrototypeOf vs instanceof usage
Classes in ECMAScript 6 (final semantics)
prototype.js
面向对象程序设计

By柏小白

js开发过程中的小函数……陆续更新

1 获取指定范围内的随机数

当我们需要获取指定范围(min,max)内的整数的时候,下面的代码非常适合。

    function getRadomNum(min, max){
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

 

测试
2016-03-26-2

2 随机获取数组中的元素

    function getRadomFromArr(arr){
        return arr[Math.floor(Math.random() * arr.length)];
    }

 

测试
2016-03-26-3

3 生成从0到指定值的数字数组

  var arr = [], length = 100, i = 1;
    for (; arr.push(i++) < length;) {
    }
    console.log(arr)

 

测试

3

4 打乱数字数组的顺序

   var arr = [1, 2, 3, 4, 5, 6, 7, 'a', 'dsfs', 8, 9, 'v'];
    arr.sort(function (){
        return Math.random() - 0.5
    });

 

测试
4

5 对象转换为数组

//注意对象必须是以下格式的才可以通过此方式转化为数组
//获取的DOM集合,以及函数的arguments也可以通过此方式转化为数组
    /**
     * 对象转换为数组
     * @type {{0: string, 1: string, 2: string, 3: string, length: number}}
     */
    var obj = {
        0: 'qian',
        1: 'long',
        2: 'chu',
        3: 'tian',
        length: 4
    }
    var _slice = [].slice;
    var objArr = _slice.call(obj);

 

测试
5

6 验证是否为数组

   function isArray(obj){
        return Object.prototype.toString.call(obj) === '[object Array]';
    }

测试

6

7 获取数组中最大或者最小值

    function maxAndMin(arr){
        return {
            max: Math.max.apply(null, arr.join(',').split(',')),
            min: Math.min.apply(null, arr.join(',').split(','))
        }
    }
//该方法适合一维或者多维数组求最大最小值的情况

测试
7

8 清空数组

//方式一 通过将长度设置为0
    var arr = [1, 2, 3, 4, 5];
    arr.length = 0;
//方式二 通过splice方法
    var arr = [1, 2, 3, 4, 5];
    arr.splice(0, arr.length);
//方式三 通过将空数组 [] 赋值给数组(严格意义来说这只是将ary重新赋值为空数组,之前的数组如果没有引用在指向它将等待垃圾回收。)
    var arr = [1, 2, 3, 4, 5];
    arr = [];

 

9 保留指定小数位

   var num =4.345678;
    num = num.toFixed(4);  // 4.3457 第四位小数位以四舍五入计算

 

10 不要直接使用delete来删除数组中的元素

    * 数组在js中也是对象,有时候我们可能会通过delete来删除数组中的元素,但是其实仅仅是将数组的元素的值赋值为了undefined。
     */
    var arr=[1,2,3,4,5,'谦龙','雏田'];
    delete arr[5];
    console.log(arr,arr[5],arr.length);

 

测试

10

可以通过splice来删除数组中的某一项

   var arr=[1,2,3,4,5,'谦龙','雏田'];
    arr.splice(5,1);
    console.log(arr,arr[5],arr.length);

测试

10-2

11 生成指定长度的随机字母数字字符串

    function getRandomStr(len) {
        var str = "";
        for( ; str.length < len; str  += Math.random().toString(36).substr(2));
        return  str.substr(0, len);
    }

测试
11

12 null 与 undefined

    function test(obj){
        if(obj!=null){// obj除了undefined 和 null 之外都会走这里
        //....这里写代码逻辑
        }
    }

 

13 找出数组中出现次数最的元素,并给出其出现过的位置

    function getMaxAndIndex( arr ){
        var obj = {};
        arr.forEach(function(item,index){
            if(!obj[item]){
                obj[item]= {indexs: [index]}
            }else{
                obj[item]['indexs'].push(index);
            }
        });
        var num=0;//记录出现次数最大值
        var str='';//记录出现次数最多的字符
        var reArr;//返回最大值的位置数组
        for(var attr in obj){
            var temp=obj[attr]['indexs'];
            if(temp.length>num){
                num=temp.length;
                str=attr;
                reArr=temp;
            }
        }
        return {
            maxStr:str,
            indexs:reArr
        }
    }

 

测试结果13

String Skill

时间对比:时间个位数形式需补0

const time1 = "2019-02-14 21:00:00";
const time2 = "2019-05-01 09:00:00";
const overtime = time1 > time2;
// overtime => false

格式化金钱

const ThousandNum = num => num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
const money = ThousandNum(20190214);
// money => "20,190,214"

生成随机ID

const RandomId = len => Math.random().toString(36).substr(3, len);
const id = RandomId(10);
// id => "jg7zpgiqva"

生成随机HEX色值

const RandomColor = () => "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
const color = RandomColor();
// color => "#f03665"

生成星级评分

const StartScore = rate => "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);
const start = StartScore(3);
// start => "★★★"

操作URL查询参数

const params = new URLSearchParams(location.search.replace(/\?/ig, "")); // location.search = "?name=young&sex=male"
params.has("young"); // true
params.get("sex"); // "male"

Number Skill

取整:代替正数的Math.floor(),代替负数的Math.ceil()

const num1 = ~~ 1.69;
const num2 = 1.69 | 0;
const num3 = 1.69 >> 0;
// num1 num2 num3 => 1 1 1

补零

const FillZero = (num, len) => num.toString().padStart(len, "0");
const num = FillZero(169, 5);
// num => "00169"

转数值:只对null、""、false、数值字符串有效

const num1 = +null;
const num2 = +"";
const num3 = +false;
const num4 = +"169";
// num1 num2 num3 num4 => 0 0 0 169

时间戳

const timestamp = +new Date("2019-02-14");
// timestamp => 1550102400000

精确小数

const RoundNum = (num, decimal) => Math.round(num * 10 ** decimal) / 10 ** decimal;
const num = RoundNum(1.69, 1);
// num => 1.7
复制代码

判断奇偶

const OddEven = num => !!(num & 1) ? "odd" : "even";
const num = OddEven(2);
// num => "even"

取最小最大值

const arr = [0, 1, 2];
const min = Math.min(...arr);
const max = Math.max(...arr);
// min max => 0 2
复制代码

生成范围随机数

const RandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const num = RandomNum(1, 10);

Boolean Skill

短路运算符

const a = d && 1; // 满足条件赋值:取假运算,从左到右依次判断,遇到假值返回假值,后面不再执行,否则返回最后一个真值
const b = d || 1; // 默认赋值:取真运算,从左到右依次判断,遇到真值返回真值,后面不再执行,否则返回最后一个假值
const c = !d; // 取假赋值:单个表达式转换为true则返回false,否则返回true

判断数据类型:undefined、null、string、number、boolean、array、object、symbol、date、regexp、function、asyncfunction、arguments、set、map、weakset、weakmap

function DataType(tgt, type) {
    const dataType = Object.prototype.toString.call(tgt).replace(/\[object /g, "").replace(/\]/g, "").toLowerCase();
    return type ? dataType === type : dataType;
}
DataType("young"); // "string"
DataType(20190214); // "number"
DataType(true); // "boolean"
DataType([], "array"); // true
DataType({}, "array"); // false

是否为空数组

const arr = [];
const flag = Array.isArray(arr) && !arr.length;
// flag => true

是否为空对象

const obj = {};
const flag = DataType(obj, "object") && !Object.keys(obj).length;
// flag => true

满足条件时执行

const flagA = true; // 条件A
const flagB = false; // 条件B
(flagA || flagB) && Func(); // 满足A或B时执行
(flagA || !flagB) && Func(); // 满足A或不满足B时执行
flagA && flagB && Func(); // 同时满足A和B时执行
flagA && !flagB && Func(); // 满足A且不满足B时执行

为非假值时执行

const flag = false; // undefined、null、""、0、false、NaN
!flag && Func();

数组不为空时执行

const arr = [0, 1, 2];
arr.length && Func();

对象不为空时执行

const obj = { a: 0, b: 1, c: 2 };
Object.keys(obj).length && Func();

函数退出代替条件分支退出

if (flag) {
    Func();
    return false;
}
// 换成
if (flag) {
    return Func();
}

switch/case使用区间

const age = 26;
switch (true) {
    case isNaN(age):
        console.log("not a number");
        break;
    case (age < 18):
        console.log("under age");
        break;
    case (age >= 18):
        console.log("adult");
        break;
    default:
        console.log("please set your age");
        break;
}

Array Skill

克隆数组

const _arr = [0, 1, 2];
const arr = [..._arr];
// arr => [0, 1, 2]

合并数组

const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
const arr = [...arr1, ...arr2];
// arr => [0, 1, 2, 3, 4, 5];

去重数组

const arr = [...new Set([0, 1, 1, null, null])];
// arr => [0, 1, null]

混淆数组

const arr = [0, 1, 2, 3, 4, 5].slice().sort(() => Math.random() - .5);
// arr => [3, 4, 0, 5, 1, 2]

清空数组

const arr = [0, 1, 2];
arr.length = 0;
// arr => []

截断数组

const arr = [0, 1, 2];
arr.length = 2;
// arr => [0, 1]

交换赋值

let a = 0;
let b = 1;
[a, b] = [b, a];
// a b => 1 0

过滤空值:undefined、null、””、0、false、NaN

const arr = [undefined, null, "", 0, false, NaN, 1, 2].filter(Boolean);
// arr => [1, 2]

异步累计

async function Func(deps) {
    return deps.reduce(async(t, v) => {
        const dep = await t;
        const version = await Todo(v);
        dep[v] = version;
        return dep;
    }, Promise.resolve({}));
}
const result = await Func(); // 需在async包围下使用

数组首部插入成员

let arr = [1, 2]; // 以下方法任选一种
arr.unshift(0);
arr = [0].concat(arr);
arr = [0, ...arr];
// arr => [0, 1, 2]

数组尾部插入成员

let arr = [0, 1]; // 以下方法任选一种
arr.push(2);
arr.concat(2);
arr[arr.length] = 2;
arr = [...arr, 2];
// arr => [0, 1, 2]

统计数组成员个数

const arr = [0, 1, 1, 2, 2, 2];
const count = arr.reduce((t, c) => {
    t[c] = t[c] ? ++ t[c] : 1;
    return t;
}, {});
// count => { 0: 1, 1: 2, 2: 3 }

解构数组成员嵌套

const arr = [0, 1, [2, 3, [4, 5]]];
const [a, b, [c, d, [e, f]]] = arr;
// a b c d e f => 0 1 2 3 4 5

解构数组成员别名

const arr = [0, 1, 2];
const { 0: a, 1: b, 2: c } = arr;
// a b c => 0 1 2

解构数组成员默认值

const arr = [0, 1, 2];
const [a, b, c = 3, d = 4] = arr;
// a b c d => 0 1 2 4

获取随机数组成员

const arr = [0, 1, 2, 3, 4, 5];
const randomItem = arr[Math.floor(Math.random() * arr.length)];
// randomItem => 1

创建指定长度数组

const arr = [...new Array(3).keys()];
// arr => [0, 1, 2]

创建指定长度且值相等的数组

const arr = new Array(3).fill(0);
// arr => [0, 0, 0]

reduce代替map和filter

const _arr = [0, 1, 2];

// map
const arr = _arr.map(v => v * 2);
const arr = _arr.reduce((t, c) => {
    t.push(c * 2);
    return t;
}, []);
// arr => [0, 2, 4]

// filter
const arr = _arr.filter(v => v > 0);
const arr = _arr.reduce((t, c) => {
    c > 0 && t.push(c);
    return t;
}, []);
// arr => [1, 2]

// map和filter
const arr = _arr.map(v => v * 2).filter(v => v > 2);
const arr = _arr.reduce((t, c) => {
    c = c * 2;
    c > 2 && t.push(c);
    return t;
}, []);
// arr => [4]

Object Skill

克隆对象

const _obj = { a: 0, b: 1, c: 2 }; // 以下方法任选一种
const obj = { ..._obj };
const obj = JSON.parse(JSON.stringify(_obj));
// obj => { a: 0, b: 1, c: 2 }

合并对象

const obj1 = { a: 0, b: 1, c: 2 };
const obj2 = { c: 3, d: 4, e: 5 };
const obj = { ...obj1, ...obj2 };
// obj => { a: 0, b: 1, c: 3, d: 4, e: 5 }

对象字面量:获取环境变量时必用此方法,用它一直爽,一直用它一直爽

const env = "prod";
const link = {
    dev: "Development Address",
    test: "Testing Address",
    prod: "Production Address"
}[env];
// link => "Production Address"

对象变量属性

const flag = false;
const obj = {
    a: 0,
    b: 1,
    [flag ? "c" : "d"]: 2
};
// obj => { a: 0, b: 1, d: 2 }

创建纯空对象

const obj = Object.create(null);
Object.prototype.a = 0;
// obj => {}

删除对象无用属性

const obj = { a: 0, b: 1, c: 2 }; // 只想拿b和c
const { a, ...rest } = obj;
// rest => { b: 1, c: 2 }

解构对象属性嵌套

const obj = { a: 0, b: 1, c: { d: 2, e: 3 } };
const { c: { d, e } } = obj;
// d e => 2 3

解构对象属性别名

const obj = { a: 0, b: 1, c: 2 };
const { a, b: d, c: e } = obj;
// a d e => 0 1 2

解构对象属性默认值

const obj = { a: 0, b: 1, c: 2 };
const { a, b = 2, d = 3 } = obj;
// a b d => 0 1 3

Function Skill

函数自执行

const Func = function() {}(); // 常用

(function() {})(); // 常用
(function() {}()); // 常用
[function() {}()];

+ function() {}();
- function() {}();
~ function() {}();
! function() {}();

new function() {};
new function() {}();
void function() {}();
typeof function() {}();
delete function() {}();

1, function() {}();
1 ^ function() {}();
1 > function() {}();

隐式返回值:只能用于单语句返回值箭头函数,如果返回值是对象必须使用()包住

const Func = function(name) {
    return "I Love " + name;
};
// 换成
const Func = name => "I Love " + name;

一次性函数:适用于运行一些只需执行一次的初始化代码

function Func() {
    console.log("x");
    Func = function() {
        console.log("y");
    }
}

惰性载入函数:函数内判断分支较多较复杂时可大大节约资源开销

function Func() {
    if (a === b) {
        console.log("x");
    } else {
        console.log("y");
    }
}
// 换成
function Func() {
    if (a === b) {
        Func = function() {
            console.log("x");
        }
    } else {
        Func = function() {
            console.log("y");
        }
    }
    return Func();
}

检测非空参数

function IsRequired() {
    throw new Error("param is required");
}
function Func(name = IsRequired()) {
    console.log("I Love " + name);
}
Func(); // "param is required"
Func("You"); // "I Love You"

字符串创建函数

const Func = new Function("name", "console.log(\"I Love \" + name)");

优雅处理错误信息

try {
    Func();
} catch (e) {
    location.href = "https://stackoverflow.com/search?q=[js]+" + e.message;
}

优雅处理Async/Await参数

function AsyncTo(promise) {
    return promise.then(data => [null, data]).catch(err => [err]);
}
const [err, res] = await AsyncTo(Func());

优雅处理多个函数返回值

function Func() {
    return Promise.all([
        fetch("/user"),
        fetch("/comment")
    ]);
}
const [user, comment] = await Func(); // 需在async包围下使用

DOM Skill

显示全部DOM边框:调试页面元素边界时使用

[].forEach.call($$("*"), dom => {
    dom.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16);
});

自适应页面:页面基于一张设计图但需做多款机型自适应,元素尺寸使用rem进行设置

function AutoResponse(width = 750) {
    const target = document.documentElement;
    target.clientWidth >= 600
        ? (target.style.fontSize = "80px")
        : (target.style.fontSize = target.clientWidth / width * 100 + "px");
}

过滤XSS

function FilterXss(content) {
    let elem = document.createElement("div");
    elem.innerText = content;
    const result = elem.innerHTML;
    elem = null;
    return result;
}

存取LocalStorage:反序列化取,序列化存

const love = JSON.parse(localStorage.getItem("love"));
localStorage.setItem("love", JSON.stringify("I Love You"));

作者:JowayYoung
链接:https://juejin.im/post/5cc7afdde51d456e671c7e48
来源:掘金

By柏小白

使用VisualSVN Server创建版本库

  1. 打开VisualSVN Server Manager,可以在窗口的右边看到版本库的一些信息,比如状态,日志,用户认证,版本库等.要建立版本库,需要右键单击左边窗口的Repositores,如下图所示:

    使用VisualSVN Server创建版本库
  2. 2

    在弹出的右键菜单中选择Create New Repository或者新建->Repository,进入下一步,如下图所示:

    使用VisualSVN Server创建版本库
  3. 3

    输入版本库名称,勾上Create default structure复选框(推荐这么做).点击OK,版本库就创建好了,版本库中会默认建立trunk,branches,tags三个文件夹,如下图所示:

    使用VisualSVN Server创建版本库
    使用VisualSVN Server创建版本库
  4. 4

    这时候我们将项目导入到版本库中,找到你的项目文件夹,在项目文件夹上点击鼠标右键,找到SVN菜单,选择导入,如下图所示:

    使用VisualSVN Server创建版本库
  5. 5

    在弹出的对话框中填上版本库URL,这个URL可以从VisualSVN Server Manager中获取,在你的版本库上单击右键,选择Copy URL to Clipboard,这样就把版本库URL复制到你的剪贴版了.如下图所示:

    使用VisualSVN Server创建版本库
  6. 6

    将复制的版本库URL粘贴上,在URL后面加上trunk子路径。然后在导入信息里面填上导入信息”导入项目到版本库“,如下图所示:

    使用VisualSVN Server创建版本库
  7. 7

    点击确定,所选中的项目就会被导入到版本库中,如下图所示:

    使用VisualSVN Server创建版本库
  8. 8

    项目导入到版本库以后,不能随便让谁都能够读写版本库,所以需要建立用户组和用户。

    VisualSVN Server Manager窗口的左侧右键单击用户组,选择Create User或者新建->User,如下图所示:

    使用VisualSVN Server创建版本库
  9. 在弹出的对话框中填写User namePassword,然后点击OK,如下图所示:

    使用VisualSVN Server创建版本库
  10. 用相同的方式分别创建用户Develpoer1,Develpoer2,Develpoer3,Test1,Test2,Manger六个用户,分别代表3个开发人员,两个测试人员和一个项目经理,如下图所示:

    使用VisualSVN Server创建版本库
  11. 然后我们建立用户组,在VisualSVN Server Manager窗口的左侧右键单击用户组,选择Create Group或者新建->Group,如图:

    使用VisualSVN Server创建版本库
  12. 在弹出窗口中填写Group nameDevelopers,然后点Add按钮,在弹出的窗口中选择三个Developer,加入到这个组,然后点Ok,如下图所示:

    使用VisualSVN Server创建版本库
  13. 用相同的方式创建组Managers,Testers,如下图所示:

    使用VisualSVN Server创建版本库
  14. 接下来我们给用户组设置权限,在MyRepository上单击右键,选择属性,如下图所示:

    使用VisualSVN Server创建版本库
  15. 在弹出的对话框中,选择Security选项卡,点击Add按钮,选中Developers,Managers,Testers三个组,然后添加进来,给Developers,Managers权限设置为Read/Write,Tester权限设置为Read Only,如下图所示:

    使用VisualSVN Server创建版本库
  16. 到此,服务端就完成了。接下来,我们用客户端去检出代码,在桌面空白处单击右键,选择SVN检出,在弹出的对话框中填写版本库URL,选择检出目录,点击确定。如下图所示:

    使用VisualSVN Server创建版本库
  17. 开始检出项目,如下图所示:

    使用VisualSVN Server创建版本库
  18. 检出完成之后,我们打开工作副本文件夹,会看到所有文件和文件夹都有一个绿色的√。至此,创建版本库和使用TortoiseSVN导入项目,检出项目已经介绍完毕。

    如下图所示:

    使用VisualSVN Server创建版本库

 

By柏小白

WebStorm打开后无法显示文件夹目录

昨天乱整,WebStorm打开项目,发现项目的文件夹目录不见了 google 一哈,发现解决的方法!!!
项目文件夹目录消失
问题原因:WebStorm自动生成的配置文件 .idea/modules.xml损坏(就是我一开始乱搞,删项目照成)。

11

解决方法 = {

    1: "关掉webstorm;",

    2: "删除.idea文件夹(如果隐藏,请设置显示隐藏文件夹);",

    3: "重新打开项目;",

    4: "OK 搞定"
}
By柏小白

jQuery-插件开发全解析

之前写过一篇文章:jquery.fn.extend与jquery.extend插件开发

现在收集了更详细的解释文档

jQuery插件的开发包括两种:

一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法。jQuery的全局函数就是属于jQuery命名空间的函数,另一种是对象级别的插件开发,即给jQuery对象添加方法。下面就两种函数的开发做详细的说明。

1、类级别的插件开发

类级别的插件开发最直接的理解就是给jQuery类添加类方法,可以理解为添加静态方法。典型的例子就是$.AJAX()这个函数,将函数定义于jQuery的命名空间中。关于类级别的插件开发可以采用如下几种形式进行扩展:

1.1 添加一个新的全局函数

添加一个全局函数,我们只需如下定义:

jQuery.foo = function() {    
alert('This is a test. This is only a test.');   
};

1.2 增加多个全局函数

添加多个全局函数,可采用如下定义:

jQuery.foo = function() {    
alert('This is a test. This is only a test.');   
};   
jQuery.bar = function(param) {    
alert('This function takes a parameter, which is "' + param + '".');   
};    
// 调用时和一个函数的一样的:jQuery.foo();jQuery.bar();或者$.foo();$.bar('bar');

1.3 使用jQuery.extend(object);

jQuery.extend({      
foo: function() {      
alert('This is a test. This is only a test.');      
},      
bar: function(param) {      
alert('This function takes a parameter, which is "' + param +'".');      
}     
});
1.4 使用命名空间

虽然在jQuery命名空间中,我们禁止使用了大量的javaScript函数名和变量名。但是仍然不可避免某些函数或变量名将于其他jQuery插件冲突,因此我们习惯将一些方法封装到另一个自定义的命名空间。

jQuery.myPlugin = {           
foo:function() {           
alert('This is a test. This is only a test.');           
},           
bar:function(param) {           
alert('This function takes a parameter, which is "' + param + '".');     
}          
};   
// 采用命名空间的函数仍然是全局函数,调用时采用的方法:   
$.myPlugin.foo();          
$.myPlugin.bar('baz');

通过这个技巧(使用独立的插件名),我们可以避免命名空间内函数的冲突。

2、对象级别的插件开发

对象级别的插件开发需要如下的两种形式:

形式1:

(function($){      
$.fn.extend({      
pluginName:function(opt,callback){      
// Our plugin implementation code goes here.        
}      
})      
})(jQuery);

形式2:

(function($) {        
$.fn.pluginName = function() {      
// Our plugin implementation code goes here.      
};      
})(jQuery);

上面定义了一个jQuery函数,形参是$,函数定义完成之后,把jQuery这个实参传递进去.立即调用执行。这样的好处是,我们在写jQuery插件时,也可以使用$这个别名,而不会与prototype引起冲突.

2.1 在JQuery名称空间下申明一个名字

这是一个单一插件的脚本。如果你的脚本中包含多个插件,或者互逆的插件(例如: $.fn.doSomething() 和$.fn.undoSomething()),那么你需要声明多个函数名字。但是,通常当我们编写一个插件时,力求仅使用一个名字来包含它的所有内容。我们的示例插件命名为“highlight“

$.fn.hilight = function() {     
  // Our plugin implementation code goes here.     
};     
我们的插件通过这样被调用:   
$('#myDiv').hilight();

但是如果我们需要分解我们的实现代码为多个函数该怎么办?有很多原因:设计上的需要;这样做更容易或更易读的实现;而且这样更符合面向对象。 这真是一个麻烦事,把功能实现分解成多个函数而不增加多余的命名空间。出于认识到和利用函数是javascript中最基本的类对象,我们可以这样做。就像其他对象一样,函数可以被指定为属性。因此我们已经声明“hilight”为jQuery的属性对象,任何其他的属性或者函数我们需要暴露出来的,都可以在”hilight” 函数中被声明属性。稍后继续。

2.2 接受options参数以控制插件的行为

让我们为我们的插件添加功能指定前景色和背景色的功能。我们也许会让选项像一个options对象传递给插件函数。例如:

// plugin definition     
$.fn.hilight = function(options) {     
  var defaults = {     
   foreground: 'red',     
   background: 'yellow'     
  };     
// Extend our default options with those provided.     
  var opts = $.extend(defaults, options);     
// Our plugin implementation code goes here.     
};     
// 我们的插件可以这样被调用:   
$('#myDiv').hilight({     
  foreground: 'blue'     
});

2.3 暴露插件的默认设置

我们应该对上面代码的一种改进是暴露插件的默认设置。这对于让插件的使用者更容易用较少的代码覆盖和修改插件。接下来我们开始利用函数对象。

// plugin definition     
$.fn.hilight = function(options) {     
  // Extend our default options with those provided.     
  // Note that the first arg to extend is an empty object -     
  // this is to keep from overriding our "defaults" object.     
  var opts = $.extend({}, $.fn.hilight.defaults, options);     
  // Our plugin implementation code goes here.     
};     
// plugin defaults - added as a property on our plugin function     
$.fn.hilight.defaults = {     
  foreground: 'red',     
  background: 'yellow'     
};      
//现在使用者可以包含像这样的一行在他们的脚本里:   
//这个只需要调用一次,且不一定要在ready块中调用   
$.fn.hilight.defaults.foreground = 'blue';     
//接下来我们可以像这样使用插件的方法,结果它设置蓝色的前景色:   
$('#myDiv').hilight();

如你所见,我们允许使用者写一行代码在插件的默认前景色。而且使用者仍然在需要的时候可以有选择的覆盖这些新的默认值:

// 覆盖插件缺省的背景颜色 

$.fn.hilight.defaults.foreground = 'blue'; 

// ... 

// 使用一个新的缺省设置调用插件 

$('.hilightDiv').hilight(); 

// ... 

// 通过传递配置参数给插件方法来覆盖缺省设置 

$('#green').hilight({ 

 foreground: 'green' 

}); 

2.4 适当的暴露一些函数

这段将会一步一步对前面那段代码通过有意思的方法扩展你的插件(同时让其他人扩展你的插件)。例如,我们插件的实现里面可以定义一个名叫”format”的函数来格式化高亮文本。我们的插件现在看起来像这样,默认的format方法的实现部分在hiligth函数下面。

// plugin definition     
$.fn.hilight = function(options) {     
// iterate and reformat each matched element     
  return this.each(function() {     
    var $this = $(this);     
// ...     
    var markup = $this.html();     
// call our format function     
    markup = $.fn.hilight.format(markup);     
    $this.html(markup);     
  });     
};     
// define our format function     
$.fn.hilight.format = function(txt) {     
return '<strong>' + txt + '</strong>';     
};

我们很容易的支持options对象中的其他的属性通过允许一个回调函数来覆盖默认的设置。这是另外一个出色的方法来修改你的插件。这里展示的技巧是进一步有效的暴露format函数进而让他能被重新定义。通过这技巧,是其他人能够传递他们自己设置来覆盖你的插件,换句话说,这样其他人也能够为你的插件写插件。

考虑到这个篇文章中我们建立的无用的插件,你也许想知道究竟什么时候这些会有用。一个真实的例子是Cycle插件.这个Cycle插件是一个滑动显示插件,他能支持许多内部变换作用到滚动,滑动,渐变消失等。但是实际上,没有办法定义也许会应用到滑动变化上每种类型的效果。那是这种扩展性有用的地方。 Cycle插件对使用者暴露”transitions”对象,使他们添加自己变换定义。插件中定义就像这样:
$.fn.cycle.transitions = { 

// ... 

};

这个技巧使其他人能定义和传递变换设置到Cycle插件。

2.5 保持私有函数的私有性

这种技巧暴露你插件一部分来被覆盖是非常强大的。但是你需要仔细思考你实现中暴露的部分。一但被暴露,你需要在头脑中保持任何对于参数或者语义的改动也许会破坏向后的兼容性。一个通理是,如果你不能肯定是否暴露特定的函数,那么你也许不需要那样做。

那么我们怎么定义更多的函数而不搅乱命名空间也不暴露实现呢?这就是闭包的功能。为了演示,我们将会添加另外一个“debug”函数到我们的插件中。这个 debug函数将为输出被选中的元素格式到firebug控制台。为了创建一个闭包,我们将包装整个插件定义在一个函数中。

 (function($) {     
// plugin definition     
  $.fn.hilight = function(options) {     
    debug(this);     
// ...     
  };     
// private function for debugging     
  function debug($obj) {     
  if (window.console && window.console.log)     
 window.console.log('hilight selection count: ' + $obj.size()); 
  };     
//  ...     
})(jQuery);

我们的“debug”方法不能从外部闭包进入,因此对于我们的实现是私有的。

2.6 支持Metadata插件

在你正在写的插件的基础上,添加对Metadata插件的支持能使他更强大。个人来说,我喜欢这个Metadata插件,因为它让你使用不多的”markup”覆盖插件的选项(这非常有用当创建例子时)。而且支持它非常简单。更新:注释中有一点优化建议。

$.fn.hilight = function(options) {     
// ...     
// build main options before element iteration     
  var opts = $.extend({}, $.fn.hilight.defaults, options);   
  return this.each(function() {     
   var $this = $(this);     
//build element specific options     
 var o = $.meta ? $.extend({}, opts, $this.data()) : opts  
//...

这些变动行做了一些事情:它是测试Metadata插件是否被安装如果它被安装了,它能扩展我们的options对象通过抽取元数据这行作为最后一个参数添加到JQuery.extend,那么它将会覆盖任何其它选项设置。现在我们能从”markup”处驱动行为,如果我们选择了“markup”:

调用的时候可以这样写: jQuery.foo(); 或 $.foo();

<!--  markup  -->     
<div class="hilight { background: 'red', foreground: 'white' } 
  Have a nice day!     
</div>     
<div class="hilight { foreground: 'orange' }">     
  Have a nice day!     
</div>     
<div class="hilight { background: 'green' }">     
  Have a nice day!     
</div>     
现在我们能高亮哪些div仅使用一行脚本:   
$('.hilight').hilight();

2.7 整合
下面使我们的例子完成后的代码:

// 创建一个闭包     
(function($) {     
  // 插件的定义     
  $.fn.hilight = function(options) {     
    debug(this);     
    // build main options before element iteration     
    var opts = $.extend({}, $.fn.hilight.defaults, options) 
    // iterate and reformat each matched element     
    return this.each(function() {     
      $this = $(this);     
      // build element specific options     
      var o = $.meta ? $.extend({}, opts, $this.data()) : opts;     
      // update element styles     
      $this.css({     
        backgroundColor: o.background,     
        color: o.foreground     
      });     
      var markup = $this.html();     
      // call our format function     
      markup = $.fn.hilight.format(markup);     
      $this.html(markup);     
    });     
  };     
  // 私有函数:debugging     
  function debug($obj) {     
    if (window.console && window.console.log)     
      window.console.log('hilight selection count: ' + $obj.size());     
  };     
  // 定义暴露format函数     
  $.fn.hilight.format = function(txt) {     
    return '<strong>' + txt + '</strong>';     
  };     
  // 插件的defaults     
  $.fn.hilight.defaults = {     
    foreground: 'red',     
    background: 'yellow'     
  };     
// 闭包结束     
})(jQuery);

这段设计已经让我创建了强大符合规范的插件。我希望它能让你也能做到。

3、总结

jQuery为开发插件提拱了两个方法,分别是:

jQuery.fn.extend(object);  给jQuery对象添加方法。
jQuery.extend(object);  为扩展jQuery类本身.为类添加新的方法。

3.1 jQuery.fn.extend(object);

fn 是什么东西呢。查看jQuery代码,就不难发现。

jQuery.fn = jQuery.prototype = {  

init: function( selector, context ) {//....   

//......  

};

原来 jQuery.fn = jQuery.prototype.对prototype肯定不会陌生啦。虽然 javascript 没有明确的类的概念,但是用类来理解它,会更方便。jQuery便是一个封装得非常好的类,比如我们用 语句 $(“#btn1”) 会生成一个 jQuery类的实例。

jQuery.fn.extend(object); 对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使用这个“成员函数”。

比如我们要开发一个插件,做一个特殊的编辑框,当它被点击时,便alert 当前编辑框里的内容。可以这么做:

$.fn.extend({        

     alertWhileClick:function(){       

         $(this).click(function(){      

              alert($(this).val());       

          });       

      }       

});

$(“#input1″).alertWhileClick(); //页面上为:<input id=”input1” type=”text”/>

$(“#input1”) 为一个jQuery实例,当它调用成员方法 alertWhileClick后,便实现了扩展,每次被点击时它会先弹出目前编辑里的内容。

 

3.2 jQuery.extend(object);

为jQuery类添加添加类方法,可以理解为添加静态方法。如:

$.extend({  

    add:function(a,b){return a+b;}  

});

便为jQuery添加一个为add的“静态方法”,之后便可以在引入jQuery的地方,使用这个方法了,$.add(3,4); //return 7

By柏小白

使用WebStorm集成开发环境Less解析安装与配置

 

1.安Node.JS

由于Less是使用JS开发的,所以Less运行时依赖Node.JS,如果你电脑之前没有安装过Node.JS,还需下载安装Node.JS

柏小白-小白变大神

node.js官网 下载

安装过程都是一路下一步。安装完成后打开控制台输入node -v,如果能显示出版本号就说明,安装成功了。

2.替换淘宝镜像 CNPM

由于长城牌防火墙的原因,可能NPM(Node.js的包管理工具)无法访问到服务器,这时就可替换成淘宝的NPM镜像

打开控制台直接输入:
npm install -g cnpm –registry=https://registry.npm.taobao.org
MAC平台前面还需加一个sodo

3.安装Less

打开控制台直接输入:
cnpm install -g less
接着输入lessc -v能看到版本号就表示安装成功了

4.添加File Watchers

打开WebStorm,点击文件—>设置—>File Watchers—>右边的+

柏小白-小白变大神

Less配置

program:你Node安装路径下的lessc.cmd
arguments:–no-color –source-map=$FileNameWithoutExtension$.css.map $FileName$ 
working directory:$FileDir$
output paths to refresh:$FileNameWithoutExtension$.css:$FileNameWithoutExtension$.css.map

之后你只要在项目中添加一个.less文件,系统就会自动为你编译了。

By柏小白

提高博客wordpres后台安全性的详细方法

加强安全设置,以避免因为漏洞而遭到不必要的损失

具体方法:

1)使用插件

1.1  使用Stealth Login Page 插件    使用方法 

1.2  使用 Protected wp-login 插件

chajian

使用方法“度娘”(个人建议Google),度娘全是给钱排名,么么哒(*  ̄3)(ε ̄ *)。。

Read More

By柏小白

jquery.fn.extend与jquery.extend插件开发

jQuery为开发插件提拱了两个方法,分别是:

JavaScript代码

  • jQuery.fn.extend(object);
  • jQuery.extend(object);

Read More

By柏小白

Nginx配置文件nginx.conf中文详解

Ps:nginx真的没用过几次,每次都是搭的apache

转自:http://www.ha97.com/5194.html

PS:Nginx使 用有两三年了,现在经常碰到有新用户问一些很基本的问题,我也没时间一一回答,今天下午花了点时间,结合自己的使用经验,把Nginx的主要配置参数说明 分享一下,也参考了一些网络的内容,这篇是目前最完整的Nginx配置参数中文说明了。更详细的模块参数请参 考:http://wiki.nginx.org/Main


#定义Nginx运行的用户和用户组
user www www;

#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 8;

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;

#进程文件
pid /var/run/nginx.pid;

#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
worker_rlimit_nofile 65535;

#工作模式与连接数上限
events
{
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
use epoll;
#单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 65535;
}

#设定http服务器
http
{
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型
#charset utf-8; #默认编码
server_names_hash_bucket_size 128; #服务器名字的hash表大小
client_header_buffer_size 32k; #上传文件大小限制
large_client_header_buffers 4 64k; #设定请求缓
client_max_body_size 8m; #设定请求缓
sendfile on; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改 成off。
autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。
tcp_nopush on; #防止网络阻塞
tcp_nodelay on; #防止网络阻塞
keepalive_timeout 120; #长连接超时时间,单位是秒

#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

#gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
gzip_types text/plain application/x-javascript text/css application/xml;
#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用

upstream blog.ha97.com {
#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
server 192.168.80.121:80 weight=3;
server 192.168.80.122:80 weight=2;
server 192.168.80.123:80 weight=3;
}

#虚拟主机的配置
server
{
#监听端口
listen 80;
#域名可以有多个,用空格隔开
server_name www.ha97.com ha97.com;
index index.html index.htm index.php;
root /data/www/ha97;
location ~ .*.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
#图片缓存时间设置
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 10d;
}
#JS和CSS缓存时间设置
location ~ .*.(js|css)?$
{
expires 1h;
}
#日志格式设定
log_format access ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” $http_x_forwarded_for’;
#定义本虚拟主机的访问日志
access_log /var/log/nginx/ha97access.log access;

#对 “/” 启用反向代理
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可选。
proxy_set_header Host $host;
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
}

#设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic “NginxStatus”;
auth_basic_user_file conf/htpasswd;
#htpasswd文件的内容可以用apache提供的htpasswd工具来产生。
}

#本地动静分离反向代理配置
#所有jsp的页面均交由tomcatresin处理
location ~ .(jsp|jspx|do)?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
#所有静态文件由nginx直接读取不经过tomcat或resin
location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$
{ expires 15d; }
location ~ .*.(js|css)?$
{ expires 1h; }
}
}

更详细的模块参数请参考:http://wiki.nginx.org/Main

By柏小白

Nginx下修改wordpress固定链接后导致访问文章404

开始做seo的优化,当然牵扯到永久链接,wordpress提供多种类型的链接形式

1/%year%/%monthnum%/%day%/%postname%/

2/%year%/%monthnum%/%postname%/

3/%year%/%monthnum%/%day%/%postname%.html

4/%year%/%monthnum%/%postname%.html

5/%category%/%postname%.html

6/%post_id%.html

7/%postname%/

我选择了/%postname%.html,伪静态,虽然现在貌似没什么差别了,但还是该下吧。下面就出现了修改固定链接后,访问文章会出现404错误,以前我都是apache做web服务器,所以只要apache下就三个个关键,即

  1. wordpress对目录下的.htaccess拥有读写权限
  2. 固定链接的目录结构需要 Apache服务器的mod_rewrite模块支持,所以在Apache配置文件httpd.conf中将 LoadModule rewrite_module modules/mod_rewrite.so设置为启用。
  3. 同样是Apache配置文件,其中对于站点目录下的AllowOverride None的参数设置为All。当然修改完配置后,一定要重启Apache服务。
  4. 由于是新配置的本地测试环境,2、3两项问题同时出现,逐项更正设置后,固定链接的工作正常。

现在我用的nginix,所以也要修改nginix的ngnix.conf配置文件,让其支持重定向

假设我的wordpress博客是的 server{}段是直接放到放到了nginx.conf  (有的人为了方便管理,都习惯在单独写个vhost/目录来存放每个网站的配置文件,这就要根据你自己的设置来添加了)

vi /your_nginx_path/conf/nginx.conf

按照nginix的正则表达式的规则,可参考:Nginx 的中文维基

  • ^:匹配输入字符的开始位置
  • $:匹配数日字符串的结束位置
  • +:匹配前面的子表达式一次或者多次
  • [0-9]:数字字符范围
  • $1:调用变量

在server{}  字段   中的  “root /websit/wwwroot/;”(这行就是指定网站所在目录的)  这一行的下面 ,添加下面的内容:

         

if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}

rewrite /wp-admin$ $scheme://$host$uri/ permanent;//这行是为了防止打开后台、插件页等打不开的。

保存后,输入    /etc/init.d/nginx restart , 重启nginix。就ok了!

相当于告诉nginix访问这些后按照正则表达式转到其唯一正确的地址,以此打开文章。

貌似/%postname%/会以中文为链接,为了seo,可以考虑一个插件 WP Slug Translate,它会自动换中文标题为英文,不能联网就改为拼音。

By柏小白

javascript简单滚动

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8" />
    <title>简单滚动</title>
    <script src="http://code.jquery.com/jquery-1.7.min.js"></script>
</head>
<body>
    <h1>简单滚动</h1>
    <style type="text/css">
/*简单滚动*/

.scroll{width:300px;height:25px;line-height:25px;border:#ccc 1px solid;overflow:hidden}
.scroll a{height:25px;display:block;padding-left:10px;}
</style>
    <!--简单滚动-->
    <div class="scroll">
        <div>
            <a>这是公告标题的第一行</a>
            <a>这是公告标题的第二行</a>
            <a>这是公告标题的第三行</a>
        </div>

    </div>
    <script type="text/javascript">

            // 简单滚动
            function AutoScroll(obj){
                $(obj).find("div").animate({
                    marginTop:"-25px"
                },1000,function(){
                    $(this).css({marginTop:"0px"}).find("a:first").appendTo(this);
                });
            }

            $(function(){
                setInterval('AutoScroll(".scroll")',3000)

            });



</script>

</body>

</html>

 





简单滚动


简单滚动

By柏小白

谈谈JavaScript匿名函数

 

匿名函数的概念大家也许不会陌生,但是我相信下面的内容会打开一些新的思路。

我们知道函数的定义方式有两种:

1 function fn1(){alert(‘fn1 works’);}

2 var fn2=function(){alert(‘fn2 works’);}

这两种方式有什么区别?思考一下…

1 第一种方式定义函数,函数声明过程在整个程序执行之前的预处理就完成了,所以只要处于同一个作用域,就可以访问到,即使在定义之前调用它也可以。

2 第二章方式就是匿名函数,这种方式函数只能按照程序流程执行到定义的那一行代码才被声明,所以只能在定义之后调用它。

举个例子

var fn1;

fn1();//报错

fn1=function(){

fn2();//fn2 works

alert(‘fn1 works’);

return false;

function fn2(){

alert(‘fn2 works’);

}

}

fn1();//fn2 works + fn1 works

我们看到fn2虽然处在return之后,程序流程并没有执行到它,但是它依然可以被使用,反之fn2只有在它被定义之后才会被正常执行。

明白了这个,下面看一看匿名函数在递归里用处

递归就是函数内部调用自己,举个例子

function fn1(n){
return n>2?fn1(n-1)+fn1(n-2):n;
}

当我们想把这个函数赋给其他的对象属性时,就要用到匿名函数,比如

obj1={

fn:function(n){

return n>2?obj1.fn(n-1)+obj1.fn(n-2):n;
}
}
obj2={
fn:obj.fn;
}
这个时候可以正常调用obj2.fn(),但是这里有一个隐患,我们必须保证obj1里的fn不能被覆盖,看下面的例子
obj1={}
obj2.fn();
obj1被清空,执行出错,怎么办,解决办法有很多,自己先想一个…
最容易的想到的是使用this,更改obj1里面fn的定义如下

obj1={

fn:function(n){

return n>2?this.fn(n-1)+this.fn(n-2):n;
}
}
这样即使obj1里的fn被改写也不影响obj2.fn(),但是this,你迷惑吗?
this在JavaScript里面绝对是一个难理解的概念,理解了最好,但是很多时候其实不一定非得用this,这个例子中,我们可以选个给匿名函数添加个名字

obj1={

fn:function fnname(n){

return n>2?fnname(n-1)+fnname(n-2):n;
}
}
我们发现和this的结果一样,但是这就避开了this的混淆视听,而且注意这个函数名只有函数内部可以访问,外部是访问不了的(请私下测试),这样就能避免诸如全局变量的问题。
还有一种解决方案,这个方案是最优雅的,所以我要作为大礼送给大家
我们知道有个arguments对象,这个对象里面有好多好玩的属性和方法,其中一个叫做callee,它的作用是调用函数本身!继续修改上面的例子

obj1={

fn:function(n){

return n>2?arguments.callee(n-1)+arguments.callee(n-2):n;
}
}
这个是目前我发现最优雅的方法,大家有其他更好的方案可以拿来讨论。
匿名函数的讨论先到此为止。
By柏小白

jQuery事件绑定的最佳实践

如果你经常使用jQuery,那么你也许很熟悉事件绑定。这是很基本的东西,但是深入一点,你就能够找到机会让你事件驱动的代码变得不太零碎,并且更容易管理。

更好的选择器策略

让我们从基础的例子开始。下面的HTML代码表示的是可以开合的导航菜单。

<button class="nav-menu-toggle">Toggle Nav Menu</button>
<nav>
<ul>
<li><a href="/">West Philadelphia</a></li>
<li><a href="/cab">Cab Whistling</a></li>
<li><a href="/throne">Throne Sitting</a></li>
</ul>
</nav>

 

下面这个是点击按钮之后控制导航菜单开合的javascript代码

$('.nav-menu-toggle').on('click',function(){
$('nav').toggle();
});

 

这可能是最常用的实现方式。它能够使用,但是比较脆。javascript代码依赖了按钮的类名nav-menu-toggle。很可能在未来其他开发者或者健忘的你在重构代码的时候会删除或者重命名这个类名。

问题的核心是我们同时在表现和交互中使用了CSS的类名。这违反了关注点分离的原则,让维护更容易出错。

让我们用一个不同的方法来实现

<button data-hook="nav-menu-toggle">Toggle Nav Menu</button>
<nav data-hook="nav-menu">
<ul>
<li><a href="/">West Philadelphia</a></li>
<li><a href="/cab">Cab Whistling</a></li>
<li><a href="/throne">Throne Sitting</a></li>
</ul>
</nav>

 

这次我们使用这个data属性(data-hook)来选择元素。任何对CSS类的改变将不会影响到javascript,让我们能够实现关注点分离以及更加稳定的代码。

下面我们用data-hook属性来选择对应的元素:

$('[data-hook="nav-menu-toggle"]').on('click',function(){
$('[data-hook="nav-menu"]').toggle();
});

 

需要注意的是,我也使用data-hook作为nav元素的选择器。你不一定需要,但是我喜欢这里面包含的思想:任何使用你看到data-hook,你会知道这个元素在javascript中引用到啦。

一些语法糖

我必须承认data-hook选择器并不是很漂亮。让我们通过扩展jQuery实现一个自定义的函数:

$.extend({
hook:function(hookName){
var selector;
if(!hookName || hookName === '*'){
// select all data-hooks
selector='[data-hook]'
}else{
// select specific data-hook
selector='[data-hook*="'+hookName+'"]';
}
return $(selector);
}
});

 

上面准备完毕,我们来重写一下javascript。

$.hook('nav-menu-toggle').on('',function(){
$.hook('nav-menu').toggle();
});

 

更好的是,我们甚至可以把一系列以空格分开的hook名字放在一个元素上。

<button data-hook="nav-menu-toggle video-pause click-track">Toggle Nav Menu</button>

 

我们可以找到里面的任意个hook名字:

$.hook('click-track'); // returns the button as expected

 

我们也能够找到页面上所有的hook元素

// both are equivalent
$.hook();
$.hook('*');

 

防止函数表达式

到目前为止,我们在事件处理中使用的都是匿名函数。让我们重写一下,使用声明的函数来代替它。

function toggleNavMenu(){
$.hook('nav-menu').toggle();
}

$.hook('nav-menu-toggle').on('click',toggleNavMenu);

 

这让事件绑定的代码更加易读。这个toggleNavMenu函数名表达了意图,是代码自我注释的好例子。

我们同时也获得了可复用的能力,因为其他地方可能需要使用toggleNavMenu函数。

最后,这对于自动化测试来说是意见大喜事,因为声明的函数的单元测试要比匿名函数单元测试容易的多。

同时使用多个事件

jQuery提供了一个简单方便的语法来处理多事件的问题。比如,你可以为一系列空格隔开的事件列表绑定同一个事件处理函数。

$.hook('nav-menu-toggle').on('click keydown mouseenter',trackAction);

 

如果你需要为不同的事件绑定不同的处理函数,你可以使用对象表达方式:

$.hook('nav-menu-toggle').on({
'click':trackClick,
'keydown':tranckKeyDown,
'mouseenter':trackMouseEnter
});

 

反过来,你可以同时取消多个事件的绑定:

// unbinds keydown and mouseenter
$.hook('nav-menu-toggle').off('keydown mouseenter');

// nuclear options:unbinds everything
$.hook('nav-menu-toggle').off();

 

你可以想象到的是,不小心的取消事件绑定可能会导致严重的我们不想要的副作用。继续看我们可以通过哪些技巧来减轻这个问题。

小心的取消事件绑定

一般情况下我们不会在一个元素的同一事件类型绑定多个事件处理函数。让我们再看一下之前的那个按钮:

<button data-hook="nav-menu-toggle video-pause click-track">Toggle Nav Menu</button>

 

不同的代码区域可能会在同一个元素的同一事件绑定不同的事件处理函数:

// somewhere in the nav code
$.hook('nav-menu-toggle').on('click',toggleNavMenu);

// somewhere in the video playback code
$.hook('video-pause').on('click',pauseCarltonDanceVideo);

// somewhere in the analytics code
$.hook('click-track').on('click',trackClick);
尽管我们使用了不同的选择器,但是这个元素现在有三个事件处理函数啦。假如我们的分析代码不在关心这个按钮:
// no good
$.hook('click-track').off('click');

 

糟糕的是,上面的代码实际上回删除所有的点击事件处理函数,不仅仅是trackClick。我们应该实用更加有辨别力的方式来指定我们需要删除的事件处理函数:

$.hook('click-track').off('click',trackClick);

 

另一种方式是使用命名空间。任何事件都有资格使用一个命名空间来实现绑定和取消绑定,这样你就可以更好的控制事件绑定和取消绑定。

// binds a click event in the "analytics" namespace
$.hook('click-track').on('click.analytics', trackClick);

// unbinds only click events in the "analytics" namespace
$.hook('click-track').off('click.analytics');

 

你也可以使用多个命名空间:

// binds a click event in both the "analytics" and "usability" namespaces
$.hook('click-track').on('click.analytics.usability',trackClick);

// unbinds any events in either the "analytics" OR "usability" namespaces
$.hook('click-track').off('.usability .analytics');

// unbinds any events in both the "analytics" AND "usability" namespaces
$.hook('click-track').off('.usability.analytics');

 

需要注意的是,命名空间的顺序是没有关系的,因为命名空间不是层级式的。

如果你有一个复杂的功能需要多个元素绑定多个事件,那么使用命名空间是一种简单的把他们组织起来然后快速清除的方式:

// free all elements on the page of any "analytics" event handling
$('*').off('.analytics');

 

命名空间在写插件的时候尤其有用,因为这样你就能保证只会取消自己命名空间范围内的事件处理函数的绑定。

原文:Effective Event Binding with jQuery

转载:http://segmentfault.com/u/wangfulin

By柏小白

如何让2个并列的div根据内容自动保持同等高度

最近在工作中碰到一个需求:

有左右2个并列的div,2个div都不能限定高度。左div为导航,右div为内容。如何能让左div块自动获得和右div块相等的高度?

同时,也有网友提问到“如果右块高度比左块低,会不会导致左块的内容被溢出不显示之类的问题。应该是取左右2者的最高值吧来对齐吧”。

的确应该是哪个div Height值大,就将其值赋给Height值小的div,从而使2个div高度始终保持一致。看代码:

function $(id){ 
	return document.getElementById(id) 
} 
function getHeight() { 
	if ($("left").offsetHeight>=$("right").offsetHeight){
		$("right").style.height=$("left").offsetHeight + "px";
	}
	else{
		$("left").style.height=$("right").offsetHeight + "px";
	}	
}
window.onload = function() {
	getHeight();
}

经测试,该代码有效。

另外,在实际运用,可能还会存在由于左div或右div存在padding属性而导致上述取值变多或变少的问题。比如,最终赋值时发现left比right还高10px,那么也可以通过修改上述代码解决:

$("left").style.height=$("right").offsetHeight-10 + "px";

 

By柏小白

Html5新标签解释及用法

HTML 5 是一个新的网络标准,目标在于取代现有的 HTML 4.01, XHTML 1.0 and DOM Level 2 HTML 标准。它希望能够减少浏览器对于需要插件的丰富性网络应用服务(plug-in-based rich internet application,RIA),如Adobe Flash, Microsoft Silverlight, 与 Sun JavaFX 的需求。

HTML 5 提供了一些新的元素和属性,反映典型的现代用法网站。其中有些是技术上类似 <div> 和 <span> 标签,但有一定含义,例如 <nav>(网站导航块)和 <footer>。这种标签将有利于搜索引擎的索引整理、小屏幕装置和视障人士使用。同时为其他浏览要素提供了新的功能,通过一个标准接口,如 <audio> 和 <video> 标记。

之前的一篇:HTML5 Shiv – 让该死的IE系列支持HTML5吧介绍了如何让所有浏览器都支持html5标签,你可以放心大胆的用了!

一些过时的 HTML 4 标记将取消,其中包括纯粹用作显示效果的标记,如 <font> 和 <center>,因为它们已经被 CSS 取代。还有一些透过 DOM 的网络行为(via)。

下面我们来看一下HTML 5提供的一些新的标签用法以及和HTML 4的区别。

<article>标签定义外部的内容。比如来自一个外部的新闻提供者的一篇新的文章,或者来自 blog 的文本,或者是来自论坛的文本。亦或是来自其他外部源内容。
HTML5:<article></article>
HTML4:<div></div>

<aside>标签定义 article 以外的内容。aside 的内容应该与 article 的内容相关。
HTML5:<aside>Aside 的内容是独立的内容,但应与文档内容相关。</aside>
HTML4:<div>Aside 的内容是独立的内容,但应与文档内容相关。</div>

<audio> 标签定义声音,比如音乐或其他音频流。
HTML5:<audio src="someaudio.wav">您的浏览器不支持 audio 标签。</audio>
HTML4:<object type="application/ogg" data="someaudio.wav"><param name="src" value="someaudio.wav"></object>

<canvas> 标签定义图形,比如图表和其他图像。这个 HTML 元素是为了客户端矢量图形而设计的。它自己没有行为,但却把一个绘图 API 展现给客户端 JavaScript 以使脚本能够把想绘制的东西都绘制到一块画布上。
HTML5:<canvas id="myCanvas" width="200" height="200"></canvas>
HTML4:<object data="inc/hdr.svg" type="image/svg+xml" width="200" height="200"></object>

<command> 标签定义命令按钮,比如单选按钮、复选框或按钮。
HTML5: <command onclick=cut()" label="cut">
HTML4: none

<datalist> 标签定义可选数据的列表。与 input 元素配合使用,就可以制作出输入值的下拉列表。
HTML5: <datalist></datalist>
HTML4: see combobox.

<details> 标签定义元素的细节,用户可进行查看,或通过点击进行隐藏。与 <legend> 一起使用,来制作 detail 的标题。该标题对用户是可见的,当在其上点击时可打开或关闭 detail。
HTML5: <details></details>
HTML4: <dl style="display:hidden"></dl>

<embed> 标签定义嵌入的内容,比如插件。
HTML5: <embed src="horse.wav" />
HTML4: <object data="flash.swf"  type="application/x-shockwave-flash"></object>

<figcaption> 标签定义 figure 元素的标题。”figcaption” 元素应该被置于 “figure” 元素的第一个或最后一个子元素的位置。
HTML5: <figure><figcaption>PRC</figcaption></figure>
HTML4: none

<figure> 标签用于对元素进行组合。使用 <figcaption> 元素为元素组添加标题。
HTML5: <figure><figcaption>PRC</figcaption><p>The People's Republic of China was born in 1949...</p></figure>
HTML4: <dl><h1>PRC</h1><p>The People's Republic of China was born in 1949...</p></dl>

<footer> 标签定义 section 或 document 的页脚。典型地,它会包含创作者的姓名、文档的创作日期以及/或者联系信息。
HTML5: <footer></footer>
HTML4: <div></div>

<header> 标签定义 section 或 document 的页眉。
HTML5: <header></header>
HTML4: <div></div>

<hgroup> 标签用于对网页或区段(section)的标题进行组合。
HTML5: <hgroup></hgroup>
HTML4: <div></div>

<keygen> 标签定义生成密钥。
HTML5: <keygen>
HTML4: none

<mark>主要用来在视觉上向用户呈现那些需要突出的文字。<mark>标签的一个比较典型的应用就是在搜索结果中向用户高亮显示搜索关键词。
HTML5: <mark></mark>
HTML4: <span></span>

<meter> 标签定义度量衡。仅用于已知最大和最小值的度量。必须定义度量的范围,既可以在元素的文本中,也可以在 min/max 属性中定义。
HTML5: <meter></meter>
HTML4: none

<nav> 标签定义导航链接的部分。
HTML5: <nav></nav>
HTML4:<ul></ul>

<output> 标签定义不同类型的输出,比如脚本的输出。
HTML5: <output></output>
HTML4: <span></span>

<progress> 标签运行中的进程。可以使用 <progress> 标签来显示 JavaScript 中耗费时间的函数的进程。
HTML5: <progress></progress>
HTML4: none

<rp> 标签在 ruby 注释中使用,以定义不支持 ruby 元素的浏览器所显示的内容。
HTML5: <ruby>漢 <rt><rp>(</rp>ㄏㄢˋ<rp>)</rp></rt></ruby>
HTML4: none

<rt> 标签定义字符(中文注音或字符)的解释或发音。
HTML5: <ruby>漢 <rt> ㄏㄢˋ </rt></ruby>
HTML4: none

<ruby> 标签定义 ruby 注释(中文注音或字符)。
HTML5: <ruby>漢 <rt><rp>(</rp>ㄏㄢˋ<rp>)</rp></rt></ruby>
HTML4: none

<section> 标签定义文档中的节(section、区段)。比如章节、页眉、页脚或文档中的其他部分。
HTML5: <section></section>
HTML4: <div></div>

<source> 标签为媒介元素(比如 <video> 和 <audio>)定义媒介资源。
HTML5: <source>
HTML4: <param>

<summary> 标签包含 details 元素的标题,”details” 元素用于描述有关文档或文档片段的详细信息。”summary” 元素应该是 “details” 元素的第一个子元素。
HTML5: <details><summary>HTML 5</summary>This document teaches you everything you have to learn about HTML 5.</details>
HTML4: none

<time> 标签定义日期或时间,或者两者。
HTML5: <time></time>
HTML4: <span></span>

<video> 标签定义视频,比如电影片段或其他视频流。
HTML5: <video src="movie.ogg" controls="controls">您的浏览器不支持 video 标签。</video>
HTML4:<object type="video/ogg" data="movie.ogv"><param name="src" value="movie.ogv"></object>

By柏小白

iframe背景透明设置方法

allowtransparency=”true”

如下:

<iframe width="100%" height="200" src="demo.html" allowTransparency="true" frameBorder="0" scrolling="no"></iframe>

 

By柏小白

针对IE的CSS hack 全面 实用

.all IE{property:value\9;}
.gte IE 8{property:value\0;}
.lte IE 7{*property:value;}
.IE 8/9{property:value\0;}
.IE 9{property:value\9\0;}
.IE 7{+property:value;}
.IE 6{_property:value;}
.not IE{property//:value;}

te:就是Less than or equal to的简写,也就是小于或等于的意思。

lt :就是Less than的简写,也就是小于的意思。

gte:就是Greater than or equal to的简写,也就是大于或等于的意思。

gt :就是Greater than的简写,也就是大于的意思。

!  :就是不等于的意思,跟javascript里的不等于判断符相同

By柏小白

CSS实现单行、多行文本溢出显示省略号(…)

如果实现单行文本的溢出显示省略号同学们应该都知道用text-overflow:ellipsis属性来,当然还需要加宽度width属来兼容部分浏览。

实现方法:

overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;

效果如图:
dome1

但是这个属性只支持单行文本的溢出显示省略号,如果我们要实现多行文本溢出显示省略号呢。

接下来重点说一说多行文本溢出显示省略号,如下。

实现方法:

display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;

效果如图:
dome2

适用范围:
因使用了WebKit的CSS扩展属性,该方法适用于WebKit浏览器及移动端;

注:

  1. -webkit-line-clamp用来限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他的WebKit属性。常见结合属性:
  2. display: -webkit-box; 必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。
  3. -webkit-box-orient 必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 。

实现方法:

p{position: relative; line-height: 20px; max-height: 40px;overflow: hidden;}
p::after{content: "..."; position: absolute; bottom: 0; right: 0; padding-left: 40px;
background: -webkit-linear-gradient(left, transparent, #fff 55%);
background: -o-linear-gradient(right, transparent, #fff 55%);
background: -moz-linear-gradient(right, transparent, #fff 55%);
background: linear-gradient(to right, transparent, #fff 55%);
}

效果如图:
dome3
适用范围:
该方法适用范围广,但文字未超出行的情况下也会出现省略号,可结合js优化该方法。

注:

  1. 将height设置为line-height的整数倍,防止超出的文字露出。
  2. 给p::after添加渐变背景可避免文字只显示一半。
  3. 由于ie6-7不显示content内容,所以要添加标签兼容ie6-7(如:<span>…<span/>);兼容ie8需要将::after替换成:after。

 

By柏小白

JS特效:类似QQ对话框上下部分可拖动代码

<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>例子</title>
<style>
ul,li{margin:0;padding:0;}
body{font:14px/1.5 Arial;color:#666;}
#box{position:relative;width:600px;height:400px;border:2px solid #000;margin:10px auto;overflow:hidden;}
#box ul{list-style-position:inside;margin:10px;}
#top{color:#FFF;overflow-x:hidden;overflow-y:auto;}
#bottom{color:#FFF;overflow-x:hidden;overflow-y:auto;}
#top{background:green;}
#bottom{background:blue;}
#line{position:absolute;bottom:100px;width:100%;height:4px;overflow:hidden;margin-top:-2px;background:red;cursor:n-resize;}
</style>
<script>
function $(id) {
    return document.getElementById(id)  
}
window.onload = function() {
    var oBox = $("box"), oTop = $("top"), oBottom = $("bottom"), oLine = $("line");
    oLine.onmousedown = function(e) {
        var disY = (e || event).clientY;
        oLine.top = oLine.offsetTop;
        document.onmousemove = function(e) {
            var iT = oLine.top + ((e || event).clientY - disY);
            var maxT = oBox.clientHeight - oLine.offsetHeight;
            oLine.style.margin = 0;
            iT < 0 && (iT = 0);
            iT > maxT && (iT = maxT);
            oLine.style.top = oTop.style.height = iT + "px";
            oBottom.style.height = oBox.clientHeight - iT + "px";
            return false
        };  
        document.onmouseup = function() {
            document.onmousemove = null;
            document.onmouseup = null;  
            oLine.releaseCapture && oLine.releaseCapture()
        };
        oLine.setCapture && oLine.setCapture();
        return false
    };
};
</script>
</head>
<body>
<center>上下拖动红条改变显示区域高度</center>
<div id="box">
    <div id="top" style="height:300px;">
        <ul>
            <li>西安一大厦发生爆炸7人遇难31人受伤</li>
            <li>意大利经济学家蒙蒂出任过渡政府总理</li>
            <li>天宫神八今晚分离后再对接 全程需半小时</li>
            <li>吉林骗子承包厨子施工铁路桥墩将爆破拆除</li>
            <li>胡锦涛:人民币升值无法解决美国问题</li>
            <li>红会否认通过民政部门索捐 称按工龄捐款属谣言</li>
            <li>昆明警车拒绝救助临产孕妇 市民称警察当时在玩游戏</li>
            <li>网帖称贫困县人社局80名员工公款赴港澳旅游</li>
            <li>云南师宗矿难副矿长承认用煤灰抹脸假装逃生</li>
            <li>中介操控卵子黑市 北大清华女生卖卵可得数万元</li>
            <li>云南一村庄户籍"不存在" 村民身份不明四处碰壁</li>
            <li>河北燕郊数千人陷传销 称发展下线可获利百万</li>
            <li>国际原子能机构出示图片证明伊朗研发核武器</li>
        </ul>
    </div>
    <div id="bottom" style="height:100px;">
        <ul>
            <li>京沪高铁因质量问题被召回动车拟16日恢复运营</li>
            <li>黑龙江穆棱河污染致数万人饮水难近10年</li>
            <li>湖南政府采购买高不买低 琴行老板揭招标内幕</li>
        </ul>
    </div>
    <div id="line"></div>
</div>
</body>
</html>

 





例子




上下拖动红条改变显示区域高度

  • 西安一大厦发生爆炸7人遇难31人受伤
  • 意大利经济学家蒙蒂出任过渡政府总理
  • 天宫神八今晚分离后再对接 全程需半小时
  • 吉林骗子承包厨子施工铁路桥墩将爆破拆除
  • 胡锦涛:人民币升值无法解决美国问题
  • 红会否认通过民政部门索捐 称按工龄捐款属谣言
  • 昆明警车拒绝救助临产孕妇 市民称警察当时在玩游戏
  • 网帖称贫困县人社局80名员工公款赴港澳旅游
  • 云南师宗矿难副矿长承认用煤灰抹脸假装逃生
  • 中介操控卵子黑市 北大清华女生卖卵可得数万元
  • 云南一村庄户籍”不存在” 村民身份不明四处碰壁
  • 河北燕郊数千人陷传销 称发展下线可获利百万
  • 国际原子能机构出示图片证明伊朗研发核武器
  • 京沪高铁因质量问题被召回动车拟16日恢复运营
  • 黑龙江穆棱河污染致数万人饮水难近10年
  • 湖南政府采购买高不买低 琴行老板揭招标内幕


By柏小白

手机网站前端开发布局技巧

在 此所说的移动平台前端开发是指针对高端智能手机(如Iphone、Android)做站点适配也就是WebApp,并非是针对普通手机开发Wap 2.0,所以在阅读本篇文章以前,你需要对webkit内核的浏览器有一定的了解,你需要对HTML5和CSS3有一定的了解。如果你已经对此有所了解, 那现在就开始往下阅读吧……

1、首先我们来看看webkit内核中的一些私有的meta标签,这些meta标签在开发webapp时起到非常重要的作用

<meta content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;” name=”viewport” />
<meta content=”yes” name=”apple-mobile-web-app-capable” />
<meta content=”black” name=”apple-mobile-web-app-status-bar-style” />
<meta content=”telephone=no” name=”format-detection” />

第一个meta标签表示:强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览;
第二个meta标签是iphone设备中的safari私有meta标签,它表示:允许全屏模式浏览;
第三个meta标签也是iphone的私有标签,它指定的iphone中safari顶端的状态条的样式;
第四个meta标签表示:告诉设备忽略将页面中的数字识别为电话号码

2、HTML5标签的使用
在开始编写webapp时,哥建议前端工程师使用HTML5,而放弃HTML4,因为HTML5可以实现一些HTML4中无法实现的丰富的WEB应 用程序 的体验,可以减少开发者很多的工作量,当然了你决定使用HTML5前,一定要对此非常熟悉,要知道HTML5的新标签的作用。比如定义一块内容或文章区域 可使用section标签,定义导航条或选项卡可以直接使用nav标签等等。

3、放弃CSS float属性
在项目开发过程中可以会遇到内容排列排列显示的布局(见下图),假如你遇见这样的视觉稿,哥建议你放弃float,可以直接使用display:block;

4、利用CSS3边框背景属性
看看这样一个按钮
这个按钮有圆角效果,有内发光效果还有高光效果,这样的按钮使用CSS3写是无法写出来的,当然圆角可以使用CSS3来写,但高光和内发光却无法使用CSS3编写,
这个时候你不妨使用-webkit-border-image来定义这个按钮的样式。
-webkit-border-image就个很复杂的样式属性,你一开始可以无法快速理解,建议你阅读一篇关于border-image的文章

5、块级化a标签
请保证将每条数据都放在一个a标签中,为何这样做?因为在触控手机上,为提升用户体验,尽可能的保证用户的可点击区域较大。

6、自适应布局模式
在编写CSS时,我不建议前端工程师把容器(不管是外层容器还是内层)的宽度定死。为达到适配各种手持设备,我建议前端工程师使用自适应布局模式 (支付宝 采用了自适应布局模式),因为这样做可以让你的页面在ipad、itouch、ipod、iphone、android、web safarik、chrome都能够正常的显示,你无需再次考虑设备的分辨率。

By柏小白

使用sessionStorage、localStorage存储数组与对象

有时候,我们需要将数据存储到sessionStorage和localStorage中,这样做的好处有:

1 缓存数据

2 减少对内存的占用

但是,storage只能存储字符串的数据,对于JS中常用的数组或对象却不能直接存储。

var obj = { name:'Jim' };
sessionStorage.obj = obj;
localStorage.obj = obj;
 
var arr = [1,2,3];
sessionStorage.obj = arr;
localStorage.obj = arr;

上面的写法都是不能成功的!但我们可以通过JSON对象提供的parse和stringify将其他数据类型转化成字符串,再存储到storage中就可以了。请看下面的代码。

var obj = { name:'Jim' };
var str = JSON.stringify(obj);
 
//存入
sessionStorage.obj = str;
//读取
str = sessionStorage.obj;
//重新转换为对象
obj = JSON.parse(str);

localStorage也一样,只是和sessionStorage的存储时间不一样。
需要注意的是,JS中的数组本质上也是对象类型,所以上面的代码对数组也是适用的。

By柏小白

js判断上传图片类型 以及图片文件大小,和高度宽度尺寸大小控制

js判断上传图片类型 以及图片文件大小,和高度宽度尺寸大小控制:

/* 
 * 判断图片类型 
 *  
 * @param ths  
 *          type="file"的javascript对象 
 * @return true-符合要求,false-不符合 
 */ 
function checkImgType(ths){  
    if (ths.value == "") {  
        alert("请上传图片");  
        return false;  
    } else {  
        if (!/\.(gif|jpg|jpeg|png|GIF|JPG|PNG)$/.test(ths.value)) {  
            alert("图片类型必须是.gif,jpeg,jpg,png中的一种");  
            ths.value = "";  
            return false;  
        }  
 
         else
        {
             var img=new Image(); 
             img.src=filepath;   
          while(true){ 
                 if(img.fileSize>0){ 
                 if(img.fileSize>10*1024){       
                     alert("图片不大于10M。"); 
                      return false; 
                      } 
                      break; 
                     } 
 
                  }
          }
    }  
    return true;  
}  
 
/* 
 * 判断图片大小 
 *  
 * @param ths  
 *          type="file"的javascript对象 
 * @param width 
 *          需要符合的宽  
 * @param height 
 *          需要符合的高 
 * @return true-符合要求,false-不符合 
 */ 
function checkImgPX(ths, width, height) {  
    var img = null;  
    img = document.createElement("img");  
    document.body.insertAdjacentElement("beforeEnd", img); // firefox不行  
    img.style.visibility = "hidden";   
    img.src = ths.value;  
    var imgwidth = img.offsetWidth;  
    var imgheight = img.offsetHeight;  
       
    alert(imgwidth + "," + imgheight);  
       
    if(imgwidth != width || imgheight != height) {  
        alert("图的尺寸应该是" + width + "x"+ height);  
        ths.value = "";  
        return false;  
    }  
    return true;  
}

 

By柏小白

jquery操作select(取值,设置选中)

每一次操作select的时候,总是要出来翻一下资料,不如自己总结一下,以后就翻这里了。

比如

<select class="selector"></select>

1、设置value为pxx的项选中

	
$(".selector").val("pxx");

2、设置text为pxx的项选中

$(".selector").find("option[text='pxx']").attr("selected",true);

这里有一个中括号的用法,中括号里的等号的前面是属性名称,不用加引号。很多时候,中括号的运用可以使得逻辑变得很简单。

3、获取当前选中项的value

$(".selector").val();

4、获取当前选中项的text

$(".selector").find("option:selected").text();

这里用到了冒号,掌握它的用法并举一反三也会让代码变得简洁。

很多时候用到select的级联,即第二个select的值随着第一个select选中的值变化。这在jquery中是非常简单的。

如:

By柏小白

超酷的固定菜单页面滚动效果

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>演示:超酷的页面滚动效果</title>
<style type="text/css">
.nav{width:50px; /*position:fixed; right:5px;*/ position:fixed; margin-left:920px; top:30%; z-index:1999; background:#f0f0f0; border: 1px solid #ccc;
  -webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;
  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);}
.nav li{height:50px; line-height:50px; border-bottom:1px solid #d3d3d3; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAEECAYAAABqa2e1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABZ0RVh0Q3JlYXRpb24gVGltZQAwNC8xMi8xM/3pQrMAAAAYdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3Jrc0+zH04AAA1QSURBVHic7Z1rbBzFAcd/M3e+5OwzTnxxnqSJMUmBJBZKUkhpWslNKG0JIRKqFEAW6gPUiqoBBaiEQK1UtUKofGgbIT60qQgtbYWgiEiBtiEqtMJQo0ohUGKS5oVKXrYT++yz77XTD7MX2/Gdfbs7S0bR/qVTovPuzvxu3jP/nRFKKS4HyUsdAVOKQGxTBGKbIhDbFIHYpgjENsVNPEQIMd0lXwA+BPor/dFEf88IyDTaAmySUp6bM2fOz8+cOXMaeAaYASggBtwTNJAws5YEvglsBM45jhPv7+9/ZOHChYuBAaDX/QwAc4IGJkwka4WslQDuAz4LDAF5NFi9lDLnOI4CCu619UqpJ9FQvhVG1koB9wMLgQw6wgooAVnHcSTgmA7UNEgzsA1oQqdEEQ1RVsn9GJdJkAXAg+4zyxCfmkwV9mXAI+gaKIs3CLV69errg0YgcGEXQlwPfAcYBUbwnnUSQFNTU9PL58+f/5vveAQBEUJ8EbgTGEZD+CnEApgJNDY2Nr42ODj4iq+4+AURQmwGvoqumXIEq4kEuoFsTKVSf89kMi94foAfECFEJ3AjulDnmFgz+VUZJtXQ0NA9NDT0rKebvYAIIeLAvcB1jDV0JifGBLrMpOrr6w9ks9lfK6VqSmm/WasR/evphwjxAwJkLSllsVQqPVPhT6PoH2xa+W1HMu6nrDp0FvOrOnTK9vl9gKl2JHaJ7798BlYRiBfF4/GRsMMIG0QsWrTo/UKh8JslS5Z0o6vXUBQ2SOyhhx56Fxg5fvz4W4Q4tA51zC6lVA888MAQuh82TEhjEQg5RaSUeUAJIcqNpfGR4YWwwnowIBzHmcnELkzg9qJqYKYmH5RS1WZClBDiQoutlEpTudAHatnDmkXxJBNxuGwaRL/jkWcJsQYCYkopT7OPfqvfAXQXOyzNRM8+1jxp5xdkFD1bYo2CFPbA87U1qOYUMVJr2aDLptaKQGxTBGKbIhDbFIHYpgjENkUgtikCsU0RiG2KQGxTBGKbAq+PTDPvmwJa3P+fA85ffIGpWRzTCz31wFpgNXCt+/zymkg59T8E3gPeBgZNBWzC5gTadvE14CvoCOfQnq0SY+sjwv1bnXu9iMVib5VKpReVUoFnLU2AzEHb/5rRS2wFNITDZJ9KGSaGBkpKKUcTicQvR0ZGTgSKR0C/1jLge24EyxC1PlCgs15SSjkzlUr9dmBgoNtvXHzXWkKIFuC76F++qlMolUp9kkqlPqnwiLJldthxnOGhoaF72tralvuNjy8Q1+50vxuZavY/uWXLlpczmcxLmUzmT3fcccfvq4RXAkYcxxk5ceLEfR0dHbN8xcnnQs8taPfcEFUWfJLJ5GA2m90FDAghCgBSym2O48yu8lgJNLS0tPznzJkzO/HoA/OcIkKIemADUxsxRS6XawaKZQgAx3EaqO5+cIDRs2fPrtq8efNSr/Hyk7XWufdNaYl1HCfR3Ny8Fd221KN98tVSo6wikO/u7v4SHpeyPWctIcSD6NY6P82ldUADGgL0CtcwY574qvfF43EKhcLP3OtrkqcUEUJItOe9loXQUmtr676lS5fuWbp06Z7W1tZ9td5XLBZnPv7443O9xM1rF6W83FaLFSN25MiRtxi31iiEuLGGex2g2NXVNR84XmNYnkEaqdxiV322ECJ70XfTZS0Ap7+/vx5dTmoC8VrYBd5a7lq+m0o1x88rSE3WVRO64oorPHUkvYL0YtawXFU33HCDp7A8gSilisD/vEbKq+Lx+MiTTz55Dg82ET8NYo/P+2qVaG5uPoYu5KGCvEOITjggduutt77L9A3uBHkGUUoNxmKxsByjIp1OH965c+cZPJp2fGWRUqm0V0pp3MsrpSzee++9/2RsqFyzfI8Q6+vrr8zlct9yX8erpBnALMbeasihZ1GqvgzQ0dHx6r59+w6713nygwUa6jY3N7cPDAxsqQJTnmgo92JL6Fa9UvlSK1eu7Dpw4MC/0TMrnspHOTDf6u/vf6+tre138Xi8Un520L9+1v1UfH1JSlnasGHDHheiPGT2rMDV6KFDh46sX7/+mZaWlg/w1liKdDp9+NFHH31+7969R9Ap4duVZ2peC6WUvPPOOxe9/fbbq0+ePHlVLpdrqnR9PB4fnj9//n9vvvnmg27tVE61QB5JYyBlKaViwIyHH3543tmzZ+t7enpm5XK5eHt7e286nS489dRT/YxlO8+1U9V4mAYZLxdKoAu8wH13VwhRGndNoPAvxCOyAlqmCMQ2RSC2KQKxTRGIbYpAbFMEYpsiENsUgdimCMQ2RSC2ybQVsAH4IbAY70t0nl80Hi+TVsAGYDt6/zk/a42eXzQeL1MgZYjZ6D2FioDctGnTy0qpKReEDh06NPejjz5aFzQCJkDGQwwzNgUa37179wn0K+NVtWDBgmXoLUIDKRCIEKIaBLjrIuNtTlXkcCk3QZoGAmpfYzSyFhmk+l2KdpZWgvjUFQSkvDRwySEgeGF3qFI7lUqlT7WxNVFr1VQ7hS0TILXWTqHKRPKHtmeWF102ncYIxDZFILYpArFNEYhtikBsUwRim0x049XGjRuXAfP93AssMhAHIyCl119//S70a6te5aB9jMMEnEkxAVJEGyv9ZlMjJ2AEddDVoadITcrXlGlkBbRNEYhtikBsUwRimyIQ2xSB2KYIxDZFILYpArFNEYhtikBsU2AQIcRUny8LIXa5/1a8xpTCTpFNQL+U8jal1MwwAwoT5Dr03G7GcRyno6Mj8EmtUylMkGvQOwqUgEJPT0+bUqourMDCBLmasTnd0rlz55bgb6K7JoUF0oJeZrgAMjo6OmfHjh2m54kvKCyQa5m4UYUDFJ9++unrp7PP+lVYIIuZvFRQ7O3tXcC4Q1NNKiyQVUwGcQYGBpYQ0ol/YYBcx8RdZcty8vl8w0033XRdCGHWvj4ihJiL3qLwGqr73ss7aVbbpGUGevu3JNWddwI4COxQStW8K6CXZF4CXMnUBn6FzlLVLLQFNOQwU4NcuXbt2hVA9xRhTZAXkA+klIcdx2mu9eEV5DD9TjQimUye2r59+0lq33zP89KbaG1tveXYsWOfJ5wt3MTy5cvf6enp+Rc6VQdqDcdrYVdHjx59bc2aNbuSyaTvQxgrKZlM9nV2dr7gQgyjd3Sq+ccKshgab21t3WggdS5OhSF82NSDVL/FoKlTJRV8ee2NbLmjlIoLIX6Et4X/mFLqFwRIhfEy0iAKIWahzQNeFN+6desiAqTCeJlq2df6uEe8+eabKzHUZTEFciXetzws9fX1XYOhTqQJkAZgJd6NMaV8Pl9/++23txmIgxGQtejWelKKJJPJvscee+y5dDp9lMldEgcodHd3r8LEi50Gaq27gRVM7HqIefPmfXjq1Km96IKcaWlp+Xpvb+9aJrY5dYlEwsnlck/gYdvoSjKRIhePPcTy5cvfcSFGhRDnhRCl3t7e3YsXL97rHqxdVimfz9evWrXqc0EjEQhECHHx2EO0t7e/UW7ghBAT9gf++OOP/7FixYo/joNxgPzp06fbCFjog6bIYtx95aSU+c7Ozhf279//HjAkhKi4ReiBAweObNq06VfjegOlbDZ7Bd7boYlSSvn+AHOklD9OpVL3dXZ2rlRKpZVSNRVcpZSYN2/eZuCnV1999e1KqaYgcTHhoIuh9ywt4u/lygb0iHEYPbr0pcgKaJsiENsUgdimCMQ2RSC2KQKxTRGIbYpAbFMEYpsiENsUgdimywYkzJOOn2VsTlgCLwK7L77I1HRUmCkygHZJ9AL9V111VUIplQwrsFCcOq5GGTsLsU4IEeYhXpdPGYlAbFMEYpsuG5Cge5nOBSqdfzvppNfBwcFZy5Ytu5aLjGdug3rUi+2vYlwCns/eADzBZId1Hr1dbjnSMfSJx0kmbhsiEonE67lc7iXctUjfcQnaRUgmk0vy+fy3HccZv5hZPibzwmovGkAyZhwQc+fO/eD06dOvopfcLl2KgM4a6XT6mr6+vrvw4EdJJpP92Wz2eXQPIPAxt0YKe19f38HGxsbXqHHzyWQy2b9z584/M+bVCixjtVYmk3mrqanpTaaBkVIWtm3btmfr1q0ZDO5/avzQulQq9Y2hoaGVVCi4Usr83Xff/cquXbtOAueFECVrDq2rNB6pq6v7fqFQmHPR13LdunV/6erqOggMCCGKYPl4pFAo7JwxY8Z4w6Zob29/o6urqwdt7zC+2XFYLXs2kUj8QUpZQFueDu7fv38/GqLqKa5BFOrBjrNnz/5MIpFYf+rUqb+iLU+TaihrykgNiqN36Q/1SHRfIG4f60YApdSkCQUfz/sy2lxzVCn1vp9n+C0jLeiXJW9D95+C6nrg1lmzZrXh07flt/froDuFEmioZjKrRW6OyAND6XRa4uFVi/EK0o0vAAghfkIAG5+7KfggPiI/XkGngwpoS3iQHf0c3NMxgkTExAb4ptqFQJ5GvyDH58+f/9yaNWuMzRwqpcSKFSt8dyKDtCOCcGYqy4MyT4o8jbYpArFNEYhtikBsUwRimyIQ2/R/UXHpI1TPp5AAAAAASUVORK5CYII=) no-repeat; text-align:center; cursor:pointer}
.nav li:hover{background-color:#f9f9f9; text-decoration:none}
.nav li:last-child{border-bottom:none}
.nav li.cur{background-color:#ffc}
.nav li.pro{background-position:0 0}
.nav li.news{background-position:0 -55px}
.nav li.ser{background-position:0 -105px}
.nav li.con{background-position:0 -155px}
.nav li.job{background-position:0 -207px}
.box{height:500px; margin: 0 10px}
.box h3{height:32px; line-height:32px; padding-left:20px; font-size:14px}
.box p{line-height:30px; margin:20px; text-align:center; font-size:28px}
.box p span{margin:10px}

</style>
<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
<!-- <script type="text/javascript" src="jquery.easing.min.js"></script> -->
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>

<script type="text/javascript">
$(function(){
    navpos();
    
    var pro_top = $("#pro").offset().top;
    var news_top = $("#news").offset().top;
    var ser_top = $("#ser").offset().top;
    var con_top = $("#con").offset().top;
    var job_top = $("#job").offset().top;
    //alert(tops);
    $(window).scroll(function(){
        var scroH = $(this).scrollTop();
        if(scroH>=job_top){
            set_cur(".job");
        }else if(scroH>=con_top){
            set_cur(".con");
        }else if(scroH>=ser_top){
            set_cur(".ser");
        }else if(scroH>=news_top){
            set_cur(".news");
        }else if(scroH>=pro_top){
            set_cur(".pro");
        }
    });
    
    $(".nav li").click(function() {
        var el = $(this).attr('class');
        $('html, body').animate({
            scrollTop: $("#"+el).offset().top
            },{
            easing: 'easeOutSine',
            duration: 300,
            complete:function(){
            }
        });
    });
});
$(window).resize(function(){
  navpos();
});
function navpos(){
    var page_w = $(document).width();
    var offset = $("#main").offset().left;
    var main_w = $("#main").outerWidth();
    var right = page_w-offset-main_w-50;
    //alert(right);
    if(right>10){
        $(".nav").css('right',right-10);
    }else{
        $(".nav").css('right',10);
    }
}
function set_cur(n){
    if($(".nav li").hasClass("cur")){
        $(".nav li").removeClass("cur");
    }
    $(".nav li"+n).addClass("cur");
}
</script>
</head>
 
<body>
 
<div id="main">
  <ul class="nav">
    <li class="pro"></li>
    <li class="news"></li>
    <li class="ser"></li>
    <li class="con"></li>
    <li class="job"></li>
</ul>
     <div id="pro" class="box">
        <h3>产品展示</h3>
        
        <br/>
       
     </div>
     <div id="news" class="box">
        <h3>新闻中心</h3>
     </div>
     <div id="ser" class="box">
        <h3>服务支持</h3>
       
     </div>
     <div id="con" class="box">
        <h3>联系我们</h3>
     </div>
     <div id="job" class="box" style="height:680px">
        <h3>人才招聘</h3>
     </div>
</div>
</body>
</html>

 





演示:超酷的页面滚动效果




产品展示

新闻中心

服务支持

联系我们

人才招聘


By柏小白

javaScript & jquery完美判断图片是否加载完毕

好久没写东西了,正好最近因为工作需要,写了一个瀑布流异步加载的程序。

今天就不谈瀑布流,来谈一下关于load的问题。

————————————————————-

众所周知,常见瀑布流当鼠标滚动到浏览器底部的时候,就会发起一个ajax的请求。在服务端生成item列表后,通过 js append到相应的div里边。

看起来很简单的样子,关键问题就出在图片的加载问题上,图片一般都放在服务器上,通过http下载到客户端。

例如我的图片地址:

http://xxx.xxx.com/sc/item/cover/9-4352-c400.jpg

而图片下载到本地是需要一定时间的(网速快的路过)。当图片还没有下载完的时候,使用js获取到元素的宽高将会是0。

——————————————————————-

有的同学说了我使用jquery的ready不就好了。如下:

$(document).ready(function(){
  // 在这里写你的代码...
});

如果这么简单就好了,我这里就说下ready与window.onload的区别。

jquery的ready只是dom的结构加载完毕,便视为加载完成。(缺点是图片没有加载完毕,宽高为0,程序出错)

js的window.onload是指dom的生成和资源的加载,比如flash、图片完全加载出来后才执行onload。(缺点就是当某一张图片很大的时候,岂不阻止了其它js的正常执行)

————————————————————————————-

知道了他们的区别后,我们再来谈谈如何避免错误和选择性使用。

如果你进行了百度,很多人会告诉你。

这样:

$('img').load(function(){
  // 加载完成    
});

好像很强大的样子,其实不然,他的缺点是每加载一张图片,回调函数就执行一次。好吧太烦了,我只想全部加载完走一次就可以了。当然可以,你可以进行修改如下:

va imgNum=$('img').length;
$('img').load(function(){
    if(!--imgNum){
        // 加载完成
    }
});

这样总可以了吧,我加载一张,就用图片总数去减一,减到0我就加载完毕。看起来很完美,前提是你没遇到IE。

IE的图片总是从缓存文件里去拿,这就造成load方法根本就不执行,只有是新图片才会走load。

服了吧?继续往下看。

—————————————————————

或者是这样:

document.getElementById('img').onload=function(){
        // 加载完成 
};

看我原生代码一统天下,实际上效果甚微,一次只能处理一个你准备写多少个document,有人说我可以用循环去绑定,经过我测试貌似根本没效果。

还是一笑而过吧。看看我的最终解决方案(兼容:谷歌&火狐&IE)

————————————————————-

利用图片没有加载完成的时候,宽高为0。我们很容易判断图片的一个加载情况。如下:

var t_img; // 定时器
var isLoad = true; // 控制变量
 
// 判断图片加载状况,加载完成后回调
isImgLoad(function(){
    // 加载完成
});
 
// 判断图片加载的函数
function isImgLoad(callback){
    // 注意我的图片类名都是cover,因为我只需要处理cover。其它图片可以不管。
    // 查找所有封面图,迭代处理
    $('.cover').each(function(){
        // 找到为0就将isLoad设为false,并退出each
        if(this.height === 0){
            isLoad = false;
            return false;
        }
    });
    // 为true,没有发现为0的。加载完毕
    if(isLoad){
        clearTimeout(t_img); // 清除定时器
        // 回调函数
        callback();
    // 为false,因为找到了没有加载完成的图,将调用定时器递归
    }else{
        isLoad = true;
        t_img = setTimeout(function(){
            isImgLoad(callback); // 递归扫描
        },500); // 我这里设置的是500毫秒就扫描一次,可以自己调整
    }
}

 

By柏小白

更换网页背景的jquery代码(写入cookie)

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8" />
    <title>更换网页背景的jquery代码(写入cookie)</title>

<style type="text/css">
    body,p,ul{margin:0;padding:0;}
    ul{float:right;height:40px;margin-top:20px;margin-right:20px;}
    ul li{list-style-type:none;float:left;width:20px;height:20px;margin-left:10px;cursor:pointer;}
    .skin{height:40px;position:fixed;background:#fff;border-bottom:solid 1px #cccc;top:0;left:0;width:100%;}
    .red{background:#F06;}/*红色*/
    .black{background:#000;}/*黑色*/
    .blue{background:#09F;}/*蓝色*/
    .green{background:#093;}/*绿色*/
</style>
<script type="text/javascript" src="http://ajax.useso.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver=3.4.2"></script>
<script type="text/javascript">
    $(document).ready(function(){
            //为了安全 google chrome 等浏览器是禁止本地文件写Cookie的即file:///F:/Lord%20community/lrtk/Untitled-2.html这样的以file开头的是不能写本地文件的
            var cookieClass = getCookie('class');//读取需要缓存的对象。
            $("body").attr("class",cookieClass);//
            $(".skin_list li").each(function(){
                    $(this).click(function(){                          
                            var className=$(this).attr("class");//保存当前选择的类名
                            $("body").attr("class",className,30);//把选中的类名给body
                            function SetCookie(name,value,day)//两个参数,一个是cookie的名子,一个是值
                            {
                                var exp  = new Date();    //new Date("December 31, 9998");
                                exp.setTime(exp.getTime() + day*24*60*60*1000);
                                document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
                            }
                            SetCookie("class",className,30);
                    })
                });
            });
            function getCookie(name)//取cookies函数       
            {
                var nameEQ = name + "=";
                var ca = document.cookie.split(';');
                for(var i=0;i < ca.length;i++) {
                    var c = ca[i];
                    while (c.charAt(0)==' ') c = c.substring(1,c.length);
                    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
                }
                return null;
            }
</script>
</head>
                                
<body>
<div class="skin"><ul class="skin_list"><li style="width:100px;text-align:right;">更换背景:</li></li><li class="red"></li><li class="black"></li><li class="blue"></li><li class="green"></li></ul></div>
 
</body>
</html>

 





更换网页背景的jquery代码(写入cookie)



  • 更换背景:


By柏小白

jquery批量链接设置新窗口打开

//方法一
$("a[href^='http://']").click(function(){
 this.target = "_blank";
});
//方法二
$(function(){
  $("a[href^='http://']").attr({'target':'_blank'})
})

 

By柏小白

使用jQuery判断元素是否存在

使用传统javascript方法,如下:

if(document.getElementById('div')) {     
    // 找到到对应元素 
} else {     
    // 没有找到找到到对应元素 
}

使用jQuery则比较简单,只需判断此元素的长度是否为0,如果为0则此元素不存在,代码如下:

if ($("#div").length > 0){ 
    // 找到对应id=div的元素,然后执行此块代码 
}

甚至能找到组合元素,如下,我们找一个id定义为div的元素里面是否包含img,代码如下:

if ($("#div img").length > 0){ 
    // 找到对应id=div并且包含img的元素,然后执行此块代码 
}

 

By柏小白

判断safari_判断IE_判断firefox_判断Opera—JS判断浏览器

JS

//----------------------------- 判断浏览器 -------------------------  
function myBrowser(){  
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串  
var isOpera = userAgent.indexOf("Opera") > -1; //判断是否Opera  
var isMaxthon = userAgent.indexOf("Maxthon") > -1 ; //判断是否傲游3.0  
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera ; //判断是否IE   
var isFF = userAgent.indexOf("Firefox") > -1 ; //判断是否Firefox  
var isSafari = userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") < 1 ; //判断是否Safari  
var isChrome = userAgent.indexOf("Chrome") > -1 ; //判断是否Chrome  
  
if(isIE){   
   var IE5 = IE55 = IE6 = IE7 = IE8 = false;  
   var reIE = new RegExp("MSIE (+);");  
   reIE.test(userAgent);  
   var fIEVersion = parseFloat(RegExp["$1"]);  
  
   IE55 = fIEVersion == 5.5 ;  
   IE6 = fIEVersion == 6.0 ;  
   IE7 = fIEVersion == 7.0 ;  
   IE8 = fIEVersion == 8.0 ;  
  
   if(IE55){ return "IE55"; }  
   if(IE6){ return "IE6"; }  
   if(IE7){ return "IE7"; }  
   if(IE8){ return "IE8"; }  
}  
  
if(isFF){ return "FF"; }  
if(isOpera){ return "Opera"; }  
if(isMaxthon){ return "Maxthon"; }  
if(isSafari){ return "Safari"; }  
if(isChrome){ return "Chrome"; }  
  
} //myBrowser() end  
  
  
window.onload=function(){  
  
document.getElementById("ua").innerHTML=navigator.userAgent;  
  
if(myBrowser()=="FF"){alert("我是 Firefox");}  
if(myBrowser()=="Maxthon"){alert("我是傲游(webkit核心)");}  
if(myBrowser()=="Opera"){alert("我是 Opera");}  
if(myBrowser()=="Safari"){alert("我是 Safari");}  
if(myBrowser()=="Chrome"){alert("我是 Chrome");}  
if(myBrowser().indexOf("IE")>-1){alert("我是 IE");}   
if(myBrowser()=="IE55"){alert("我是 IE5.5");}  
if(myBrowser()=="IE6"){alert("我是 IE6");}  
if(myBrowser()=="IE7"){alert("我是 IE7");}  
if(myBrowser()=="IE8"){alert("我是 IE8");}  
}

Jquery判断浏览器版本:

$.browser.msie; 
if ($.browser.webkit) { alert( "this is webkit!" ); }
if ($.browser.safari) { alert( "this is safari" ); }
var ua = $.browser; if ( ua.mozilla && ua.version.slice(0,3) == "1.9" ) { alert( "Do stuff for firefox 3" ); }
if ( $.browser.msie ) { $("#div ul li").css( "display","inline" ); } else { $("#div ul li").css( "display","inline-table" ); }

 

By柏小白

图片垂直居中的使用技巧

当然出题并不是随意,而是有其现实的原因,垂直居中是 淘宝 工作中最常遇到的一个问题,很有代表性。

题目的难点在于两点:
1.垂直居中;
2.图片是个置换元素,有些特殊的特性。

至于如何解决,下面是一个权衡的相对结构干净,CSS简单的解决方法:

.box {
/*非IE的主流浏览器识别的垂直居中的方法*/
display: table-cell;
vertical-align:middle;
/*设置水平居中*/
text-align:center;
/* 针对IE的Hack */
*display: block;
*font-size: 175px;/*约为高度的0.873,200*0.873 约为175*/
*font-family:Arial;/*防止非utf-8引起的hack失效问题,如gbk编码*/
width:200px;
height:200px;
border: 1px solid #eee;}
.box img {
/*设置图片垂直居中*/
vertical-align:middle;}<div class="box">
<img src="http://pics.taobao.com/bao/album/promotion/taoscars_180x95_071112_sr.jpg" /></div>

 

By柏小白

支持 Firefox、Chrome 等主流浏览器的全站变灰 CSS 代码

cccc

 

html{
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: grayscale(100%);
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
}

 

 

 

By柏小白

如何让未知尺寸的图片在已知宽高的容器内水平垂直居中?

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>已知宽高的容器内水平垂直居中?</title>
    <style>

.test{display:table-cell;*display:block;*position:relative;width:200px;height:400px;text-align:center;vertical-align:middle; background:#58d0fe;}
.test p{*position:absolute;*top:50%;*left:50%;margin:0;}
.test p img{*position:relative;*top:-50%;*left:-50%;vertical-align:middle;}

    </style>
</head>
<body>
    <div class="test">
        <p>
            
            <img src="" alt="">
        </p>

    </div>
</body>
</html>

 





已知宽高的容器内水平垂直居中?


柏小白家臭小子



By柏小白

纯CSS3实现的Android Logo

 

html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>纯CSS3实现的Android Logo</title>
   
</head>
<body>
    <div class="android">
        <div class="head">
            <div class="l_ant"></div>
            <div class="r_ant"></div>
            <div class="l_eye"></div>
            <div class="r_eye"></div>
        </div>
        <div class="body">
            <div class="l_arm"></div>
            <div class="r_arm"></div>
            <div class="l_leg"></div>
            <div class="r_leg"></div>
        </div>
    <

css

  div {margin: o; padding: 0;}
            div div {background: #A4CA39; position: relative;}
             
            .android{
                height: 404px; width: 334px;
                margin: 100px auto;
                
            }
            .head{
                width: 220px; height: 100px;
                top: 32px;
                
                border-radius: 110px 110px 0 0;
                -moz-border-radius: 110px 110px 0 0;
                -webkit-border-radius: 110px 110px 0 0;
                
                -webkit-transition: all 0.1s ease-in;
            }
            .l_eye, .r_eye {
                background: #fff;
                width: 20px; height: 20px;
                position: absolute; top: 42px;
                
                border-radius: 10px;
                -moz-border-radius: 10px;
                -webkit-border-radius: 10px;
            }
            .l_eye {left: 50px;}
            .r_eye {right: 50px;}
             
            .l_ant, .r_ant{
                width: 6px; height: 50px;
                position: absolute; top: -34px;
                border-radius: 3px;
                -webkit-border-radius: 3px;
                -moz-border-radius: 3px;
            }
            .l_ant {
                left: 50px;
                transform: rotate(-30deg);
                -webkit-transform: rotate(-30deg);
                -moz-transform: rotate(-30deg);
                -ms-transform:rotate(-30deg);
            }
            .r_ant {
                right: 50px;
                transform: rotate(30deg);
                -webkit-transform: rotate(30deg);
                -moz-transform: rotate(30deg);
                -ms-transform:rotate(30deg);
            }
             
            .body{
                width: 220px; height: 184px;
                top: 40px;
                
                border-radius: 0 0 25px 25px;
                -webkit-border-radius: 0 0 25px 25px;
                -moz-border-radius: 0 0 25px 25px;
            }
             
            .l_arm, .r_arm, .l_leg, .r_leg {
                width: 50px; position: absolute;
                -webkit-transition: all 0.1s ease-in;
                -moz-transition:all 0.1s ease-in;
                cursor:pointer;
            }
            .l_arm, .r_arm {
                height: 150px;
                border-radius: 25px;
                -moz-border-radius: 25px;
                -webkit-border-radius: 25px;
            }
            .l_leg, .r_leg {
                height: 80px; top: 182px;
                border-radius: 0 0 25px 25px;
                -moz-border-radius: 0 0 25px 25px;
                -webkit-border-radius: 0 0 25px 25px;
            }
            .l_arm {left: -58px;}
            .r_arm {right: -58px;}
            .l_leg {left: 45px;}
            .r_leg {right: 45px;}
             
            .head:hover {
                -webkit-transform: rotate(-5deg) translate(-4px, -8px);
                -transform: rotate(-5deg) translate(-4px, -8px);
                -moz-transform: rotate(-5deg) translate(-4px, -8px);
                -ms-transform: rotate(-5deg) translate(-4px, -8px);
            }
            .l_arm:hover{
                -webkit-transform: rotate(15deg) translate(-14px, 0);
                -transform: rotate(15deg) translate(-14px, 0);
                -moz-transform: rotate(15deg) translate(-14px, 0);
                -ms-transform:rotate(15deg) translate(-14px,0);
            }
            .r_arm:hover{
                -webkit-transform: rotate(-30deg) translate(30px, 0);
                -transform: rotate(-30deg) translate(30px, 0);
                -moz-transform: rotate(-30deg) translate(30px, 0);
                -ms-transform:rotate(-30deg) translate(30px,0);
            }

 





纯CSS3实现的Android Logo



By柏小白

如何去掉链接虚线框

链接的虚线框影响整体风格,我们在工作经常会将它去掉,而采用图片高亮的方式来显示焦点状态。然而去掉虚线框在两种浏览器中却分别对待,这种技巧经常用到,作个记录,以备不时之需。

当一个链接得到焦点时,默认会有个虚线框。如图:

在 Firefox 里可以用 -moz-outline:none; 或者 outline:none; 来将其去掉。所以我们可以这样写:

input,textarea {
  outline:none;
}

 

顺便提一下,如果你用过 Safari 和 Chrome 可能会发现,当输入框得到焦点时边框会出现阴影效果。

如果想去掉阴影效果也可以用 outline 属性。

input,textarea {
  outline:none;
}

 

言归正传,刚刚说的是 Firefox ,现在说说 IE。首先比较遗憾,还没有找到通过 CSS 去掉 IE 链接虚线框比较好的解决办法。所以只能用一个替代的办法,就是 a 标签的 hidefocus 属性(这个属性是 IE 独有的)。

	
<a href="#" hidefocus="true">链接</a>

 

注意:JS 脚本对应的属性名是:hideFocus。对应的 JS 代码应该是:

xxx.hideFocus ="true";

Read More

By柏小白

CSS解决Chrome浏览器限制使用12px以下字体的问题

在谷歌的浏览器Chrome中有一个奇怪的问题,页面上小于12px的字都以12px显示。

在其它浏览器中都没有此问题,不知道是谷歌真没发现这个bug,还是谷歌为了考虑到chrome的用户体验,故意把字号限制到最小12px ?

我看了那么多网站,应用10px或其它小于12px字号的站还真不多见,大多出现在全英文的网站上,因为10px的字母看着也算清晰,即使清晰,我也觉得没必要搞个10px的字,那么地小,节约页面空间?布局美观?还是为了排版需要?这也太狭义了吧。。。

然而,事实上小于12px的汉字看的眼睛胀痛,笔画多点的根本不能识别,那就更不应该应用10px的字了。能清晰地观看到页面中的信息,应该是用户对网站最基本的要求了。

不管是bug也好,还是功能也罢,即然有人需要在Chrome上显示10px的字,那就满足他们的需求。

要解决chrome中最小字体为12px的问题,可以使用Webkit 的内核 -webkit-text-size-adjust 的私有属性来解决,比如下面的代码就可以成功的解决,简单有效,通过- webkit-text-size-adjust即可实现字体大小不随终端设备或浏览器影响。

css样式定义如下:

	
.chrome10px { -webkit-text-size-adjust:none; font-size:10px; }

如果还不能满足你在来瞧瞧:“针对谷歌浏览器内核,加webkit前缀,用transform:scale()这个属性进行缩放!”

.chrome10px {font-size:10px;-webkit-transform:scale(0.8);display:block; }

 

By柏小白

给input的placeholder设置颜色

html5提供了placeholder让前端开发人员省了不少事,但是如果你要设置的颜色就有点蛋疼了,css没直接提供这样的选择器,毕竟placeholder是后来者,那怎么办呢?能不能修改?答案是可以了,css没有提供,我们可爱的现代浏览器有提供,嘿嘿~~~收藏吧童鞋们~~~

3
4
5
6
7
8
9
10
11
12
::-webkit-input-placeholder { /* WebKit browsers */
    color:    #999;
}
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
    color:    #999;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
    color:    #999;
}
:-ms-input-placeholder { /* Internet Explorer 10+ */
    color:    #999;
}

 

By柏小白

修改微信朋友圈分享链接后的小小图标

方法/步骤
在网页的头部加上以下代码,图片路径自行修改。

<head>
<div id='wx_pic' style='margin:0 auto;display:none;'>
<img src='/image/data/pic300.jpg' />
</div>
</head>

制作像素是 300*300px的图片,命名为pic300.jpg。将图片放到步骤一对应的路径下。

保存好文件后,就可以分享到朋友圈了。此时分享的网页链接就会有小图片显示了

By柏小白

jQuery实现购物车多物品数量的加减小计+总价计算

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>jQuery实现购物车多物品数量的加减小计+总价计算</title>
    <script src="http://code.jquery.com/jquery-1.7.min.js"></script>
    <script>
$.each($('input[class*=text_box]'),function(i,t){
    subtotal($(t));
})
$(function(){
$(".add").click(function(){
    var t=$(this).parent().find('input[class*=text_box]');
    t.val(parseInt(t.val())+1);
    if(isNaN(t.val())){
        t.val(1);
    }
    subtotal(t)
});
$(".min").click(function(){ 
    var t=$(this).parent().find('input[class*=text_box]'); 
    t.val(parseInt(t.val())-1);
    if(parseInt(t.val())<=0 || isNaN(t.val())){ 
        t.val(1);
    }
    subtotal(t);
});
$('input[class*=text_box]').keyup(function(){
    var t=$(this);
    t.val(parseInt(t.val()));
    if (isNaN(t.val()) || parseInt(t.val()) <= 0) {
        t.val(1);
    }
    if (t.val(parseInt(t.val())) != t.val()) {
        t.val(parseInt(t.val()));
    }
    subtotal(t);
});
function subtotal(sum){
    var subtotal=0;
    subtotal=parseFloat(sum.siblings('.price').text())*parseInt(sum.val());
    sum.siblings('.subtotal').html(subtotal.toFixed(2));
    setTotal();
}
function setTotal(){
    var s=0; 
    $("#tab td").each(function(){ 
        s+=parseInt($(this).find('input[class*=text_box]').val())*parseFloat($(this).find('span[class*=price]').text()); 
    });
    $("#total").html(s.toFixed(2));
    } 
    setTotal();
});
</script></head>
<body>
    <table id="tab">
        <tr>
            <td>
                <span>单价:</span>
                <span class="price">1.50</span>
                <input class="min" name="" type="button" value="-" />
                <input class="text_box" name="" type="text" value="1" />
                <input class="add" name="" type="button" value="+" />
                <span class="subtotal">1.50</span>
            </td>
        </tr>
        <tr>
            <td>
                <span>单价:</span>
                <span class="price">3.95</span>
                <input class="min" name="" type="button" value="-" />
                <input class="text_box" name="" type="text" value="1" />
                <input class="add" name="" type="button" value="+" />
                <span class="subtotal">3.95</span>
            </td>
        </tr>
    </table>

    <p>
        总价:
        <label id="total"></label>
    </p>
</body>
</html>

 





jQuery实现购物车多物品数量的加减小计+总价计算


单价:
1.50



1.50
单价:
3.95



3.95

总价:


By柏小白

jquery全屏banner自动轮播切换

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jquery全屏banner自动轮播切换</title>
<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
<script type="text/javascript">
function banner(){  
    var d=0;
    var speed=5000;
    var count=1;
    var time;
    var fouse=$('#banner .d1');
    var dot=$('#banner_id li');
    fouse.hide();
    fouse.eq(0).fadeIn('slow');
    if(fouse.length>0){
        dot.eq(0).addClass('nuw');
        function Carousel(){
            var c=d+1;
            if(c>fouse.length-1){
                c=0;
            }
            fouse.eq(d).css('z-index','2');
            fouse.eq(c).css('z-index','1');
            fouse.eq(c).show();
            fouse.eq(d).fadeOut('slow');
            dot.removeClass('nuw');
            dot.eq(c).addClass('nuw');
            d=c;
        }
        time=setInterval(Carousel,speed);
        dot.click(function(){
            var e=dot.index(this);
            if(e!=d&&count==1){
                count=0;
                fouse.eq(d).css('z-index','2');
                fouse.eq(e).css('z-index','1');
                fouse.eq(e).show();
                fouse.eq(d).fadeOut('slow',function(){count=1});
                dot.removeClass('nuw');
                dot.eq(e).addClass('nuw');
                d=e;
            }
        });
        $('#banner_id').hover(function(){
            clearInterval(time);
        },function(){
            time=setInterval(Carousel,speed);
        });
    }
    else{
        $('#banner').hide();
    }
}
</script>
</head>
<body>
<style type="text/css">
*{margin:0;padding:0;list-style-type:none;}
a,img{border:0;}
body{font:12px/180% Arial, Helvetica, sans-serif, "新宋体";}
/* banner */
.banner{height:400px;overflow:hidden;}
.banner .d1{width:100%;height:392px;display:block;position:absolute;left:0px;top:0px;}
.banner .d2{width:100%;height:30px;clear:both;position:absolute;z-index:100;left:0px;top:360px;}
.banner .d2 ul{float:left;position:absolute;left:50%;top:0;margin:0 0 0 -96px;display:inline;}
.banner .d2 li{width:17px;height:15px;overflow:hidden;cursor:pointer;background:url(images/img1.png) white no-repeat center;float:left;margin:0 3px;display:inline;}
.banner .d2 li.nuw{background:url(images/img1_1.png) white no-repeat center;}
</style>
<div class="banner" id="banner" >
    <a href="#" class="d1" style="background:url(images/banner1.jpg) red center no-repeat;"></a> 
    <a href="#" class="d1" style="background:url(images/banner2.jpg) yellow center no-repeat;"></a>
    <a href="#" class="d1" style="background:url(images/banner3.jpg) #03A9F4 center no-repeat;"></a>
    <a href="#" class="d1" style="background:url(images/banner4.jpg) #795548 no-repeat;"></a>
    <a href="#" class="d1" style="background:url(images/banner5.jpg) #CDDC39 no-repeat;"></a>
    <div class="d2" id="banner_id">
        <ul>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
</div>
<script type="text/javascript">banner()</script>
<div style="text-align:center;clear:both">
<p>适用浏览器:IE6+、360、FireFox、Chrome、Safari、Opera、傲游、搜狗、世界之窗.图片自行配图</p>
</div>
</body>
</html>

 





jquery全屏banner自动轮播切换




By柏小白

Jquery 实现表单验证,所有验证通过方可提交

<html>
    <head>
        <meta charset=utf-8"> 
        <title>Reg</title>
        <style>
            .state1{
                color:#aaa;
            }
            .state2{
                color:#000;
            }
            .state3{
                color:red;
            }
            .state4{
                color:green;
            }
        </style>
        <script src="jquery.js"></script>
        <script>
            $(function(){
 
                var ok1=false;
                var ok2=false;
                var ok3=false;
                var ok4=false;
                // 验证用户名
                $('input[name="username"]').focus(function(){
                    $(this).next().text('用户名应该为3-20位之间').removeClass('state1').addClass('state2');
                }).blur(function(){
                    if($(this).val().length >= 3 && $(this).val().length <=12 && $(this).val()!=''){
                        $(this).next().text('输入成功').removeClass('state1').addClass('state4');
                        ok1=true;
                    }else{
                        $(this).next().text('用户名应该为3-20位之间').removeClass('state1').addClass('state3');
                    }
                     
                });
 
                //验证密码
                $('input[name="password"]').focus(function(){
                    $(this).next().text('密码应该为6-20位之间').removeClass('state1').addClass('state2');
                }).blur(function(){
                    if($(this).val().length >= 6 && $(this).val().length <=20 && $(this).val()!=''){
                        $(this).next().text('输入成功').removeClass('state1').addClass('state4');
                        ok2=true;
                    }else{
                        $(this).next().text('密码应该为6-20位之间').removeClass('state1').addClass('state3');
                    }
                     
                });
 
                //验证确认密码
                    $('input[name="repass"]').focus(function(){
                    $(this).next().text('输入的确认密码要和上面的密码一致,规则也要相同').removeClass('state1').addClass('state2');
                }).blur(function(){
                    if($(this).val().length >= 6 && $(this).val().length <=20 && $(this).val()!='' && $(this).val() == $('input[name="password"]').val()){
                        $(this).next().text('输入成功').removeClass('state1').addClass('state4');
                        ok3=true;
                    }else{
                        $(this).next().text('输入的确认密码要和上面的密码一致,规则也要相同').removeClass('state1').addClass('state3');
                    }
                     
                });
 
                //验证邮箱
                $('input[name="email"]').focus(function(){
                    $(this).next().text('请输入正确的EMAIL格式').removeClass('state1').addClass('state2');
                }).blur(function(){
                    if($(this).val().search(/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/)==-1){
                        $(this).next().text('请输入正确的EMAIL格式').removeClass('state1').addClass('state3');
                    }else{                  
                        $(this).next().text('输入成功').removeClass('state1').addClass('state4');
                        ok4=true;
                    }
                     
                });
 
                //提交按钮,所有验证通过方可提交
 
                $('.submit').click(function(){
                    if(ok1 && ok2 && ok3 && ok4){
                        $('form').submit();
                    }else{
                        return false;
                    }
                });
                 
            });
        </script>
    </head>
<body>
  
<form action='do.php' method='post' >
    用 户 名:<input type="text" name="username">
                <span class='state1'>请输入用户名</span><br/><br/>
    密  码:<input type="password" name="password">
                <span class='state1'>请输入密码</span><br/><br/>
    确认密码:<input type="password" name="repass">
                <span class='state1'>请输入确认密码</span><br/><br/>
    邮  箱:<input type="text" name="email">
                <span class='state1'>请输入邮箱</span><br/><br/>   
 
</form>
</body>

 




Reg




用 户 名:
请输入用户名

密  码:
请输入密码

确认密码:
请输入确认密码

邮  箱:
请输入邮箱

By柏小白

jQuery 实现回到顶部代码

HTML 结构
我使用了JS添加,需要提取出来也比较方便,需要美化的自行添加style

CSS 代码

/*返回顶部*/
.GoTop { width: 50px; height: 45px; bottom: 55px; cursor: pointer; background: red; color: white; text-align: center; position: fixed; right: 50px; display: none; z-index: 580; }

jQuery 代码

$(function() {

	var globalConfig = true;  //是否启用回到顶部  true启用 : false 关闭 
	if(!globalConfig)return false;  


	var $GoTop = $('.GoTop'),right,



	$window = $(window);

	if(!$GoTop.length){ //如果不存在返回顶部append添加

	    $GoTop = $('<div class="GoTop">返回顶部</div>');

	    $("body").append($GoTop);
	}


	if($window.width() < 1280){ //浮动右边right距离 
	    right = 10;
	}
	else{
	    right = Math.abs(($window.width() - 1200) / 2 - $GoTop.width());  //1200  定义主体宽度 
	    $GoTop.css("right", right);
	}


	$GoTop.bind("click.GoTop", function (){  //当点击标签的时候,使用animate在500毫秒的时间内,滚到顶部
	    $('body,html').animate({scrollTop: 0}, "500");
	});


	$window.bind("scroll.GoTop", function (){ //只要窗口滚动,就触发下面代码 

      $(this).scrollTop()>100?$GoTop.fadeIn():$GoTop.fadeOut();   //判断滚动后高度超过100px,就显示  

	});






});

 





返回顶部





By柏小白

jquery 文字滚动大全 单行滚动 多行滚动 带按钮控制滚动

<!DOCTYPE html>
<html lang="zh-cn">
<head>
	<meta charset="UTF-8" />
<title>jquery 文字滚动大全 单行滚动 多行滚动 带按钮控制滚动</title>
<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
<style type="text/css">
*{margin:0;padding:0;}
ul,li{list-style-type:none;}
body{font:12px/180% Arial, Helvetica, sans-serif;}
a{color:#333;text-decoration:none;}
a:hover{color:#3366cc;text-decoration:underline;}
.demopage{width:960px;margin:0 auto;}
.demopage h2{font-size:14px;margin:20px 0;}
/* scrollDiv */
.scrollDiv{height:25px;/* 必要元素 */line-height:25px;border:#ccc 1px solid;overflow:hidden;/* 必要元素 */}
.scrollDiv li{height:25px;padding-left:10px;}
#s2,#s3{height:100px;}
</style>
</head>
 
<body>
<div class="demopage">
	<h2>jquery 文字上下滚动--单行 批量多行 文字图片上下翻滚 | 单行滚动</h2>
	<div class="scrollDiv" id="s1">
		<ul>
			<li><a href="http://www.17sucai.com/">jquery 滚动条 Scrollbar 设置浏览器默认滚动条样式</a></li>
			<li><a href="http://www.17sucai.com/">jquery 图片切换 switchable 带左右按钮控制分页索引图片切换</a></li>
			<li><a href="http://www.17sucai.com/">jquery powerFloat万能浮动框提示插件 支持图片、文字、ajax异步加载、表单验证等</a></li>
			<li><a href="http://www.17sucai.com/">jquery 弹出层插件 ThickBox 多功能弹出层插件支持图片、ajax、内嵌内容弹等</a></li>
			<li><a href="http://www.17sucai.com/">jquery 表单美化 jquery tzCheckbox 复选框美化 自定义默认复选框</a></li>
			<li><a href="http://www.17sucai.com/">jquery HTML5 幻灯片插件 用 Canvas 制作类似百叶窗拍摄快门摄影拍摄效果</a></li>
			<li><a href="http://www.17sucai.com/">jquery 图片放大镜 图片类似放大镜效果鼠标滑过小图异步加载中图、大图</a></li>
			<li><a href="http://www.17sucai.com/">jquery 图片幻灯片 点击小图显示大图异步加载 支持按钮播放</a></li>
		</ul>
	</div><!--scrollDiv end-->
	<script type="text/javascript">
	function AutoScroll(obj){
		$(obj).find("ul:first").animate({
			marginTop:"-25px"
		},500,function(){
			$(this).css({marginTop:"0px"}).find("li:first").appendTo(this);
		});
	}
	$(document).ready(function(){
		setInterval('AutoScroll("#s1")',3000);
	});
	</script>
	
	
	<h2>jquery 文字上下滚动--单行 批量多行 文字图片上下翻滚 | 多行滚动</h2>
	<div class="scrollDiv" id="s2">
		<ul>
			<li><a href="http://www.17sucai.com/">jquery Xslider 插件焦点图片特效图片淡隐淡现、图片上下滚动、图片左右滚动、选项卡</a></li>
			<li><a href="http://www.17sucai.com/">jquery 文字连续滚动 节奏感十足的齿轮式滚动图片展示与文字内容特效展示</a></li>
			<li><a href="http://www.17sucai.com/">jquery cycle 循环幻灯片插件多功能幻灯片插件支持多种幻灯片特效</a></li>
			<li><a href="http://www.17sucai.com/">jquery轻量级进度条 progressbar 带动画显示的进度过程的jquery进度条特效</a></li>
			<li><a href="http://www.17sucai.com/">jquery菜单特效 鼠标滑过菜单区域图标和文本类似flash动画酷炫移动展示</a></li>
			<li><a href="http://www.17sucai.com/">jquery 图片切换 自动切换显示隐藏show/hide带左右按钮与分页索引按钮控制图片自动切换显示隐藏show/hide</a></li>
			<li><a href="http://www.17sucai.com/">jquery图片特效 slide banner焦点图片切换图片上下翻滚、图片左右翻滚、图片淡隐淡现3种图片滚动特效</a></li>
			<li><a href="http://www.17sucai.com/">javascript jscolor colorpicker js颜色选择器插件10多种调用颜色方法与取值</a></li>
		</ul>
	</div>
	<script type="text/javascript">
	//滚动插件
	(function($){
		$.fn.extend({
			Scroll:function(opt,callback){
					//参数初始化
					if(!opt) var opt={};
					var _this=this.eq(0).find("ul:first");
					var lineH=_this.find("li:first").height(), //获取行高
						line=opt.line?parseInt(opt.line,10):parseInt(this.height()/lineH,10), //每次滚动的行数,默认为一屏,即父容器高度
						speed=opt.speed?parseInt(opt.speed,10):500, //卷动速度,数值越大,速度越慢(毫秒)
						timer=opt.timer?parseInt(opt.timer,10):3000; //滚动的时间间隔(毫秒)
					if(line==0) line=1;
					var upHeight=0-line*lineH;
					//滚动函数
					scrollUp=function(){
							_this.animate({
									marginTop:upHeight
							},speed,function(){
									for(i=1;i<=line;i++){
											_this.find("li:first").appendTo(_this);
									}
									_this.css({marginTop:0});
							});
					}
					//鼠标事件绑定
					_this.hover(function(){
							clearInterval(timerID);
					},function(){
							timerID=setInterval("scrollUp()",timer);
					}).mouseout();
			}       
		});
	})(jQuery);
	
	$(document).ready(function(){
		$("#s2").Scroll({line:4,speed:500,timer:4000});
	});
	</script>
	
	
	<h2>jquery 上下滚动--单行 批量多行 文字图片上下翻滚 | 可控制向前向后的多行滚动</h2>
	<div class="scrollDiv" id="s3">
		<ul>
			<li><a href="http://www.17sucai.com/">jquery colorpicker 插件颜色选择器 点击颜色选择颜色值与颜色相应变化</a></li>
			<li><a href="http://www.17sucai.com/">jquery评论星星打分特效、鼠标滑过星星显示评论信息</a></li>
			<li><a href="http://www.17sucai.com/">jquery图片切换滚动 水平手风琴切换滚动鼠标滑过图片水平切换</a></li>
			<li><a href="http://www.17sucai.com/">jquery 图片切换滚动特效带分页索引按钮控制左右图片切换滚动</a></li>
			<li><a href="http://www.17sucai.com/">jquery筛选器插件选项卡 css3制作一个漂亮的HTML5筛选容器插件选项卡</a></li>
			<li><a href="http://www.17sucai.com/">jquery 图片特效用CSS3和HTML5制作仿动画头条报纸缩小到放大翻转图片展示</a></li>
			<li><a href="http://www.17sucai.com/">jquery特效基于jquery幻灯片插件制作一个泡沫幻灯片图片展示特效</a></li>
			<li><a href="http://www.17sucai.com/">jquery 图片幻灯片仿IBM首页焦点图切换,类似flash动态效果图片切换</a></li>
		</ul>
	</div>
	<span id="btn1" >点击向上滚动</span>&nbsp;&nbsp;<span id="btn2">点击向下滚动</span>
	<script type="text/javascript">
	(function($){
		$.fn.extend({
			Scroll:function(opt,callback){
					//参数初始化
					if(!opt) var opt={};
					var _btnUp = $("#"+ opt.up);//Shawphy:向上按钮
					var _btnDown = $("#"+ opt.down);//Shawphy:向下按钮
					var timerID;
					var _this=this.eq(0).find("ul:first");
					var     lineH=_this.find("li:first").height(), //获取行高
							line=opt.line?parseInt(opt.line,10):parseInt(this.height()/lineH,10), //每次滚动的行数,默认为一屏,即父容器高度
							speed=opt.speed?parseInt(opt.speed,10):500; //卷动速度,数值越大,速度越慢(毫秒)
							timer=opt.timer //?parseInt(opt.timer,10):3000; //滚动的时间间隔(毫秒)
					if(line==0) line=1;
					var upHeight=0-line*lineH;
					//滚动函数
					var scrollUp=function(){
							_btnUp.unbind("click",scrollUp); //Shawphy:取消向上按钮的函数绑定
							_this.animate({
									marginTop:upHeight
							},speed,function(){
									for(i=1;i<=line;i++){
											_this.find("li:first").appendTo(_this);
									}
									_this.css({marginTop:0});
									_btnUp.bind("click",scrollUp); //Shawphy:绑定向上按钮的点击事件
							});
	
					}
					//Shawphy:向下翻页函数
					var scrollDown=function(){
							_btnDown.unbind("click",scrollDown);
							for(i=1;i<=line;i++){
									_this.find("li:last").show().prependTo(_this);
							}
							_this.css({marginTop:upHeight});
							_this.animate({
									marginTop:0
							},speed,function(){
									_btnDown.bind("click",scrollDown);
							});
					}
				   //Shawphy:自动播放
					var autoPlay = function(){
							if(timer)timerID = window.setInterval(scrollUp,timer);
					};
					var autoStop = function(){
							if(timer)window.clearInterval(timerID);
					};
					 //鼠标事件绑定
					_this.hover(autoStop,autoPlay).mouseout();
					_btnUp.css("cursor","pointer").click( scrollUp ).hover(autoStop,autoPlay);//Shawphy:向上向下鼠标事件绑定
					_btnDown.css("cursor","pointer").click( scrollDown ).hover(autoStop,autoPlay);
	
			}      
		})
	})(jQuery);
	
	$(document).ready(function(){
		$("#s3").Scroll({line:4,speed:500,timer:2000,up:"btn1",down:"btn2"});
	});
	</script>
	
</div><!--demopage end-->	
</body>
</html>

 





jquery 文字滚动大全 单行滚动 多行滚动 带按钮控制滚动

jquery 文字上下滚动–单行 批量多行 文字图片上下翻滚 | 单行滚动


jquery 文字上下滚动–单行 批量多行 文字图片上下翻滚 | 多行滚动

jquery 上下滚动--单行 批量多行 文字图片上下翻滚 | 可控制向前向后的多行滚动

点击向上滚动  点击向下滚动



By柏小白

jQuery弹性滑动导航菜单

最近看到很多鼠标滑过的效果,今天来整理下

<div id="nav">
	<div class="nav-menu">
		<a class="current" href="#">首页</a>
		<a href="#">Menu YI</a>
		<a href="#">Menu ER</a>
		<a href="#">Menu SAN</a>
		<a href="#">Menu SI</a>
		<a href="#">Menu WU</a>
	</div>
	<div class="nav-current"></div>
</div>

Read More

By柏小白

jQuery表单输入框焦点效果

//聚焦型验证
$("#focus .inputText").each(function() {
    $(this).focus(function() {
        $(this).siblings("span").hide();
    }).blur(function() {
        if ($(this).val() == "") {
            $(this).siblings("span").show();
        } else {
            $(this).siblings("span").hide();
        }
    })
})
 
//输入型验证
$("#keydown .inputText").each(function() {
    $(this).keydown(function() {
        $(this).siblings("span").hide();
    }).blur(function() {
        if ($(this).val() == "") {
            $(this).siblings("span").show();
        } else {
            $(this).siblings("span").hide();
        }
    })
})

CSS代码

body {
    background: #333;
    padding: 0;
    margin: 0;
}
 
#focus, #keydown {
    width: 400px;
    padding: 20px;
    background: #FCF9EF;
    margin: 30px 0 0 30px;
}
 
#focus h2, #keydown h2 {
    font-size: 24px;
    font-family: "微软雅黑";
    color: #b00000;
}
 
#focus label, #keydown label {
    display: block;
    position: relative;
    height: 40px;
    margin-top: 20px;
}
 
#focus span, #keydown span {
    display: block;
    position: absolute;
    top: 0;
    left: 10px;
    height: 40px;
    line-height: 40px;
    font-size: 14px;
    color: #999;
    cursor: text;
}
 
.radius {
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
}
 
.inputText {
    width: 378px;
    height: 14px;
    padding: 12px 10px;
    border: 1px #ccc solid;
    font-size: 14px;
    color: #333;
    -moz-box-shadow: inset 1px 1px 5px #ddd;
    -webkit-box-shadow: inset 1px 1px 5px #ddd;
    box-shadow: inset 1px 1px 5px #ddd;
}
 
.inputText:focus {
    outline: none;
    border: 1px #B00000 solid;
    -moz-box-shadow: 0 0 4px rgba(255,153,164,0.8);
    -webkit-box-shadow: 0 0 4px rgba(255,153,164,0.8);
    box-shadow: 0 0 4px rgba(255,153,164,0.8);
}

HTML代码

<form class="radius" id="focus">
    <h2>聚焦型提示语消失</h2>
    <label> <span>请输入帐号</span>
        <input type="text" class="inputText radius" />
    </label>
    <label> <span>请输入密码</span>
        <input type="password" class="inputText radius" />
    </label>
</form>
 
<form class="radius" id="keydown">
    <h2>输入型提示语消失</h2>
    <label> <span>请输入帐号</span>
        <input type="text" class="inputText radius" />
    </label>
    <label> <span>请输入密码</span>
        <input type="password" class="inputText radius" />
    </label>
</form>

Read More

By柏小白

用JS控制iframe里的页面,做到3秒自动换

<iframe id="ifr" src="http://www.qietu.cn/?xxx";></iframe>

假定iframe的id为ifr

下面是js程序

var times = 10;  //循环次数
var iframe = document.getElementById('ifr');   //获取iframe元素
//设置定时执行
var t = setInterval(function(){
     if(times--<=0)  clearInterval(t);
     changeFrameSrc(iframe);
},3000);   //3000毫秒
//改变iframe的src属性的函数
function changeFrameSrc(f){
    var src = 'http://www.qietu.cn/?'+rand(100,999);  //生成地址
    f.src = src;
}
//随机函数
function rand(min,max){
    return parseInt(Math.random()*(max-min+1)+min);
}

Read More

By柏小白

CSS+Cookie实现的固定页脚广告条

经常看到有些网站为了吸引用户注意,在页面底部放置固定横幅广告,用户滚动页面时,横幅广告一直固定在页底,并不随页面滚动而滚动,当然一般允许用户可以关闭广告条,并设置一定时间内不再显示此广告条。本文将介绍使用CSS+Cookie来实现这一效果。
HTML
首先,我们将横幅广告的html代码放到页面最底部,因为是最后加载的。也可以使用外部js动态插入到页面底部。整个HTML结构由遮罩层.float_layer,内容层.float_content组成,其中.float_bg为广告部分,内容可以是图片、文字等任意形式的html元素,.float_close是关闭按钮,用户不喜欢广告可以关闭展示。

<div class="float_mask" id="float_mask"> 
    <div class="float_layer"> 
    </div> 
    <div class="float_content clearfix"> 
        <div class="float_bg"> 
            <a target="_blank" href="http://www.helloweba.com/" title='广告部分'> 
                <div class="float_slogan"><!--广告内容--></div> 
            </a> 
        </div> 
        <div class="float_close"> 
            <a onclick="closeFootAd()" href="#" title="我知道了"></a> 
        </div> 
    </div> 
</div>

Read More

By柏小白

chrome下去掉保存密码后输入框变成黄色背景样式

做前端的童鞋一定经常遇到过chrome保存密码后input输入框会变成黄色,对于正在开发中的项目,老是出来黄色背景很是不爽。

我们用代码审查查看了input样式发现有如下样式设定。
]A}O5L_1S40XW{[LK0BT3OA

然后我用!important设定后发现不能修改默认状态。最后用了阴影实现了

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
    box-shadow:0 0 0 60px #fff inset;
    -webkit-text-fill-color: #333;
}

如果不想保存密码的话加个autocomplete=”off”到form或者input就行了。

相关链接:http://labs.enonic.com/articles/remove-forced-yellow-input-background-in-chrome

By柏小白

网页中点击链接跳转到QQ聊天界面

scheme = "mqqwpa://im/chat?chat_type=wpa&uin=" + g.tuin + "&version=1&src_type=web&web_src=" + host;

是的,具体的是:

mqqwpa://im/chat?chat_type=wpa&uin=360708355&version=1

,点击试一下?

可是,不知道为什么现在只能到达手机QQ界面,无法到达QQ聊天界面,我用的ios测试的,继续抛砖引玉中。

后来进行了另外的尝试,点击这里试一下。是不是可以进入聊天界面。

链接是这样的:

mqqwpa://im/chat?chat_type=wpa&uin=574201314&version=1&src_type=web&web_src=qietu.cn

 

<a class="qqzaixian" href="http://wpa.qq.com/msgrd?v=3&amp;uin=360708355&amp;site=qq&amp;menu=yes" target="_blank">点我与“柏小白”聊天</a>

 

pc:点我与“柏小白”聊天

By柏小白

怎样替换为默认图片,加载图片失败

img元素加载图片失败,则变成一个小图标,让页面变得难看。此时如何替换为默认图片?
onerror属性
img元素自带onerror属性,加载失败时,触发error事件

<img src="http://yongqing.is-programmer.com/posts/image.gif" onerror='this.src="http://yongqing.is-programmer.com/posts/default.gif" />

Read More

By柏小白

javascript addLoadEvent延迟加载函数

addLoadEvent 函数 jQuery之父John Resig(提示:噢!也许真的是他写的,但是谁知道呢?)

/*
延迟加载脚本
*func 参数 “函数”
*
*/

function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    } else {
        window.onload = function() {
            oldonload();
            func();
        }
    }
}

 

 

By柏小白

animate-css3动画演示

413870769-JOJO 提供 还没有使用,好用在给于说明

无码无真相:

从上往下渐显

 
  <div class="tip tbShow ani-time1 ani-jy"></div>

从下往上渐显

 
    <div class="tip btShow ani-time1 ani-jy"></div>

从右往左渐显

 
    <div class="tip rlShow ani-time1 ani-jy"></div>

从左往右渐显

 
    <div class="tip lrShow ani-time1 ani-jy"></div>

闪烁,最好设置反向动画更佳:ani-yjfx

 
    <div class="tip shanshuo ani-time1 ani-yjfx"></div>

从小变大

    <div class="tip bianda ani-time1 ani-jy"></div>

上下跳动

    <div class="tip shangxia ani-time1 ani-yjfx"></div>

顺时针转圈

    <div class="tip zhuanquan ani-time1 ani-jy"></div>

逆时针转圈

    <div class="tip zhuanquan-ni ani-time1 ani-jy"></div>






动画

从上往下渐显

从下往上渐显

从右往左渐显

从左往右渐显

闪烁,最好设置反向动画更佳:ani-yjfx

从小变大

上下跳动

顺时针转圈

逆时针转圈



By柏小白

加载Loading 让网页加载完后显示

初次渲染页面页面闪动处理方法:

一个JavaScript网页加载特效,当网页没有加载完成时,会一直显示出这个Loading,当Loading结束后,再会显示网页内容。

现在很多网站仍然在用的网页进度条效果。

//页面加载完成后影藏 loading
function subSomething(){
  if(document.readyState == "complete") // 当前页面状态
  $("#webloading").fadeOut(500,function(){
    $(this).remove();
  });
}
document.onreadystatechange = subSomething;  // 当前页面状态改变的时候执行这个方法
<div id="webloading"></div>

加上定时器

function subSomething() {

var timeId=setInterval(function(){
if (document.readyState == "complete") { // 当前页面状态
    $("#webloading").fadeOut(500, function() {
      $(this).remove();
       clearInterval(timeId);
    });
 
  }

}, 1000)

}

 






Document



By柏小白

慢慢,收集js代码块(持续更新……)

酷爱代码,但无记性

经常看,经常忘记,今天开始总结下代码块,便于今后翻阅

1.window.onload 事件处理函数

//  加载函数
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}

2.添加class 函数

function addClass(element, value) {
  if (!element.className) {
    element.className = value;
  } else {
    newClassName = element.className;
    newClassName += " ";
    newClassName += value;
    element.className = newClassName;
  }
}

3.跳转页面-当前导航菜单添加属性

function highlightPage() {

  // 现代浏览器一般都支持
  // if (!document.getElementsByTagName) return false;
  // if (!document.getElementById) return false;

  if (!document.getElementById("navigation")) return false;
  var nav = document.getElementById("navigation");
  var links = nav.getElementsByTagName("a");

 
  for (var i = 0; i < links.length; i++) {
    //links[i]的 URL 
    var linkurl = links[i].getAttribute("href");  
    // 当前页面URL相匹配的链接 
    var currenturl = window.location.href; 
    // links[i]的 URL与当前页面的URL进行比较
    if (currenturl.indexOf(linkurl) != -1) {
      // 添加值为here的class属性
      links[i].className = "here";
      // 获取当前最后一个子节点---就是当表示文本,并转换成小写字母
      var linktext = links[i].lastChild.nodeValue.toLowerCase();
      // 把变量linktext 赋值给 body元素的id属性即可
      document.body.setAttribute("id", linktext);
    }
  }

}

// 调用 window.onload 事件处理函数
addLoadEvent(highlightPage);
<div id="navigation">
    <ul>
        <li><a href="index.html">Home</a></li>
        <li><a href="about.html">About</a></li>
        <li><a href="photos.html">Photos</a></li>
        <li><a href="live.html">Live</a></li>
        <li><a href="contact.html">Contact</a></li>
    </ul>
</div>

4. 点击空白或者页面其他地方,关闭弹框

$(document).mouseup(function(e){
  var _con = $(' 目标区域 ');   // 设置目标区域
  if(!_con.is(e.target) && _con.has(e.target).length === 0){ // Mark 1
    some code...   // 功能代码
  }
});

//  Mark 1 的原理:
// 判断点击事件发生在区域外的条件是:
// 1. 点击事件的对象不是目标区域本身
// 2. 事件对象同时也不是目标区域的子元素

 

未完待续……

By柏小白

javascript

——人脑不是机器,记忆都会退化,我们需要文档辅助作知识沉淀

javascript

基本功

语言特性
  • 数据类型:
    • Undefined, Null, Bollean, Number, String
    • ObjectArray
    • DateRegExp
  • typeof输出(以下六个值之一):
    • undefined javascript var x; typeof(x); // "undefined"
    • boolean javascript var x = false; typeof x; // "boolean"
    • string javascript var x = ''; typeof x; // "string"
    • number javascript var x = NaN; typeof x; // "number"
    • object javascript var x = {}; var y = []; var z = null; typeof x; // "object" typeof y; // "object" typeof z; // "object"
    • function javascript var x = function() {}; typeof x; // "function"
类型转换:
  • 简单类型 -> 简单类型: javascript '1'-0; // 0, equal to Number(1)
  • 简单类型 -> 对象(使用基本函数的构造函数:Number(), String(), Boolean()等生成): javascript var n = 5; console.log(n.toString(2)); // 快速进制转换
  • 对象 -> 简单类型(参考JavaScript 类型转换
1. 隐式转换:除Date外,统统是先 `valueOf`、再 `toString`(`Date` 在 `+` 和 `==` 时优先转化为字串):
``` javascript
[] + 1; // 1
```

2. 显式Number(对象):先`valueOf`,再`toString()`,都不存在则返回`NaN`:
``` javascript
Number({}); // NaN
```

3. 显式String(对象):先取`valueOf()`,再取`valueOf()`,都不存在则抛异常:
``` javascript
String({}); // [object Object]
```
DOM操作(增、删、查、改、移、数据交换)
  • createElement, createTextNode, createDocumentFragment, appendChild
  • removeChild, removeNode
  • getElementById, getElementsByTagName, getElementsByClassName, querySelector, querySelectorAll, parentNode, firstChild, lastChild, nextSibling, previousSibling, childNodes
  • replaceChild, insertBefore
  • getAttribute, setAttribute, data-x, jQuery.attr(), jQuery().prop(), jQuery().data(), classList, innerHTML, innerText, textContent
事件机制(IE VS W3C)
  • 事件绑定与解绑:addEventListener(type, handler, flag), attechEvent('on' + type, handler), removeEventListener(type, handler), detechEvent('on' + type, handler)
  • 事件流:
    • 事件捕获流:沿着文档树由外到内
    • 事件对象 javascript function handler(e) { var e = e || window.event; var target = e.target || e.srcElement; // e.currentTarget 指的是绑定事件的元素,不一定和target是同一个 }
    • 事件冒泡流:沿着文档树由内到外,load、unload、focus、blur、submit和change事件不支持冒
OOP(原型链、继承。。。)
  • 比较(参考 全面理解面向对象的 JavaScript
    • 基于类Class的面向对象,对象由类Class产生:如JavaC#
    • javascript:基于原型prototype的OOP,对象由构造器(构造函数)constructor利用原型prototype产生
  • 生成js对象:
1. 类JSON的对象字面量:简单直观,但不适用于复杂的对象(类)
``` javascript
var Preson = {
    name: 'xiaoming',
    age: 15
};
```

2. 构造函数模式:存在内存浪费的问题,比如下面例子里的`this.city`,在内存里生成了多次
``` javascript
var Person = function(name, age) {
    // 全部标记为私有成员
    this.name = name;
    this.age = age;
    this.city = 'shen zhen';
};
var xm = new Person('xiaoming', 15);
var xl = new Person('xiaoli;, 20);
```

3. 原型`prototype`模式:每次实例化只增加私有的对象属性(或方法)到实例中,所有实例的公有属性(或方法)指向同一个内存地址
``` javascript
var Person = function(name, age) {
    // 对象的私有成员
    this.name = name;
    this.age = age;
};
Person.prototype.city = 'shen zhen';// 共有成员
```
  • 对象的继承
1. 非构造函数的继承:继承可以简单使用对象之间的深、浅拷贝

2. 构造函数的继承:大多是基于原型的继承,但是阅读性差,也不利于扩展

    1. 借调:依赖apply或者call实现
    ``` javascript
    function A(name) {
        this.name = name;
    }
    function B(name, age) {
        A.apply(this, arguments);
        this.age = age;
    }
    ```

    2. 子类prototype引用父类的prototype
    ``` javascript
    function A() {}
    A.prototype.propA = 'a';
    A.prototype.propB = 'b';
    function B() {}
    B.prototype = A.prototype; // 原型链引用,改成B.prototype = new A();可以解决引用的问题
    B.prototype.propB = 'B'; // 函数重载
    B.prototype.constructor = B;
    var b = new B();
    ```
    A、B的prototype引用同一个地址,实时上A的prototype.constructor已经被改成了B

    3. 借用空函数的prototype,类似YUI的实现:
    ``` javascript
    function extend(sub, sup) {
        var _f = function() {};
        _f.prototype = sup.prototype;
        sub.prototype = new _f();
        sub.prototype.constructor = sub;
        sub.super = sup.prototype;// 保存原构造函数
        _f = null;
    }
    A.prototype.propA = 'a';
    A.prototype.propB = 'b';
    function B() {}
    extend(B, A);
    ```

    构造函数的继承,重要的是理解原型链`prototype chain`,继承基本就是原型链的拷贝或者引用。

    理解原型链`prototype chain`:
    ``` javascript
    function A() {}
    function B() {}
    B.prototype = new A();
    function C(x, y) {}
    C.prototype = new B();
    var c = new C();
    c.__proto__ === C.prototype;// true
    B.prototype.__proto__ === A.prototype;// true
    B.__proto__ === B.prototype;// true
    A.__proto__ === Function.prototype;// true
    A.prototype.__proto__ === Object.prototype;// true
    ```
    ***__proto__属性***:对象的`__proto__`指向`Object.prototype`,Function对象的`__proto__`指向构造函数的prototype。

3. 类式继承:本质上还是使用构造函数的`prototype`,封装成类,典型的例子是jQuery之父*John Resig*的[Simple JavaScript Inheritance](http://ejohn.org/blog/simple-javascript-inheritance/),其他类库也有各自的实现

    * Simple Inheritance的用法
    ``` javascript
    var Person = Class.extend({
        init: function(gender) {
            this.gender = gender;
        }
    });
    var Teacher = Person.extend({
        init: funciton(gender, name) {
            this._super(gender);
            this.name = name;
        },
        role: 'teacher',
        speek: function() {
            console.log('Hello, i am a %s.', this.role);
        }
    });
    var Student = Person.extend({
        init: funciton(gender, name) {
            this._super(gender);
            this.name = name;
        },
        role: 'student',
        speek: function() {
            console.log('Hello, i am a %s.', this.role);
        }
    });
    ```
函数式编程、作用域、闭包、THIS
  • 实参、形参 javascript foo(1, 2); function foo(a, b, c) { console.log(arguments.length);//2 实际传入的参数 console.log(foo.length);//3 期望传入的参数 }
  • 函数申明与函数表达式 javascript function foo() {} // 函数申明 var foor = function foo() {};// 函数表达式 执行顺序:解析器会率先读取函数声明,所以在任何代码执行前函数申明可用 javascript fn(2); // 4 function fn(n) {console.log(n);} fn(2); // 4 function fn(n) {console.log(n*n);} //重载 fn(2); // 4 var fn = function(n) {console.log(++n);};// 函数表达式,按照申明的顺序执行 fn(2); // 3
  • arguments, callee, caller, apply, call
    • arguments,类数组,类似的还有NodeList、classList等对象。根据ECMA-262的标准,arguments属性是基于传入的参数来新建arguments,不是基于命名参数的数量。
    • arguments.callee,返回正在执行的Function对象的一个引用 javascript function foo(n) { console.log(arguments.callee.arguments.length); console.log(arguments.callee.length); } foo(1, 2, 3);// 分别打出3,1
    • arguments.caller,返回调用这个Function对象的Function对象的引用
    • applycall,传参不同,功能相同,都是把Function对象绑定到另外一个对象上去执行,其内的this指向这个对象
  • 作用域
    • 函数的局部变量:函数形参、函数内部var声明的变量
    • 变量的查找(作用域链):查找函数内部变量 -> 查找嵌套的外部函数 …-> 查找window对象 -> 未定义
    • js中没有块级作用域,可以用匿名函数模拟
    • 未用关键字var申明的变量,会自动升级为全局变量挂到window上
    • 顶级作用域内使用var申明的变量是window对象的一个属性
  • 闭包
    • 由于作用域的限制,函数外部不能访问函数内部的局部变量
    • 闭包就是能够读取其他函数内部变量的函数引自学习Javascript闭包 javascript function foo() { var x = 1; return function fn() { // closure return x; } } var bar = foo(); console.log(bar()); // get the local variables in foo
    • 闭包的另一个作用是在内存中保存函数的局部变量,这有可能导致内存泄露
  • this:函数中的this始终指向函数的调用者 javascript function foo(x) { this.x = x; } foo(1); // 调用者是window,也可以window.foo() console.log(window.x); // 1 var o = {}; o.foo = foo; o.foo(2); // 调用者是o console.log(o.x); // 2 console.log(window.x); // 1 这里有一篇详细的例子
AJAX(XMLHTTPREQUEST VS ACTIVEXOBJECT)
  • 请求过程
    • 建立到服务器的新请求:xhr.open()
    • 向服务器发送请求:xhr.send()
    • 退出当前请求:xhr.abort()
    • 查询当前HTML的就绪状态:xhr.readyState
    • 服务器返回的请求响应文本:xhr.responseText
  • REST API:POST, GET, PUT, DELETE
    • GET:更多的用于操作,参数暴露到url,(服务器端可能对)url长度有限制
    • POST:更多的用于操作
  • HTTP状态码
  • XHR2

跨域问题

  • 跨域的形成(同源限制):主域、子域、ip和域名、协议不同、端口不同
  • 常用解决方案
    • iframe+document.domain:适用于垮子域的情况 缺点是如果一个域名下存在安全问题,另一个域名下可能也会有问题,还有就是创建iframe的开销
    • 动态引入js脚本:适合所有的跨域场景 引入的脚本会立刻执行,存在安全风险 要与远端沟通约定变量,增加了开发和维护成本
    • iframe+location.hash:适合各种场景下跨域 iframe嵌套引用,开销更大 会产生历史记录,url中暴露传递的内容
    • iframe+window.name:使用iframe的window.name从外域传递数据到本地域,适合各种场景下跨域且数据安全 缺点是数据有大小限制
    • postMessage跨域通讯

jQuery

可阅读yuanyan同学的jQuery编程实践

安全问题

  • XSS
  • CSRF
  • SQL注入
  • 敏感信息采用安全传输(SSL/HTTPS)
  • 上传限制(大小、mime类型、可执行文件)
  • (服务器端)严格的路径限制,比如杜绝路径跳转

css

  • css盒子模型
  • css的继承规则
  • IE低版本的hacks
  • 浏览器的怪异模式与标准模式

性能优化(最佳实践)

HTML优化

  • 语意化html结构:SEO友好,利于维护
  • 精简html结构:嵌套过复杂的结构会导致浏览器构建DOM树缓慢
  • html最小化:html大小直接关系到下载速度,移除内联的css,javascript,甚至模板片,有条件的话尽可能压缩html,去除注释、空行等无用文本
  • 总是设置文档字符集:如果不设置,浏览器在渲染页面前会做一些查找,先搜索可进行解析的字符
  • 显式设置图片的宽高:减少页面重绘(参考【高性能前端1】高性能HTML
  • 去除空链接属性(imglinkscriptiframe元素的srchref属性被设置了,但是属性却为空):部分浏览器依然会去请求空地址
  • 正确的闭合标签:浏览器不一定会将它们修复成正确的格式
  • 避免@import引入样式表:IE低版本浏览器会再页面构建好之后再去加载import的样式表,会导致白屏
  • 样式表放head里,脚本延后引入
  • 未完待续。。。

CSS优化

  • 避免css表达式:css表达式会不断的重复计算,导致页面性能下降
  • 避免AlphaImageLoader滤镜:这个滤镜的问题在于浏览器加载图片时它会终止内容的呈现并且冻结浏览器(引自【高性能前端1】高性能CSS
  • 合并图片(css sprites)
  • 尽量避免通配符选择器:CSS选择器是从右到左进行规则匹配,基于这个机制,浏览器会查找所有同类节点然后逐级往上查找,知道根节点,这样效率很低
  • 尽量避免属性选择器(\*=, |=, ^=, $=, ~=):正则表达式匹配比基于类别的匹配慢
  • 移除无匹配的规则:缩减文档体积;浏览器会把所有的样式规则都解析后索引起来,即使是当前页面无匹配的规则
  • 合并多条可合并的规则,使用简写: css .box {margin-top: 10px; margin-left: 5px; margin-bottom: 15px;} /* bad */ .box {margin: 10px 0 15px 5px;} /* better */
  • 对IE浏览器单独使用hack:代码清晰易读,同时也减小样式体积
  • 模块化css,最好能够组件化:查找、维护方便,同时也利于代码复用
  • 完善注释
  • 未完待列。。

JavaScript优化

  • 尽量减少或最少化对DOM的操作(脱离文档流对DOM进行修改)
    • 隐藏元素,对其进行修改之后再显示
    • 使用文档片段DocumentFragement批量修改,最后再插入文档
    • 将元素拷贝一份,修改完之后再替换原有元素
  • 谨慎操作节点集合NodeList(images, links, forms, document.getElementsByTagName): 缓存NodeList以及NodeList.length的引用
  • 尽量操作元素节点(DOM节点如childNodes, firstChild不区分元素节点和其他类型节点,但大部分情况下只需要访问元素节点引自《高性能JavaScript》):
    • children代替childNodes
    • childElementCount代替childNodes.length
    • firstElementChild代替firstChild
  • 读写分离,减少layout: javascript x = box.offsetLeft; // read box.offsetLeft = '100px'; // write y = box.offsetTop; // read box.offsetTop = '100px'; // write 这个过程造成了两次的layout,可做如下改造:javascript x = box.offsetLeft; // read y = box.offsetTop; // read box.offsetLeft = '100px'; // write box.offsetTop = '100px'; // write
  • 最小化重排(repeat): javascript box.style.width = '100px'; box.style.heihgt = '50px;'; box.style.left = '200px'; 三个操作都会重新计算元素的几何结构,在部分浏览器可能会导致3次重排,可做如下改写:javascript var css = 'width: 100px; height: 50px; left: 200px;'; box.style.cssText += css;
  • 使用事件委托:充分利用冒泡机制,减少事件绑定
  • 无阻塞加载:脚本延后加载,合并加载,并行加载
  • 函数内部的变量尽可能使用局部变量,缩短变量作用域的查找时间
  • 缓存对象引用: javascript var a = $('#box .a'); var b = $('#box .b'); 可以缓存$('#box')到临时变量: javascript var box = $('#box'); var a = box.find('.a'); var b = box.find('.b');
  • 减少多级引用: javascript var $P = Jx().UI.Pager.create();// 同样可以先缓存结果
  • 缓存Ajax:
    • 缓存Ajax数据,利用本地存储或者临时变量,存储不需要实时更新的数据
    • 设置HTTP Expires信息
  • 复杂的计算考虑使用Web Worker

jQuery性能优化

合理使用选择器
  • id和标签选择器最快,因为是直接调用原生API javascript $('#box'); // document.getElementById | document.querySelector $('div'); // document.getElementsByTagName
  • 类选择器在低版本浏览器较慢,伪元素、属性选择器在不支持querySelector的浏览器很慢
  • 尽可能优先使用符合CSS语法规范的CSS选择器表达式,以此来避免使用jQuery自定义的选择器表达式,因为当jQuery遇到单个id, 标签名,类名,选择器就会快速调用浏览器支持的DOM方法查询 javascript $('input[checked="checked"]'); // 比较快 $('input:checked'); // 较慢
  • 优先选择$.fn.find查找子元素,因为find之前的选择器并没有使用 jQuery 自带的 Sizzle 选择器引擎,而是使用原生API查找元素 javascript $('#parent').find('.child'); // 最快 $('.child', $('#parent')); // 较快,内部会转换成第一条语句的形式,性能有一定损耗 $('#parent .child'); // 不如上一个语句块
  • 使用组合选择器时,尽可能让右端更明确,因为Sizzle引擎是从右到左进行匹配的 javascript $('div.foo .bar'); // slow $('.foo div.bar'); // faster
  • 避免过度具体,简洁的 DOM 结构也有助于提升选择器的性能 javascript $('.foo .bar .baz'); $('.foo div.baz'); // better
  • 尽量避免使用通配符选择器
尽可能的少创建JQUERY对象
  • document.getElementById('el')$('#el')
  • 如获取元素id: javascript $('div').click(function(e) { // 生成了个jQuery对象 var id = $(this).attr('id'); // 这样更直接 var id = this.id; });
  • 使用链式调用缓存jQuery对象 xml <div id="user" class="none"> <p class="name"></p> <p class="city"></p> </div> javascript $('#user') .find('.name').html('zhangsan').end() .find('.city').html('shenzhen').end() .removeClass('none');
  • 做好jQuery对象缓存 javascript var box = $('.box'); box.find('> .cls1'); box.find('> .cls2');
避免频繁操作DOM
  • 复杂操作把元素从DOM中移除再操作 javascript var $el = $('.box').detach(); var $p = $el.parent(); // do some stuff with $el... $p.append($el);
  • 在循环外执行DOM修改 javascript // 性能差 $.each(arr, function(i, el) { $('.box').prepend($(el)); }); // 较好的做法 var frag = document.createDocumentFragment(); $.each(arr, function(i, el) { flag.appendChild(el); }); $('.box')[0].appendChild(flag);
使用事件代理
$('ul li').on('click', fn);
// better
$('ul').on('click', 'li', fn);

 

使用事件代理(委托),当有新元素添加进来的时候,不需要再为它绑定事件,这里有demo可以查看效果。

整体优化

  • 雅虎34条:合并压缩文件和图片、gzip/deflate、CDN、HTTP头设置Cache-Control/Expires和Last-Modified/ETag、并行下载与DNS查询的平衡等
  • 缓存静态文件,尽可能采用CDN策略,并采用不带cookie的独立域名存放,并开启keep-alive
  • 动态与静态结合,服务器端拼凑页面片,最快展现给用户,缩短白屏时间和页面可用时间,非首屏数据懒加载
  • 内容分开存放,比如图片和ajax分别采用不用的服务器(域名下)
  • 保证单个html的http请求数最少
  • 确保网站有favicon.ico文件(浏览器会自动请求favicon.ico,如果不存在则会出现大量的404消耗带宽)
  • 未完待续。。。
By柏小白

html你好?

 

<!doctype html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>柏小白</title>
</head>
<body>

</body>
</html>
By柏小白

WebStorm 11.0.3 汉化包设置

WebStorm 10 汉化包 //链接:http://pan.baidu.com/s/1cghgPw 密码:noie
WebStorm 11 汉化包 //链接:http://pan.baidu.com/s/1kVdMWyb 密码:ap96

柏小白-教你汉化WebStorm 11.0.3

柏小白-教你汉化WebStorm 11.0.3

进入WebStorm 11.0.3 (我是安装后,帮助-关于-里面升级成功为11.0.4)
WebStorm 软件中 找到(lib)并进入,把你在百度里下载的 WebStorm_zh_CN-(resources_cn.jar)直接放进(lib)
完成了,重新启动 WebStorm 11.0.3 中文汉化完成。。。
传说:“IntelliJ IDEA Community Edition 15.0.4 也可以用这个(resources_cn.jar)”

翻译插件作者:Github

By柏小白

IIS部署 Web svg/woff/woff2字体 404错误

问题:最近在IIS上部署web项目的时候,发现浏览器总是报找不到woff、woff2字体的错误。导致浏览器加载字体报404错误。

原因:因为服务器IIS不认SVG,WOFF/WOFF2 这几个文件类型,只要在IIS上添加MIME 类型即可。

解决方法

1、打开服务器IIS管理器,找到MIME类型。

2222

 

 

2、添加MIME类型 添加三条:

文件扩展名      MIME类型

.svg             image/svg+xml
.woff            application/x-font-woff
.woff2          application/x-font-woff

1111

注:本文在win7环境下IIS7版本中填写的MIME类型,在IIS6、IIS8 MIME类型管理所处位置不一样,但是添加方式和参数均相同。

By柏小白

FTP版本发布搭建

Windws Server 2008 R2 WEB环境配置之FTP服务搭建
说来就搞笑之前都是,使用windows服务器 客户端-服务器端-安装百度云盘 做发布-来来回回好麻烦,一直想用以前使用过的FTP做静态版本发布,google了三篇有用的文章,现在做存档,方便下次查阅

没有FTP的伙伴狂点下载:

FTP下载链接:http://pan.baidu.com/s/1eREU63K 密码:qlxp

文章1:Windws Server 2008 R2 WEB环境配置之FTP服务搭建

FTP是一种文件传输协议,基于其可以使远距离的二台计算机之间复制文件变得更简单。所以今天我们来搭建一个简单、易用、安全的FTP服务环境。

市面上FTP软件不下2、3十款,最著名的就数SERV-U了,其功能强大,设置相对复杂,目前最新版本已经发布到15.0了,在其官网上可以下载到14.0的版本。

关于SERV-U的教程网上有很多,也有各种版本,但是今天我们不打算讲它。今天的主题讲二款FTP服务软件的搭建与设置,一款是Windows Server 2008 R2自带的FTP服务器软件,另一款就是开源且强大的Filezilla Server了。

 

IIS自带FTP搭建

1、先安装IIS FTP 角色服务。

打开“服务器管理器”,“角色”,如果是第一次安装IIS,则选择“添加角色”;如果你原先已经安装过 IIS ,则选择“添加角色服务”,然后选中“FTP服务器”即可。

我这里原先已经安装好了IIS,所以选择“添加角色服务”,

在选择角色服务窗口中,选中“FTP服务器”,

下一步,等待安装完毕。

2、新建FTP站点

FTP站点跟创建网站类似。

给站点起一个名称,指FTP站点的根目录,

填写ftp服务器的ip地址,端口,默认端口是21,

指定一个用户可以访问此FTP站点,你也可以选择所有用户。

然后再新建一个用户名为ftp的用户,

打开FTP客户端软件,填上IP地址,用户名,密码就可以连上了。

总结:因为IIS FTP的用户是系统用户,安全性也不是很高。在我的使用过程中,一直有连接不上的情况,就算是新建一个站点,一样的设置,一样的用户都有可能连接不上,研究了一下午,各种坑都有,所以我不推荐大家使用。

Filezilla Server FTP服务搭建

Filezilla Server是一款开源的FTP服务软件,占用资源小,设置简单。

目前官方最新版是0.9.48,可以在官网下载到。官网下载的是英文版,在安装时会安装一个myPCBackup的备份软件,这个软件我们一般不会用,可以在安装完后删除这个软件。

其实还有另一种安装方法。就是在本地安装过一次以后,可以把FileZilla Server目录拷贝出来,上传到服务器再使用。我用的就是这种安装方式。这是我拷贝出来的,提供FileZilla Server 0.9.48下载。

解压下载的FileZilla Server 0.9.48,把它放到c:\FileZilla Server目录下,右击FileZilla Server.exe以管理员身份运行安装,

安装,

加为系统服务,开机自动启动。

点是开启服务。

然后双击FileZilla Server Interface.exe,这个是FileZilla Server的管理工具,

Ip地址、端口默认即可,给管理员设置一个密码,点ok进行设置。

点击菜单栏上的“Edit”,“Users”,点击”Add”,新增一个用户,

我们没有建用户组,所以直接默认为<none>即可。

勾选“Password”,并设置一个密码。

点击左侧的”Shared folders”,点击“Add”添加一个FTP目录,

选中刚添加的目录,在右侧选中相应的权限,最后点OK即可。

这样就添加了一个用户名为user1,FTP目录为D:\FTP 的站点。

 

再在Windows 防火墙中添加一条入站规则,选择端口21。

FTP传输模式有被动和主动二种,所以我们需要在服务器上额外添加一些端口供被动模式使用。

打开FileZilla Server Interface.exe,点击菜单栏“Edit”,“Settings”,选中“Passive mode settings”,勾选右侧的“Use custom port range”,填入一组端口区间。

把上面的1700-1720端口添加到防火墙中,入站规则和出站规则都添加。

经过如此设置,不管是被动模式还是主动模式都能正常连接服务器了。

并且FileZilla的用户跟系统用户无关,所以安全性更高,故推荐。

 

最后用FTP 客户端软件测试。可以用FileZilla Client或FlashFXP,这二款客户端我用得最多。

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://blog.postcha.com/read/9 Windws Server 2008 R2 WEB环境配置之FTP服务搭建

文章2.win7下简单FTP服务器搭建(试验成功)

    
本文介绍通过win7自带的IIS来搭建一个只能实现基本功能的FTP服务器,第一次装好WIN7后我愣是没整出来,后来查了一下网上资料经过试验后搭建成功,其实原理和步骤与windows前期的版本差不多,主要是对新的操作系统还不是很熟悉。相信用过WIN7一段时间的都能独立解决掉。

   
主要分为4个步骤
  
1.安装FTP服务

1

  2
2.在IIS控制面板里添加FTP站点
3
4

 

 

5
67

 

 

  8
3.配置FTP站点

  10

4.
测试站点是否正常工作
 ftp://192.168.10.13

11

文章3.Win7下的内置FTP组件的设置详解

  在局域网中共享文件,FTP是比较方便的方案之一。Win7内部集成了FTP,只是设置起来颇费一番功夫。着文以记之。

一、安装FTP组件

由于Win7默认没有安装FTP组件。故FTP的设置第一步就是安装FTP组件

点击:控制面板—》程序和功能—》打开或关闭Windows功能。勾选“FTP服务器”及“FTP服务”“FTP扩展性”,点击“确定”,安装FTP组件。如下图所示

二、添加FTP站点

点击:控制面板—》管理工具。选中“Internet信息服务(IIS)管理器”,如图

双击“Internet信息服务(IIS)管理器”。弹出管理器界面,如下图所示:

单击选中“网站”,并且在其上右击,选择“添加FTP站点”,出现“站点信息”界面,如下所示:

给FTP取名(本例是:zhu),以及设置FTP站点的物理路径(本例是:c:\ftp),点击“下一步”,出现“绑定和SSL设置”界面,如下图所示

IP设置为本机的IP地址,端口用FTP默认的21,SSL勾选“无”。点击“下一步”,出现“身份验证和授权信息”界面,如下图所示:

如果只是想设置简单的FTP,则“身份验证”和“授权”都勾选“匿名”,并且给匿名设置相应的权限。本例中,还要给FTP配置帐号,以及帐号的权限,故“身份验证”勾选“基本”,“授权”勾选“未选定”,点击“完成”,完成FTP站点的设置。

三、设置FTP帐号以及权限

由于Win7下的FTP帐号是Windows用户帐号。所以,先得添加两个用户帐号,一个是View,可以浏览、下载FTP内容;一个是Admin,完全控制FTP。

点击:控制面板—》管理工具—》计算机管理。在计算机管理的界面的左侧,点击:系统工具—》本地用户和组—》用户,右侧显示所有用户。如下图所示:

在“用户”上右击,出现“新用户”,如下所示:

在用户名中输入View,设置好密码,去掉勾选“用户下次登陆时须更改密码”,勾选“用户不能更改密码”和“密码永不过期”。点击“创建”,完成用户View的创建。同样的步骤,创建Admin用户。由于Windows默认将用户添加到Users组,你可以将刚才的两个用户从Users组中删除。方法是在“计算机管理”中点击“组”,在右侧的列表中找到Users,双击之,出现如下界面,点中用户View,点“删除”,点中用户Admin,点“删除”。将两个用户从Users组中删除。

接下来,在FTP站点中,给View和Admin添加权限。

点击:控制面板—》管理工具—》Internet信息服务(IIS)管理器。点中刚才新建的FTP站点。点中“FTP授权规则”。如下图所示:

点击右侧的“编辑权限”,对FTP站点文件夹添加用户权限。在弹出的窗口中,点击“安全”标签。,如下图所示:

点“编辑”,出现权限的窗口,如下:

点“添加”,在“输入对象名称来选择”中输入View,点“确定”,添加View用户。如下所示:

添加的View用户,默认是只有读取、列出的权限。在依法添加Admin用户,给Admin用户添加完全控制的权限。如下所示:

再回到“Internet信息服务(IIS)管理器”窗口,双击刚才选中的“FTP授权规则”,在FTP站点中对View和Admin授权。如下所示:

点击右侧的“添加允许规则”,在弹出的窗口中,勾选“指定的用户”,输入View,在下方的“权限”中,勾选“读取”。如下所示:

点“确定”,给FTP站点添加View用户,相应的权限是读取。再给FTP站点添加Admin用户,相应的权限是读取和写入。

至此,FTP的站点设置就完成了。站点文件夹是c:\ftp,View用户有读取(浏览和下载)的权限,Admin用户有读取和写入(上传和删除)的权限。当然,还可以根据实际的情况添加用户及相应的权限,也可以将用户添加进组,再给组设置权限。还可以添加匿名用户等等,不一而足了。

然而,事情远远没有结束。如果,你急于做测试的话。会发现,在本机上测试正常,但是用别的机器测试FTP的话,会发现连接不上。问题出在Win7下的防火墙。如果你把防火墙关掉,你会发现FTP恢复了正常,但你也不能因为要用FTP,就把Win7的防火墙关掉。要想在Win7开着防火墙的时候还要正常使用,还必须得在防火墙中进行一番设置

四、Win7的防火墙设置

点击:控制面板—》Windows防火墙。点击左侧的“允许程序或功能通过Windows防火墙”,选中“FTP服务器”,将后面的两个框都勾选,如下所示:

这是网上绝大多数介绍的防火墙设置。然而还不够,你做测试的话会发现,还是连接不上。还必须在防火墙中进一步做设置。

点击下方的“允许运行另一程序”,在弹出窗口里,点“浏览”,找到C:\Windows\System32\inetsrv\inetinfo.exe,点添加,也就是上图中的Internet Infomation Services。将后面的两个框也都选中。因为在Win7下,FTP是IIS的一个组件,因此也必须在防火墙中将IIS设置为允许。而IIS又不在默认的列表中,因此得手动添加。

遗憾的是,这样设置,FTP还是不能正常使用。由于FTP用的是21端口,因此在防火墙中还得添加出站和入站的端口规则。

在Windows防火墙窗口里,点击左侧的“高级设置”,弹出高级安全防火墙窗口,点击左侧的“入站规则”,如下图所示:

点击右侧的“新建规则”,出现向导界面,勾选“端口”,如图:

点击“下一步”,勾选TCP(FTP用的是TCP协议),再勾选特定本地端口,输入21(FTP用的是21端口)如图所示:

点击“下一步”,勾选“允许连接”,如图:

点击“下一步”,默认的都选上,如图:

点击“下一步”,在名称里输入名字,本例中是21,如图

点击“完成”,完成入站规则的设置,在用同样的方法,完成出站规则的设置,同样是21端口。

至此,在Win7的防火墙就已经设置好了。现在测试基本上就正常了。

 

不过,还有个小问题:

在用IE浏览FTP的时候,虽然可以登录,但是没法显示FTP内容。这个是IE的设置问题。在Internet选项中,将“使用被动FTP(用于防火墙和DSL调制解调器的兼容性)”勾掉就解决了不能浏览的问题。如下图所示:

 

后序。总体来说,Win7的内置FTP设置比一些第三方的FTP软件设置要繁琐一些。但是在某些场合下,还只能用Win7的内置FTP。以上的内容都是网上搜集来的,加上本人的亲测。如果谁在FTP设置上还有什么问题,欢迎交流。

作者:万仓一黍
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
By柏小白

jquery的checkbox,radio,select等方法总结

jquery的checkbox,radio,和select是jquery操作的一个难点和重点,很多前端新手对其了解不是很透彻。时间久了不用,我在写的时候有时也难免对某些操作支支吾吾,记不清楚,现在,对其做一些简单的总结!

1、checkbox日常jquery操作。

现在我们以下面的html为例进行checkbox的操作。

<input id="checkAll" type="checkbox" />全选
<input name="subBox" type="checkbox" />项1
<input name="subBox" type="checkbox" />项2
<input name="subBox" type="checkbox" />项3
<input name="subBox" type="checkbox" />项4

Read More

By柏小白

jquery编程的标准写法和最佳实践(jquery代码规范)

关于变量

1、jQuery类型的变量最好加个$前缀。

2、时常将jQuery选择器返回的内容存进变量以便重用

var $myDiv = $("#myDiv");
$myDiv.click(function(){...});

Read More

By柏小白

CDN加速服务,CDN公共库汇总

CDN公共库是指将常用的JS库存放在CDN节点,以方便广大开发者直接调用。将JS库存放在服务器单机上相比,CDN公共库更加稳定、高速。 jQuery插件库为您提供百度、微软等提供的CDN节点地址,这些CDN公共库为您的应用程序提供稳定、可靠、高速的服务,包含全球所有最流行的开源JavaScript库。本文汇总重用CDN

jQuery Migrate

jQuery官网CDN地址jQuery版本迁移辅助插件,用jquery不同版本开发的程序在修改jquery版本出现的兼容问题可以使用jQuery Migrate解决此问题 压缩:

<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>

未压缩:

<script src="http://code.jquery.com/jquery-migrate-1.2.1.js"></script>

jQuery

百度CDN地址支持的版本: 2.0.3, 2.0.2, 2.0.1, 2.0.0,1.11.1, 1.10.2, 1.10.1, 1.10.0, 1.9.1, 1.9.0, 1.8.3, 1.8.2, 1.8.1, 1.8.0, 1.7.2, 1.7.1, 1.7.0, 1.6.4, 1.6.3, 1.6.2, 1.6.1, 1.6.0, 1.5.2, 1.5.1, 1.5.0, 1.4.4, 1.4.3, 1.4.2, 1.4.1, 1.4.0, 1.3.2, 1.3.1, 1.3.0, 1.2.6, 1.2.3

压缩:

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

未压缩:

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>

 

jQuery官方CDN地址支持的版本:2.1.1, 2.0.3, 2.0.2, 2.0.1, 2.0.0, 1.10.2, 1.10.1, 1.10.0, 1.9.1, 1.9.0, 1.8.3, 1.8.2, 1.8.1, 1.8.0, 1.7.2, 1.7.1, 1.7.0, 1.6.4, 1.6.3, 1.6.2, 1.6.1, 1.6.0, 1.5.2, 1.5.1, 1.5.0, 1.4.4, 1.4.3, 1.4.2, 1.4.1, 1.4.0, 1.3.2, 1.3.1, 1.3.0, 1.2.6, 1.2.3

压缩:

<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>

未压缩:

<script src="http://code.jquery.com/jquery-2.1.1.js"></script>

微软CDN地址支持的版本:2.1.1, 2.0.3, 2.0.2, 2.0.1, 2.0.0, 1.10.2, 1.10.1, 1.10.0, 1.9.1, 1.9.0, 1.8.3, 1.8.2, 1.8.1, 1.8.0, 1.7.2, 1.7.1, 1.7.0, 1.6.4, 1.6.3, 1.6.2, 1.6.1, 1.6.0, 1.5.2, 1.5.1, 1.5.0, 1.4.4, 1.4.3, 1.4.2, 1.4.1, 1.4.0, 1.3.2, 1.3.1, 1.3.0, 1.2.6, 1.2.3

压缩:

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script>

未压缩:

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.js"></script>

jQueryui

百度CDN地址支持的版本:1.10.2, 1.10.1, 1.10.0, 1.9.2, 1.9.1, 1.9.0, 1.8.24, 1.8.23, 1.8.22, 1.8.21, 1.8.20, 1.8.19, 1.8.18, 1.8.17, 1.8.16, 1.8.15, 1.8.14, 1.8.13, 1.8.12, 1.8.11, 1.8.10, 1.8.9, 1.8.8, 1.8.7, 1.8.6, 1.8.5, 1.8.4, 1.8.2, 1.8.1, 1.8.0, 1.7.3, 1.7.2, 1.7.1, 1.7.0, 1.6.0, 1.5.3, 1.5.2

压缩:

<script src="http://libs.baidu.com/jqueryui/1.8.22/jquery-ui.min.js"></script>

jQuery官方CDN地址支持的版本:1.11.0,1.10.2, 1.10.1, 1.10.0, 1.9.2, 1.9.1, 1.9.0, 1.8.24, 1.8.23, 1.8.22, 1.8.21, 1.8.20, 1.8.19, 1.8.18, 1.8.17, 1.8.16, 1.8.15, 1.8.14, 1.8.13, 1.8.12, 1.8.11, 1.8.10, 1.8.9, 1.8.8, 1.8.7, 1.8.6, 1.8.5, 1.8.4, 1.8.2, 1.8.1, 1.8.0, 1.7.3, 1.7.2, 1.7.1, 1.7.0, 1.6.0, 1.5.3, 1.5.2

压缩:

<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script>

css 样式:black-tie blitzer cupertino dark-hive dot-luv eggplant excite-bike flick hot-sneaks humanity le-frog mint-choc overcast pepper-grinder redmond smoothness south-street start sunny swanky-purse trontastic ui-darkness ui-lightness vader根据需要修改

<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/black-tie/jquery-ui.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/blitzer/jquery-ui.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/cupertino/jquery-ui.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/dark-hive/jquery-ui.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/dot-luv/jquery-ui.css">

jqMobi

百度CDN地址支持的版本:1.0.0

压缩:

<script src="http://libs.baidu.com/jqmobi/1.0.0/jq.ui.min.js"></script>
 <script src="http://libs.baidu.com/jqmobi/1.0.0/jq.mobi.min.js"></script>

jQuerymobile

百度CDN地址支持的版本:1.3.0, 1.1.1, 1.0.1

压缩:

<script src="http://libs.baidu.com/jquerymobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>

未压缩:

<script src="http://libs.baidu.com/jquerymobile/1.3.0/jquery.mobile-1.3.0.js"></script>

Bootstrap

百度CDN地址支持的版本:2.0.4 ,2.0.3 ,2.0.2 ,2.1.1,2.2.1,2.3.1,2.3.2, 3.0.3

压缩:

<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">

未压缩:

<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.js"></script>
<link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.css" rel="stylesheet">

百度CDN地址支持的版本:2.0.4 ,2.0.3 ,2.0.2 ,2.1.1,2.2.1,2.3.1,2.3.2, 3.0.3

压缩:

<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">

未压缩:

<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.js"></script>
<link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.css" rel="stylesheet">

dojo

百度CDN地址支持的版本:1.8.3, 1.8.2, 1.8.1, 1.8.0, 1.7.4, 1.7.3, 1.7.2, 1.7.1, 1.7.0, 1.6.1, 1.6.0, 1.5.2, 1.5.1, 1.5.0, 1.4.4, 1.4.3, 1.4.1, 1.4.0, 1.3.2, 1.3.1, 1.3.0, 1.2.3, 1.2.0, 1.1.1

压缩:

<script src="http://libs.baidu.com/dojo/1.8.0/dojo.js"></script>

ext-core

百度CDN地址支持的版本:3.1.0,3.0.0

压缩:

<script src="http://libs.baidu.com/ext-core/3.1.0/ext-core.js"></script>

Highstock

百度CDN地址支持的版本:1.2.5

压缩:

<script src="http://libs.baidu.com/highstock/1.2.5/highstock.js"></script>

JSON

百度CDN地址支持的版本:json2压缩:

<script src="http://libs.baidu.com/json/json2/json2.js"></script>

backbone

百度CDN地址支持的版本:0.9.2

压缩:

<script src="http://libs.baidu.com/backbone/0.9.2/backbone-min.js"></script>

未压缩:

<script src="http://libs.baidu.com/backbone/0.9.2/backbone-min.js"></script>

jQuery插件库CDN地址支持的版本:0.9.2

压缩:

<script src="http://jq22com.qiniudn.com/backbone-min.js"></script>

未压缩:

<script src="http://jq22com.qiniudn.com/backbone.js"></script>

lesscss

百度CDN地址支持的版本:1.3.0

压缩:

<script src="http://libs.baidu.com/lesscss/1.3.0/less.min.js"></script>

mootools

百度CDN地址支持的版本:1.4.5, 1.4.4, 1.4.3, 1.4.2, 1.4.1, 1.4.0, 1.3.2, 1.3.1, 1.3.0, 1.2.5, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.1.2, 1.1.1

压缩:

<script src="http://libs.baidu.com/mootools/1.4.5/mootools-yui-compressed.js"></script>

prototype

百度CDN地址支持的版本:1.7.1.0, 1.7.0.0, 1.6.1.0, 1.6.0.3, 1.6.0.2 压缩:

<script src="http://libs.baidu.com/prototype/1.7.1.0/prototype.js"></script>

QUnit

百度CDN地址支持的版本:1.4.0,1.5.0,1.6.0,1.7.0,1.8.0,1.9.0

压缩:

<script src="http://libs.baidu.com/quint/1.9.0/qunit.js"></script>

 

By柏小白

js新生常谈之this,constructor ,prototype

this

this表示当前对象,如果在全局作用范围内使用this,则指代当前页面对象window; 如果在函数中使用this,则this指代什么是根据运行时此函数在什么对象上被调用。 我们还可以使用apply和call两个全局方法来改变函数中this的具体指向。

先看一个在全局作用范围内使用this的例子:

 console.log(this === window);  // true
  console.log(window.alert === this.alert);  // true
  console.log(this.parseInt("021", 10));  // 10

函数中的this是在运行时决定的,而不是函数定义时,如下:

// 定义一个全局函数
        function foo() {
            console.log(this.fruit);
        }
        // 定义一个全局变量,等价于window.fruit = "apple";
        var fruit = "apple";
        // 此时函数foo中this指向window对象
        // 这种调用方式和window.foo();是完全等价的
        foo();  // "apple"

        // 自定义一个对象,并将此对象的属性foo指向全局函数foo
        var pack = {
            fruit: "orange",
            foo: foo
        };
        // 此时函数foo中this指向window.pack对象
        pack.foo(); // "orange"

全局函数apply和call可以用来改变函数中this的指向,如下:

// 定义一个全局函数
        function foo() {
            console.log(this.fruit);
        }

        // 定义一个全局变量
        var fruit = "apple";
        // 自定义一个对象
        var pack = {
            fruit: "orange"
        };

        // 等价于window.foo();
        foo.apply(window);  // "apple"
        // 此时foo中的this === pack
        foo.apply(pack);    // "orange"

注:apply和call两个函数的作用相同,唯一的区别是两个函数的参数定义不同。

因为在JavaScript中函数也是对象,所以我们可以看到如下有趣的例子:

// 定义一个全局函数
        function foo() {
            if (this === window) {
                console.log("this is window.");
            }
        }

        // 函数foo也是对象,所以可以定义foo的属性boo为一个函数
        foo.boo = function() {
            if (this === foo) {
                console.log("this is foo.");
            } else if (this === window) {
                console.log("this is window.");
            }
        };
        // 等价于window.foo();
        foo();  // this is window.

        // 可以看到函数中this的指向调用函数的对象
        foo.boo();  // this is foo.

        // 使用apply改变函数中this的指向
        foo.boo.apply(window);  // this is window.

prototype

prototype本质上还是一个JavaScript对象。

并且每个函数都有一个默认的prototype属性。 如果这个函数被用在创建自定义对象的场景中,我们称这个函数为构造函数。 比如下面一个简单的场景:

// 构造函数
        function Person(name) {
            this.name = name;
        }
        // 定义Person的原型,原型中的属性可以被自定义对象引用
        Person.prototype = {
            getName: function() {
                return this.name;
            }
        }
        var hao= new Person("haorooms");
        console.log(hao.getName());   // "haorooms"

作为类比,我们考虑下JavaScript中的数据类型 – 字符串(String)、数字(Number)、数组(Array)、对象(Object)、日期(Date)等。

我们有理由相信,在JavaScript内部这些类型都是作为构造函数来实现的,比如:

// 定义数组的构造函数,作为JavaScript的一种预定义类型
        function Array() {
            // ...
        }

        // 初始化数组的实例
        var arr1 = new Array(1, 56, 34, 12);
        // 但是,我们更倾向于如下的语法定义:
        var arr2 = [1, 56, 34, 12];

同时对数组操作的很多方法(比如concat、join、push)应该也是在prototype属性中定义的。 实际上,JavaScript所有的固有数据类型都具有只读的prototype属性 (这是可以理解的:因为如果修改了这些类型的prototype属性,则哪些预定义的方法就消失了), 但是我们可以向其中添加自己的扩展方法。

// 向JavaScript固有类型Array扩展一个获取最小值的方法
        Array.prototype.min = function() {
            var min = this[0];
            for (var i = 1; i < this.length; i++) {
                if (this[i] < min) {
                    min = this[i];
                }
            }
            return min;
        };

        // 在任意Array的实例上调用min方法
        console.log([1, 56, 34, 12].min());  // 1

注意:这里有一个陷阱,向Array的原型中添加扩展方法后,当使用for-in循环数组时,这个扩展方法也会被循环出来。 下面的代码说明这一点(假设已经向Array的原型中扩展了min方法):

var arr = [1, 56, 34, 12];
        var total = 0;
        for (var i in arr) {
            total += parseInt(arr[i], 10);
        }
        console.log(total);   // NaN

解决方法也很简单:

var arr = [1, 56, 34, 12];
        var total = 0;
        for (var i in arr) {
            if (arr.hasOwnProperty(i)) {
                total += parseInt(arr[i], 10);
            }
        }
        console.log(total);   // 103

constructor

constructor始终指向创建当前对象的构造函数。比如下面例子:

// 等价于 var foo = new Array(1, 56, 34, 12);
        var arr = [1, 56, 34, 12];
        console.log(arr.constructor === Array); // true
        // 等价于 var foo = new Function();
        var Foo = function() { };
        console.log(Foo.constructor === Function); // true
        // 由构造函数实例化一个obj对象
        var obj = new Foo();
        console.log(obj.constructor === Foo); // true

        // 将上面两段代码合起来,就得到下面的结论
        console.log(obj.constructor.constructor === Function); // true

但是当constructor遇到prototype时,有趣的事情就发生了。 我们知道每个函数都有一个默认的属性prototype,而这个prototype的constructor默认指向这个函数。如下例所示:

function Person(name) {
            this.name = name;
        };
        Person.prototype.getName = function() {
            return this.name;
        };
        var p = new Person("haorooms");

        console.log(p.constructor === Person);  // true
        console.log(Person.prototype.constructor === Person); // true
        // 将上两行代码合并就得到如下结果
        console.log(p.constructor.prototype.constructor === Person); // true

当时当我们重新定义函数的prototype时(注意:和上例的区别,这里不是修改而是覆盖), constructor的行为就有点奇怪了,如下示例:

function Person(name) {
            this.name = name;
        };
        Person.prototype = {
            getName: function() {
                return this.name;
            }
        };
        var p = new Person("haorooms");
        console.log(p.constructor === Person);  // false
        console.log(Person.prototype.constructor === Person); // false
        console.log(p.constructor.prototype.constructor === Person); // false

为什么呢? 原来是因为覆盖Person.prototype时,等价于进行如下代码操作:

Person.prototype = new Object({
            getName: function() {
                return this.name;
            }
        });

而constructor始终指向创建自身的构造函数,所以此时Person.prototype.constructor === Object,即是:

function Person(name) {
            this.name = name;
        };
        Person.prototype = {
            getName: function() {
                return this.name;
            }
        };
        var p = new Person("haorooms");
        console.log(p.constructor === Object);  // true
        console.log(Person.prototype.constructor === Object); // true
        console.log(p.constructor.prototype.constructor === Object); // true

怎么修正这种问题呢?方法也很简单,重新覆盖Person.prototype.constructor即可:

function Person(name) {
            this.name = name;
        };
        Person.prototype = {
            getName: function() {
                return this.name;
            }
        };
        Person.prototype.constructor = Person;
        var p = new Person("haorooms");
        console.log(p.constructor === Person);  // true
        console.log(Person.prototype.constructor === Person); // true
        console.log(p.constructor.prototype.constructor === Person); // true

也可以这么写:

function Person(name) {
            this.name = name;
        };
        Person.prototype = {
          constructor:Person,//指定constructor
            getName: function() {
                return this.name;
            }
        };

 

By柏小白

jquery中对象object循环遍历的方法

序言:

干货的文章收藏备用

前言

一个朋友问对象如何转为数组,当我问他为啥要转得时候,他告诉我,数组可以用js循环遍历,而对象则不可以。其实呢,对象同样可以循环遍历的啊。不用转换也可以循环!说明你对js或者jquery的某些操作不是很熟练!在这里我简单介绍一下!

案例

我们看如下对象:

var  data={
       张三:69,
       李四:72,
       王五:90,
       二麻子:88,
       前端博客:100,
      haorooms : 98,
      王大壮:99
}

假如上面是后台返回的一个key,一个是value的对象(这种对象相信大家经常遇到吧!),现在要把这个内容,循环绑定到一个表格中。有的朋友对对象的循环就不知道怎么操作了!今天我给大家介绍两个方法!

方法一:

用$.each的方式进行循环!

假如你不知道$.each的话,建议大家网上搜一搜。当然也可以搜索一下“jquery的$().each,$.each的区别”,关于他们的区别,我在这里就不详细介绍了。可能有的朋友$().each这个方式用的比较多,今天主要给大家介绍$.each。

$.each()可以遍历数组和对象。方式如下:

$.each([{“name”:”haorooms”,”email”:”bb@126.com”},{“name”:”qianduan”,”email”:”aa@hao.com”}],function(i,n)
{
alert(“索引:”+i,”对应值为:”+n.name);
});

也可以这么遍历:

var arr1 = [ “one”, “two”, “three”, “four”, “five” ];
$.each(arr1, function(){
alert(this);
});
输出:one   two  three  four   five

最爽的是可以遍历数组:

var obj =data;//上面复制的data
$.each(obj, function(key, val) {
alert(obj[key]);//可以输出成绩
console.log(key);//可以输出姓名
});

方法二:

用for in循环,可以遍历obj

对上面的对象,我们可以这么写来循环!

for(var i in data){
   console.dir(i);//输出姓名
   console.dir(data[i]);//输出分数
}

for in循环相信大家应该不陌生!for循环我们用到比较多的是for(var i=0;i<array.length;i++)这样,这个主要是针对数组来循环的。对于对象,我们通常用for in循环!

另外,假如我们遇到如下对象:

var  data={
       张三:69,
       李四:72,
       王五:90,
       二麻子:88,
       前端博客:100,
      haorooms : 98,
      王大壮:99
}

我们可以用data.haorooms得到98,但是我们用“data.前端博客”会报错,因此,在我们用汉字做key值的时候,选取的时候应该用data[“前端博客”],这种方式来选择,不要再用点号了。

好,今天就到这里,欢迎大家留言指正!

By柏小白

jquery属性的相关js实现方法收集

今天网上发现了一篇文章,《jquery属性的相关js实现方法》 感觉收藏了会有需要,只要不被挤到地铁玻璃上巴起,我想手机拿着对比对比,

Read More