Be a Pure Person, Enjoy a Simple Life

02月 05

HTML META 那些事

作为一个苦逼的前端,移动设备的铺天盖地的涌来,html页面head之间的那些优化,你是不是还仅仅只惦记着关键字神马的呢?酱紫很容易out哦~。真是不整不知道一整吓一跳,本文整理一些常用的meta标签,与诸君共览:

<!DOCTYPE html><!-- 使用 HTML5 doctype,不区分大小写 注意:doctype前千万必要加注释神马的,ie会强制quirk模式 -->
<html lang="zh-cmn-Hans"> <!-- 更加标准的 lang 属性写法 http://zhi.hu/XyIa -->
<head>
    <!-- 声明文档使用的字符编码 -->
    <meta charset='utf-8'>
    <!-- 优先使用 IE 最新版本和 Chrome -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <!-- 启用360浏览器的极速模式(webkit) -->
    <meta name="renderer" content="webkit">
    <!-- 页面描述 -->
    <meta name="description" content="不超过150个字符"/>
    <!-- 页面关键词 -->
    <meta name="keywords" content=""/>
    <!-- 网页作者 -->
    <meta name="author" content="name, email@gmail.com"/>
    <!-- 搜索引擎抓取 -->
    <meta name="robots" content="index,follow"/>
    <!-- 为移动设备添加 viewport -->
    <meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no">
    <!-- `width=device-width` 会导致 iPhone 5 添加到主屏后以 WebApp 全屏模式打开页面时出现黑边 http://bigc.at/ios-webapp-viewport-meta.orz -->
 
    <!-- iOS 设备 begin -->
    <meta name="apple-mobile-web-app-title" content="标题">
    <!-- 添加到主屏后的标题(iOS 6 新增) -->
    <meta name="apple-mobile-web-app-capable" content="yes"/>
    <!-- 是否启用 WebApp 全屏模式,删除苹果默认的工具栏和菜单栏 -->
 
    <meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">
    <!-- 添加智能 App 广告条 Smart App Banner(iOS 6+ Safari) -->
    <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
    <!-- 设置苹果工具栏颜色 -->
    <meta name="format-detection" content="telphone=no, email=no"/>
    <!-- 忽略页面中的数字识别为电话,忽略email识别 -->
    <!-- 启用360浏览器的极速模式(webkit) -->
    <meta name="renderer" content="webkit">
    <!-- 避免IE使用兼容模式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- 不让百度转码 -->
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 -->
    <meta name="HandheldFriendly" content="true">
    <!-- 微软的老式浏览器 -->
    <meta name="MobileOptimized" content="320">
    <!-- uc强制竖屏 -->
    <meta name="screen-orientation" content="portrait">
    <!-- QQ强制竖屏 -->
    <meta name="x5-orientation" content="portrait">
    <!-- UC强制全屏 -->
    <meta name="full-screen" content="yes">
    <!-- QQ强制全屏 -->
    <meta name="x5-fullscreen" content="true">
    <!-- UC应用模式 -->
    <meta name="browsermode" content="application">
    <!-- QQ应用模式 -->
    <meta name="x5-page-mode" content="app">
    <!-- windows phone 点击无高光 -->
    <meta name="msapplication-tap-highlight" content="no">
    <!-- iOS 图标 begin -->
    <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-57x57-precomposed.png"/>
    <!-- iPhone 和 iTouch,默认 57x57 像素,必须有 -->
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/apple-touch-icon-114x114-precomposed.png"/>
    <!-- Retina iPhone 和 Retina iTouch,114x114 像素,可以没有,但推荐有 -->
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144x144-precomposed.png"/>
    <!-- Retina iPad,144x144 像素,可以没有,但推荐有 -->
    <!-- iOS 图标 end -->
 
    <!-- iOS 启动画面 begin -->
    <link rel="apple-touch-startup-image" sizes="768x1004" href="/splash-screen-768x1004.png"/>
    <!-- iPad 竖屏 768 x 1004(标准分辨率) -->
    <link rel="apple-touch-startup-image" sizes="1536x2008" href="/splash-screen-1536x2008.png"/>
    <!-- iPad 竖屏 1536x2008(Retina) -->
    <link rel="apple-touch-startup-image" sizes="1024x748" href="/Default-Portrait-1024x748.png"/>
    <!-- iPad 横屏 1024x748(标准分辨率) -->
    <link rel="apple-touch-startup-image" sizes="2048x1496" href="/splash-screen-2048x1496.png"/>
    <!-- iPad 横屏 2048x1496(Retina) -->
 
    <link rel="apple-touch-startup-image" href="/splash-screen-320x480.png"/>
    <!-- iPhone/iPod Touch 竖屏 320x480 (标准分辨率) -->
    <link rel="apple-touch-startup-image" sizes="640x960" href="/splash-screen-640x960.png"/>
    <!-- iPhone/iPod Touch 竖屏 640x960 (Retina) -->
    <link rel="apple-touch-startup-image" sizes="640x1136" href="/splash-screen-640x1136.png"/>
    <!-- iPhone 5/iPod Touch 5 竖屏 640x1136 (Retina) -->
    <!-- iOS 启动画面 end -->
 
    <!-- iOS 设备 end -->
    <meta name="msapplication-TileColor" content="#000"/>
    <!-- Windows 8 磁贴颜色 -->
    <meta name="msapplication-TileImage" content="icon.png"/>
    <!-- Windows 8 磁贴图标 -->
 
    <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"/>
    <!-- 添加 RSS 订阅 -->
    <link rel="shortcut icon" type="image/ico" href="/favicon.ico"/>
    <!-- 添加 favicon icon -->

    <!-- sns 社交标签 begin -->
    <!-- 参考微博API -->
    <meta property="og:type" content="类型" />
    <meta property="og:url" content="URL地址" />
    <meta property="og:title" content="标题" />
    <meta property="og:image" content="图片" />
    <meta property="og:description" content="描述" />
    <!-- sns 社交标签 end -->
 
    <title>标题</title>
</head>
01月 20

this杂谈

以下内容全是掏箱底的干货(大牛那里复制来的),部分我也没有掌握。

全局this

浏览器宿主的全局环境中,this指的是window对象。

<script type="text/javascript">
    console.log(this === window); //true
</script>

浏览器中在全局环境下,使用var声明变量其实就是赋值给this或window。

<script type="text/javascript">
    var foo = "bar";
    console.log(this.foo); //logs "bar"
    console.log(window.foo); //logs "bar"
</script>

任何情况下,创建变量时没有使用var或者let(ECMAScript 6),也是在操作全局this。

<script type="text/javascript">
    foo = "bar";
    function testThis() {
      foo = "foo";
    }
    console.log(this.foo); //logs "bar"
    testThis();
    console.log(this.foo); //logs "foo"
</script>

Node命令行(REPL)中,this是全局命名空间。可以通过global来访问。

> this
{ ArrayBuffer: [Function: ArrayBuffer],
  Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
  Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
  ...
> global === this
true

在Node环境里执行的JS脚本中,this其实是个空对象,有别于global。

test.js
console.log(this);
console.log(this === global);

$ node test.js
{}
false

当尝试在Node中执行JS脚本时,脚本中全局作用域中的var并不会将变量赋值给全局this,这与在浏览器中是不一样的。

test.js
var foo = "bar";
console.log(this.foo);

$ node test.js
undefined

…但在命令行里进行求值却会赋值到this身上。

> var foo = "bar";
> this.foo
bar
> global.foo
bar

在Node里执行的脚本中,创建变量时没带var或let关键字,会赋值给全局的global但不是this(译注:上面已经提到this和global不是同一个对象,所以这里就不奇怪了)。

test.js
foo = "bar";
console.log(this.foo);
console.log(global.foo);
$ node test.js
undefined
bar

但在Node命令行里,就会赋值给两者了。

译注:简单来说,Node脚本中global和this是区别对待的,而Node命令行中,两者可等效为同一对象。

函数或方法里的this

除了DOM的事件回调或者提供了执行上下文(后面会提到)的情况,函数正常被调用(不带new)时,里面的this指向的是全局作用域。

<script type="text/javascript">
    foo = "bar";
    function testThis() {
      this.foo = "foo";
    }
    console.log(this.foo); //logs "bar"
    testThis();
    console.log(this.foo); //logs "foo"
</script>

test.js

foo = "bar";
function testThis () {
  this.foo = "foo";
}
console.log(global.foo);
testThis();
console.log(global.foo);
$ node test.js
bar
foo

还有个例外,就是使用了"use strict";。此时this是undefined。

<script type="text/javascript">
    foo = "bar";
    function testThis() {
      "use strict";
      this.foo = "foo";
    }
    console.log(this.foo); //logs "bar"
    testThis();  //Uncaught TypeError: Cannot set property 'foo' of undefined 
</script>

当用调用函数时使用了new关键字,此刻this指代一个新的上下文,不再指向全局this。

<script type="text/javascript">
    foo = "bar";
    function testThis() {
      this.foo = "foo";
    }
    console.log(this.foo); //logs "bar"
    new testThis();
    console.log(this.foo); //logs "bar"
    console.log(new testThis().foo); //logs "foo"
</script>

通常我将这个新的上下文称作实例。

原型中的this

函数创建后其实以一个函数对象的形式存在着。既然是对象,则自动获得了一个叫做prototype的属性,可以自由地对这个属性进行赋值。当配合new关键字来调用一个函数创建实例后,此刻便能直接访问到原型身上的值。

function Thing() {
    console.log(this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo);  //logs "bar"

当通过new的方式创建了多个实例后,他们会共用一个原型。比如,每个实例的this.foo都返回相同的值,直到this.foo被重写。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo);
}
Thing.prototype.setFoo = function (newFoo) {
    this.foo = newFoo;
}
var thing1 = new Thing();
var thing2 = new Thing();
thing1.logFoo(); //logs "bar"
thing2.logFoo(); //logs "bar"
thing1.setFoo("foo");
thing1.logFoo(); //logs "foo";
thing2.logFoo(); //logs "bar";
thing2.foo = "foobar";
thing1.logFoo(); //logs "foo";
thing2.logFoo(); //logs "foobar";

在实例中,this是个特殊的对象,而this自身其实只是个关键字。你可以把this想象成在实例中获取原型值的一种途径,同时对this赋值又会覆盖原型上的值。完全可以将新增的值从原型中删除从而将原型还原为初始状态。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo);
}
Thing.prototype.setFoo = function (newFoo) {
    this.foo = newFoo;
}
Thing.prototype.deleteFoo = function () {
    delete this.foo;
}
var thing = new Thing();
thing.setFoo("foo");
thing.logFoo(); //logs "foo";
thing.deleteFoo();
thing.logFoo(); //logs "bar";
thing.foo = "foobar";
thing.logFoo(); //logs "foobar";
delete thing.foo;
thing.logFoo(); //logs "bar";

…或者不通过实例,直接操作函数的原型。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo, Thing.prototype.foo);
}
var thing = new Thing();
thing.foo = "foo";
thing.logFoo(); //logs "foo bar";

同一函数创建的所有实例均共享一个原型。如果你给原型赋值了一个数组,那么所有实例都能获取到这个数组。除非你在某个实例中对其进行了重写,实事上是进行了覆盖。

function Thing() {
}
Thing.prototype.things = [];
var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing2.things); //logs ["foo"]

通常上面的做法是不正确的(译注:改变thing1的同时也影响了thing2)。如果你想每个实例互不影响,那么请在函数里创建这些值,而不是在原型上。

多个函数可以形成原型链,这样this便会在原型链上逐步往上找直到找到你想引用的值。

function Thing1() {
}
Thing1.prototype.foo = "bar";
function Thing2() {
}
Thing2.prototype = new Thing1();
var thing = new Thing2();
console.log(thing.foo); //logs "bar"

很多人便是利用这个特性在JS中模拟经典的对象继承。
注意原型链底层函数中对this的操作会覆盖上层的值。

function Thing1() {
}
Thing1.prototype.foo = "bar";
function Thing2() {
    this.foo = "foo";
}
Thing2.prototype = new Thing1();
function Thing3() {
}
Thing3.prototype = new Thing2();
var thing = new Thing3();
console.log(thing.foo); //logs "foo"

我习惯将赋值到原型上的函数称作方法。上面某些地方便使用了方法这样的字眼,比如logFoo方法。这些方法中的this同样具有在原型链上查找引用的魔力。通常将最初用来创建实例的函数称作构造函数。
原型链方法中的this是从实例中的this开始住上查找整个原型链的。也就是说,如果原型链中某个地方直接对this进行赋值覆盖了某个变量,那么我们拿到 的是覆盖后的值。

function Thing1() {
}
Thing1.prototype.foo = "bar";
Thing1.prototype.logFoo = function () {
    console.log(this.foo);
}
function Thing2() {
    this.foo = "foo";
}
Thing2.prototype = new Thing1();
var thing = new Thing2();
thing.logFoo(); //logs "foo";

在JavaScript中,函数可以嵌套函数,也就是你可以在函数里面继续定义函数。但内层函数是通过闭包获取外层函数里定义的变量值的,而不是直接继承this。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    var info = "attempting to log this.foo:";
    function doIt() {
        console.log(info, this.foo);
    }
    doIt();
}
var thing = new Thing();
thing.logFoo();  //logs "attempting to log this.foo: undefined"

上面示例中,doIt 函数中的this指代是全局作用域或者是undefined如果使用了"use strict";声明的话。对于很多新手来说,理解这点是非常头疼的。
还有更奇葩的。把实例的方法作为参数传递时,实例是不会跟着过去的。也就是说,此时方法中的this在调用时指向的是全局this或者是undefined在声明了"use strict";时。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {  
    console.log(this.foo);   
}
function doIt(method) {
    method();
}
var thing = new Thing();
thing.logFoo(); //logs "bar"
doIt(thing.logFoo); //logs undefined

所以很多人习惯将this缓存起来,用个叫self或者其他什么的变量来保存,以将外层与内层的this区分开来。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    var self = this;
    var info = "attempting to log this.foo:";
    function doIt() {
        console.log(info, self.foo);
    }
    doIt();
}
var thing = new Thing();
thing.logFoo();  //logs "attempting to log this.foo: bar"

…但上面的方式不是万能的,在将方法做为参数传递时,就不起作用了。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () { 
    var self = this;
    function doIt() {
        console.log(self.foo);
    }
    doIt();
}
function doItIndirectly(method) {
    method();
}
var thing = new Thing();
thing.logFoo(); //logs "bar"
doItIndirectly(thing.logFoo); //logs undefined

解决方法就是传递的时候使用bind方法显示指明上下文,bind方法是所有函数或方法都具有的。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () { 
    console.log(this.foo);
}
function doIt(method) {
    method();
}
var thing = new Thing();
doIt(thing.logFoo.bind(thing)); //logs bar

同时也可以使用apply或call 来调用该方法或函数,让它在一个新的上下文中执行。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () { 
    function doIt() {
        console.log(this.foo);
    }
    doIt.apply(this);
}
function doItIndirectly(method) {
    method();
}
var thing = new Thing();
doItIndirectly(thing.logFoo.bind(thing)); //logs bar

使用bind可以任意改变函数或方法的执行上下文,即使它没有被绑定到一个实例的原型上。

function Thing() {
}
Thing.prototype.foo = "bar";
function logFoo(aStr) {
    console.log(aStr, this.foo);
}
var thing = new Thing();
logFoo.bind(thing)("using bind"); //logs "using bind bar"
logFoo.apply(thing, ["using apply"]); //logs "using apply bar"
logFoo.call(thing, "using call"); //logs "using call bar"
logFoo("using nothing"); //logs "using nothing undefined"

避免在构造函数中返回作何东西,因为返回的东西可能覆盖本来该返回的实例。

function Thing() {
    return {};
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo);
}
var thing = new Thing();
thing.logFoo(); //Uncaught TypeError: undefined is not a function

但,如果你在构造函数里返回的是个原始值比如字符串或者数字什么的,上面的错误就不会发生了,返回语句将被忽略。所以最好别在一个将要通过new来调用的构造函数中返回作何东西,即使你是清醒的。如果你想实现工厂模式,那么请用一个函数来创建实例,并且不通过new来调用。当然这只是个人建议。
诚然,你也可以使用Object.create从而避免使用new。这样也能创建一个实例。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo);
}
var thing =  Object.create(Thing.prototype);
thing.logFoo(); //logs "bar"

这种方式不会调用该构造函数。

function Thing() {
    this.foo = "foo";
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo);
}
var thing =  Object.create(Thing.prototype);
thing.logFoo(); //logs "bar"

正因为Object.create没有调用构造函数,这在当你想实现一个继承时是非常有用的,随后你可能想要重写构造函数。

function Thing1() {
    this.foo = "foo";
}
Thing1.prototype.foo = "bar";
function Thing2() {
    this.logFoo(); //logs "bar"
    Thing1.apply(this);
    this.logFoo(); //logs "foo"
}
Thing2.prototype = Object.create(Thing1.prototype);
Thing2.prototype.logFoo = function () {
    console.log(this.foo);
}
var thing = new Thing2();

对象中的this

可以在对象的任何方法中使用this来访问该对象的属性。这与用new得到的实例是不一样的。

var obj = {
    foo: "bar",
    logFoo: function () {
        console.log(this.foo);
    }
};
obj.logFoo(); //logs "bar"

注意这里并没有使用new,也没有用Object.create,更没有函数的调用来创建对象。也可以将函数绑定到对象,就好像这个对象是一个实例一样。

var obj = {
    foo: "bar"
};
function logFoo() {
    console.log(this.foo);
}
logFoo.apply(obj); //logs "bar"

此时使用this没有向上查找原型链的复杂工序。通过this所拿到的只是该对象身上的属性而以。

var obj = {
    foo: "bar",
    deeper: {
        logFoo: function () {
            console.log(this.foo);
        }
    }
};
obj.deeper.logFoo(); //logs undefined

也可以不通过this,直接访问对象的属性。

var obj = {
    foo: "bar",
    deeper: {
        logFoo: function () {
            console.log(obj.foo);
        }
    }
};
obj.deeper.logFoo(); //logs "bar"

DOM 事件回调中的this

在DOM事件的处理函数中,this指代的是被绑定该事件的DOM元素。

function Listener() {
    document.getElementById("foo").addEventListener("click",
       this.handleClick);
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs "<div id="foo"></div>"
}
var listener = new Listener();
document.getElementById("foo").click();

…除非你通过bind人为改变了事件处理器的执行上下文。

function Listener() {
    document.getElementById("foo").addEventListener("click", 
        this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs Listener {handleClick: function}
}
var listener = new Listener();
document.getElementById("foo").click();

HTML中的this

HTML标签的属性中是可能写JS的,这种情况下this指代该HTML元素。

<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>

重写this

无法重写this,因为它是一个关键字。

function test () {
    var this = {};  // Uncaught SyntaxError: Unexpected token this 
}

eval中的this

eval 中也可以正确获取当前的 this。

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    eval("console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();

这里存在安全隐患。最好的办法就是避免使用eval。
使用Function关键字创建的函数也可以获取this:

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = new Function("console.log(this.foo);");
var thing = new Thing();
thing.logFoo(); //logs "bar"

使用with时的this

使用with可以将this人为添加到当前执行环境中而不需要显示地引用this。

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    with (this) {
        console.log(foo);
        foo = "foo";
    }
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"

正如很多人认为的那样,使用with是不好的,因为会产生歧义。

jQuery中的this

一如HTML DOM元素的事件回调,jQuery库中大多地方的this也是指代的DOM元素。页面上的事件回调和一些便利的静态方法比如$.each 都是这样的。

<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
    this.click();
});
</script

传递 this

如果你用过underscore.js或者lo-dash你便知道,这两个库中很多方法你可以传递一个参数来显示指定执行的上下文。比如_.each。自ECMAScript 5 标准后,一些原生的JS方法也允许传递上下文,比如forEach。事实上,上文提到的bind,apply还有call 已经给我们手动指定函数执行上下文的能力了。

function Thing(type) {
    this.type = type;
}
Thing.prototype.log = function (thing) {
    console.log(this.type, thing);
}
Thing.prototype.logThings = function (arr) {
   arr.forEach(this.log, this); // logs "fruit apples..."
   _.each(arr, this.log, this); //logs "fruit apples..."
}
var thing = new Thing("fruit");
thing.logThings(["apples", "oranges", "strawberries", "bananas"]);

这样可以使得代码简洁些,不用层层嵌套bind,也不用不断地缓存this。

12月 02

各大平台免费接口

  电商接口

  京东获取单个商品价格接口:

  

http://p.3.cn/prices/mgets?skuIds=J_商品ID&type=1

  ps:商品ID这么获取:http://item.jd.com/954086.html

  物流接口

  快递接口:
  

http://www.kuaidi100.com/query?type=快递公司代号&postid=快递单号

  ps:快递公司编码:申通=”shentong” EMS=”ems” 顺丰=”shunfeng” 圆通=”yuantong” 中通=”zhongtong” 韵达=”yunda” 天天=”tiantian” 汇通=”huitongkuaidi” 全峰=”quanfengkuaidi” 德邦=”debangwuliu” 宅急送=”zhaijisong”

  

谷歌接口

  FeedXml转json接口:

  

http://ajax.googleapis.com/ajax/services/feed/load?q=Feed地址&v=1.0

  备选参数:callback:&callback=foo就会在json外面嵌套foo({})方便做jsonp使用。

  备选参数:n:返回多少条记录。

  天气接口

  百度接口:

  

http://api.map.baidu.com/telematics/v3/weather?location=嘉兴output=json&ak=5slgyqGDENN7Sy7pw29IUvrZ

  location:城市名或经纬度 ak:开发者密钥 output:默认xml

  气象局接口:

  

http://m.weather.com.cn/data/101010100.html

  音乐接口

  虾米接口

  

http://kuang.xiami.com/app/nineteen/search/key/歌曲名称/diandian/1/page/歌曲当前页?_=当前毫秒&callback=getXiamiData

  QQ空间音乐接口

  

http://qzone-music.qq.com/fcg-bin/cgi_playlist_xml.fcg?uin=QQ号码&json=1&g_tk=1916754934

  QQ空间收藏音乐接口

  

http://qzone-music.qq.com/fcg-bin/fcg_music_fav_getinfo.fcg?dirinfo=0&dirid=1&uin=QQ号&p=0.519638272547262&g_tk=1284234856

  多米音乐接口

  

http://v5.pc.duomi.com/search-ajaxsearch-searchall?kw=关键字&pi=页码&pz=每页音乐数

  soso接口

  

http://cgi.music.soso.com/fcgi-bin/fcg_search_xmldata.q?source=10&w=关键字&perpage=1&ie=utf-8

  视频接口

  土豆接口

  

http://api.tudou.com/v3/gw?method=album.item.get&amp;appKey=Appkey&format=json&albumId=视频剧集ID&pageNo=当前页&pageSize=每页显示

  地图接口

  阿里云根据地区名获取经纬度接口

  

http://gc.ditu.aliyun.com/geocoding?a=苏州市

  参数解释: 纬度,经度type 001 (100代表道路,010代表POI,001代表门址,111可以同时显示前三项)

  阿里云根据经纬度获取地区名接口

  

http://gc.ditu.aliyun.com/regeocoding?l=39.938133,116.395739&type=001

  IP接口

  新浪接口(ip值为空的时候 获取本地的)

  

http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=218.4.255.255

  淘宝接口
  

http://ip.taobao.com/service/getIpInfo.php?ip=63.223.108.42

  手机信息查询接口

  淘宝网接口

  

http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=手机号

  拍拍接口
  

http://virtual.paipai.com/extinfo/GetMobileProductInfo?mobile=手机号&amount=10000&callname=getPhoneNumInfoExtCallback

  百付宝接口

  

https://www.baifubao.com/callback?cmd=1059&callback=phone&phone=手机号

  115接口

  

http://cz.115.com/?ct=index&ac=get_mobile_local&callback=jsonp1333962541001&mobile=手机号

  有道接口

  

http://www.youdao.com/smartresult-xml/search.s?jsFlag=true&type=mobile&q=手机号

  手机在线接口

  

http://api.showji.com/Locating/www.showji.com.aspx?m=手机号&output=json&callback=querycallback

  视频信息接口

  优酷

  

http://v.youku.com/player/getPlayList/VideoIDS/视频ID

(比如 http://v.youku.com/v_show/id_XNTQxNzc4ODg0.html的ID就是XNTQxNzc4ODg0)

  翻译、词典接口

  腾讯

  

http://dict.qq.com/dict?q=词语

  腾讯的部分接口

  获取QQ昵称和用户头像

  

http://r.qzone.qq.com/cgi-bin/user/cgi_personal_card?uin=QQ
08月 26

我把ubuntu的密码忘了!

哎~
好久不用,把ubuntu的密码给忘了,啷个子办呢?!

你是不是也有同样的烦恼呢?
不用着急,不用着急,一起跟我做...

Step 1:
开机,狂按ESC,有木有看到这个界面?
Step 1
选中 高级模式,是的 带*好的那个,回车;

Step 2:
进入Recovery Mode,就是下面这个样子滴;
Recovery Mode
继续回车;

Step 3:
有木有看到下面这个界面,
请输入图片描述
不用犹豫,选择 root的那个,回车;

Step 4:
有木有看到底部有一个 root@ubuntu:~#;

输入 “mount -o rw,remount /”,一定不要漏了哦,不酱紫的话,你会改~不~了~的。。。。因为它是Read-only的;
然后呢,
输入: passwd jushu;好吧 junshu是我的用户名,你得换成你自己的。
回车吧,接下来应该~你懂的^_^

纳尼?你忘了你的用户名了?
试试这个:cat /etc/passwd 有木有看到你熟悉的那个名字~

好了,就酱紫了,这事儿不能说得再细了。

08月 22

js 与或运算符 || && 妙用

var add_level = 0; 
switch(add_step){ 
case 5 : add_level = 1; 
break; 
case 10 : add_level = 2; 
break; 
case 12 : add_level = 3; 
break; 
case 15 : add_level = 4; 
break; 
default : add_level = 0; 
break; 

可以写成:

 var add_level = (add_step==5 && 1) || (add_step==10 && 2) || (add_step==12 && 3) || (add_step==15 && 4) || 0; 

var add_level={'5':1,'10':2,'12':3,'15':4}[add_step] || 0; 

巧用&&

if(a >=5){ 
alert("你好"); 
} 

可以写成:

a >= 5 && alert("你好");
07月 04

关于页面渲染的一些记录

浏览器是怎样渲染一个页面的?

从浏览器渲染页面的大概过程开始说起:

  1. 由从服务器接收到的 HTML 形成 DOM(文档对象模型)。
  2. 样式被加载和解析,形成 CSSOM(CSS 对象模型)。
  3. 紧接着 DOM 和 CSSOM 创建了一个渲染树,这个渲染树是一些被渲染对象的集合( Webkit 分别叫它们”renderer”和”render object”,而在Gecko 引擎中叫”frame”)。除了不可见的元素(比如 head 标签和一些有 display:none 属性的元素),渲染树映射了 DOM 的结构。在渲染树中,每一个文本字符串都被当做一个独立的 renderer。每个渲染对象都包含了与之对应的计算过样式的DOM 对象(或者一个文本块)。换句话说,渲染树描述了 DOM 的直观的表现形式。
  4. 对每个渲染元素来说,它的坐标是经过计算的,这被叫做“布局(layout)”。浏览器使用一种只需要一次处理的“流方法”来布局所有元素(tables需要多次处理)。
  5. 最后,将布局显示在浏览器窗口中,这个过程叫做“绘制(painting)”。

重绘

当在页面上修改了一些不需要改变定位的样式的时候(比如background-color,border-color,visibility),浏览器只会将新的样式重新绘制给元素(这就叫一次“重绘”或者“重新定义样式”)。

重排

当页面上的改变影响了文档内容、结构或者元素定位时,就会发生重排(或称“重新布局”)。重排通常由以下改变触发:

  • DOM 操作(如元素增、删、改或者改变元素顺序)。
  • 内容的改变,包括 Form 表单中文字的变化。
  • 计算或改变 CSS 属性。
  • 增加或删除一个样式表。
  • 改变”class”属性。
  • 浏览器窗口的操作(改变大小、滚动窗口)。
  • 激活伪类(如:hover状态)。

浏览器如何优化渲染?

浏览器尽最大努力限制重排的过程仅覆盖已更改的元素的区域。举个例子,一个 position 为 absolue 或 fixed 的元素的大小变化只影响它自身和子孙元素,而对一个 position 为 static 的元素做同样的操作就会引起所有它后面元素的重排。

另一个优化就是当运行一段Jjavascript 代码的时候,浏览器会将一些修改缓存起来,然后当代码执行的时候,一次性的将这些修改执行。举例来说,这段代码会触发一次重绘和一次重排:

var $body = $('body'); 
$body.css('padding', '1px'); // 重排, 重绘 
$body.css('color', 'red'); // 重绘 
$body.css('margin', '2px'); // 重排, 重绘 
// 实际上只有一次重排和重绘被执行。

如上面所说,访问一个元素的属性会进行一次强制重排。如果我们给上面的代码加上一行读取元素属性的代码,这个情况就会出现:

var $body = $('body'); 
$body.css('padding', '1px'); 
$body.css('padding'); // 这里读取了一次元素的属性,一次强制重排就会发生。 
$body.css('color', 'red'); 
$body.css('margin', '2px');

上面这段代码的结果就是,进行了两次重排。因此,为了提高性能,你应该讲读取元素属性的代码组织在一起(细节的例子可以看JSBin上的代码)。

有一种情况是必须触发一次强制重排的。例如:给元素改变同一个属性两次(比如margin-left),一开始设置100px,没有动画,然后通过动画的形式将值改为50px。具体可以看例子,当然,我在这里会讲更多的细节。

我们从一个有transition的CSS class开始:

.has-transition {
   -webkit-transition: margin-left 1s ease-out;
      -moz-transition: margin-left 1s ease-out;
        -o-transition: margin-left 1s ease-out;
           transition: margin-left 1s ease-out;
}

然后进行实现:

//我们的元素默认有"has-transition"属性 
var $targetElem = $('#targetElemId');

//删除包含transition的class 
$targetElem.removeClass('has-transition');

// 当包含transition的class已经没了的时候,改变元素属性 
$targetElem.css('margin-left', 100);

// 再将包含transition的class添加回来 
$targetElem.addClass('has-transition');

// 改变元素属性 
$targetElem.css('margin-left', 50);

上面的实现没有按照期望的运行。所有的修改都被浏览器缓存了,只在上面这段代码的最后才会执行。我们需要的是一次强制重排,我们可以通过进行以下修改来实现:

//删除包含transition的class 
$(this).removeClass('has-transition');

// 改变元素属性 
$(this).css('margin-left', 100);

//触发一次强制重排,从而使变化了的class或属性能够立即执行。 
$(this)[0].offsetHeight; // offsetHeight仅仅是个例子,其他的属性也可以奏效。

// 再将包含transition的class添加回来 
$(this).addClass('has-transition');

// 改变元素属性 
$(this).css('margin-left', 50);

现在这段代码如我们所期望的运行了。

实际的优化建议

汇总了一些有用的信息,我建议以下几点:

  1. 创建合法的 HTML 和 CSS ,别忘了制定文件编码,Style 应该写在 head 标签中,script 标签应该加载 body标签结束的位置。
  2. 试着简化和优化 CSS 选择器(这个优化点被大多数使用 CSS 预处理器的开发者忽略了)。将嵌套层数控制在最小。以下是CSS选择器的性能排行(从最快的开始):
    1.ID选择器:#id

2.class选择器: .class
3.标签: div
4.相邻的兄弟元素:a + i
5.父元素选择器: ul > li
6.通配符选择器: *
7.伪类和伪元素: a:hover,你应该记住浏览器处理选择器是从右向左的,这也就是为什么最右面的选择器会更快——#id或.class。

div * {...} // bad
.list li {...} // bad
.list-item {...} // good
'#'list .list-item {...} // good

在你的脚本中,尽可能的减少 DOM 的操作。把所有东西都缓存起来,包括属性和对象(如果它可被重复使用)。进行复杂的操作的时候,最好操作一个“离线”的元素(“离线”元素的意思是与 DOM 对象分开、仅存在内存中的元素),然后将这个元素插入到 DOM 中。

如果你使用 jQuery,遵循jQuery 选择器最佳实践

要改变元素的样式,修改“class”属性是最高效的方式之一。你要改变 DOM 树的层次越深,这一条就越高效(这也有助于将表现和逻辑分开)。

尽可能的只对 position 为 absolute 或 fix 的元素做动画。

当滚动时禁用一些复杂的 :hover 动画是一个很好的主意(例如,给 body 标签加一个 no-hover 的 class)

05月 29

据说google换logo了

据说google换logo了,尼玛,这简直是大找茬啊,愣是看了半年没发现区别,还好哥有伟大的ps
旧Logo
旧Logo
新Logo
新Logo

真相就在这里
请输入图片描述

谷歌是有多无聊啊。。。。。。

04月 11

关于js冒泡的一些玩意儿

什么是冒泡:
以点击事件为例,就是点击一个子元素,同时也把这个元素的父元素的点击事件触发了。
Linke this:

<div id="outer">
    <div id="inter"></div>
</div>
//JS:
$("#outer").click(function(){
    alert("outer");
})
$("#inter").click(function(){
    alert("inter");
})

上面的代码中,点击"#inter",会先弹出"inter",紧接着会弹出"outer".
为什么我点击子元素“#inter”的事件却会触发父元素的事件?
这就是冒泡了,点击子元素,同时会触发父元素的事件。

是不是理解起来 So Easy 啦 ^.^

如何阻止冒泡:
要阻止冒泡,就要用到event.stopPropagation()方法:

//HTML:
<div id="outer">
    <div id="inter"></div>
</div>
//JS:
$("#outer").click(function(){
    alert("outer");
})
$("#inter").click(function(event){
    event.stopPropagation()
    alert("inter");
})

在点击子元素的事件上添加event.stopPropagation()方法,就能阻止向父元素冒泡。

================= 万恶的分割线 ===================

当然以上是正常情况,作为一个苦逼的前端开发,都知道有个特例的,那就是万恶的IE;
那么IE怎么处理呢。。。。

function show1(e){
        var ev = e || window.event;
        if (ev.stopPropagation) {
            ev.stopPropagation();
        }
        else if (window.event) {//IE
            window.event.cancelBubble = true;//IE
        }
}

window.event是IE中的属性,如果是IE,就执行window.event.cancelBubble = true;来阻止冒泡。

04月 04

Javascript绝句欣赏

  1. 取整同时转成数值型:

    '10.567890'|0
    

结果: 10

'10.567890'^0

结果: 10

-2.23456789|0

结果: -2

~~-2.23456789

结果: -2

  1. 日期转数值:

    var d = +new Date(); //1295698416792

  2. 类数组对象转数组:

    var arr = [].slice.call(arguments)

  3. 漂亮的随机码:

    Math.random().toString(16).substring(2); //14位
    Math.random().toString(36).substring(2); //11位

  4. 合并数组:

    var a = [1,2,3];
    var b = [4,5,6];
    Array.prototype.push.apply(a, b);
    uneval(a); //[1,2,3,4,5,6]

  5. 用0补全位数:

    function prefixInteger(num, length) {
    return (num / Math.pow(10, length)).toFixed(length).substr(2);
    }

  6. 交换值:

    a= b, b=a;

  7. 将一个数组插入另一个数组的指定位置:

    var a = [1,2,3,7,8,9];
    var b = [4,5,6];
    var insertIndex = 3;
    a.splice.apply(a, Array.concat(insertIndex, 0, b));
    // a: 1,2,3,4,5,6,7,8,9

  8. 删除数组元素:

    var a = [1,2,3,4,5];
    a.splice(3,1);

  9. 快速取数组最大和最小值

    Math.max.apply(Math, [1,2,3]) //3
    Math.min.apply(Math, [1,2,3]) //1

(出自http://ejohn.org/blog/fast-javascript-maxmin/)

  1. 条件判断:

    var a = b && 1;

相当于

if (b) {
  a = 1
}

var a = b || 1; 

相当于

if (b) {
  a = b;
} else {
  a = 1;
}
  1. 判断IE:

    var ie = /@cc_on !@/false;