特色文章

收集slidershare高质量的ppt

http://www.slideshare.net/rainoxu/javascript-5464018  javascript性能优化

http://www.slideshare.net/fool2fish/js-12953769 js高级技巧 demo在http://fool2fish.aliapp.com/js-senior-skill/index.html

http://www.slideshare.net/iddcn/ss-12153414 高粒度模块化前端开发

http://www.slideshare.net/kejun/ss-9015786 前端开发理论热点面对面

http://www.slideshare.net/firt/mobile-web-high-performance 高性能移动端开发(E文)

http://www.slideshare.net/nzakas/writing-efficient-javascript 高效率书写javascript

 教主的ES5演讲

http://v.youku.com/v_playlist/f15769239o1p4.html

http://v.youku.com/v_playlist/f15769239o1p5.html

http://v.youku.com/v_playlist/f15769239o1p6.html

 

 Real-Time Web实时信息流推送

http://www.docin.com/p-467150624.html

阿里巴巴adc  http://adc.alibabatech.org/  内有大量ppt

 

应用限流策略(待写)

令牌桶算法及解释

http://www.cnblogs.com/zhengyun_ustc/archive/2012/11/17/topic1.html

nodejs令牌桶实现

https://github.com/jhurliman/node-rate-limiter

走redis的

https://github.com/joshdevins/node-rate-limiter-proxy/blob/master/node-rate-limiter-proxy.js

https://github.com/ivolo/express-rate

https://github.com/ded/express-limiter

https://github.com/tj/node-ratelimiter

基于stream

https://github.com/einaros/ratelimit

强制限流

https://github.com/AdamPflug/express-brute

 

loopback的

http://strongloop.com/strongblog/node-js-loopback-api-gateway-sample-applications/

https://github.com/strongloop/loopback-gateway

基于ip

https://github.com/cloudkick/rate-limiter

nodejs应用安全方案

1.安全相关http头控制

X-XSS-Protection

http://wangye.org/blog/archives/596/

默认开启此头,提供配置关闭这个头,因为这个头可能会对页面内脚本造成影响。

X-Content-Type-Options:nosniff
默认开启 减少 MIME 类型的安全风险,主要防范MIME sniffing功能的跨站点脚本攻击 http://tech.hexun.com/2009-03-02/115137005.html
http://technet.microsoft.com/zh-cn/gg622941(v=vs.85)

X-Download-Options:noopen
默认开启,禁止浏览器打开下载的文件。让浏览器随便打开这些用户上载的文件,非常危险。http://www.cnblogs.com/kaneboy/archive/2011/05/16/2437077.html

X-Powered-By
为了隐藏服务器细节,防止针对性的漏洞攻击,默认设置为null。用户可以自定义。

X-Frame-Options 主要为了防止页面内嵌iframe造成攻击,为了避免影响页面其他需求, 提供三个属性可以让用户配置,DENY,SAMEORIGIN,ALLOW-FROM
https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options?redirectlocale=en-US&redirectslug=The_X-FRAME-OPTIONS_response_header

Strict-Transport-Security 主要为了使用户在使用http访问要求用https访问的网页时,自动跳转到http。

Access-Control-Allow-Origin
禁止使用*,限制在白名单内,且跨域请求必须经过审核才可以上线。

2.模板引擎层面控制

模版引擎默认转码。
提供七个工具函数做为输出转码工具:

HTML转义:escapeHtml

XML转义:escapeXml()

文本转义 escapeText

JS转义:escapeJs

URL转义:escapeUrl

URL安全转义:escapeSeUrl 转义时同时检查是否是安全url

JSON转义:escapeJson 对json的value进行html和javascript转义

3.应用层控制

重写redirect

加入白名单,若出现不良跳转(如攻击者构造url)一律block掉。

sla限流策略

对应用限制最大连接数,防止崩坏

禁止trace

关闭应用对trace方法的支持

crossdomain

对于涉及flash的站点,提供corssdomain文件,但是限制其访问的域
http://blog.csdn.net/summerhust/article/details/7721627

4.csrf攻击防御与jsonp安全策略

1、登陆状态下,所有请求默认强制校验cToken。可以绕过但是绕过之后,则强制检查请求Reffer是否在白名单中,也可以额外添加信任的域名。

2、对callback做长度(128字符)和字符([0-9a-zA-Z_])限制,对输出json数据过滤。 防止utf-7攻击,flash,xss。

3、ContentType标准化, json为application/json, jsonp为application/javascript。 应用层面已经实现并且挂载了nosniff

4、对jsonp输出内容前,加了2个\r\n。 配合防止utf-7,flash攻击。

5.CSP(Content Security Policy)

 

cors,postmessage,eventsource相关

http://www.ibm.com/developerworks/cn/web/1301_jiangjj_html5message/

https://developer.mozilla.org/zh-CN/docs/Server-sent_events/Using_server-sent_events

https://github.com/Yaffle/EventSource

 

ajax分段上传

http://www.atatech.org/article/detail/11502/0

 

cors

http://www.atatech.org/article/detail/9010/0

做真正的全栈开发工程师(1)

最近我厂的前后端分离非常火。很多同事也在研究。但事实上给我启发最大的是http://www.zhihu.com/question/23512853  这个问答第一个回答:

 

1,不可忽视的后端技术门槛
不能不提这茬,即便midway很务实的只挑选了视图层作为主攻方向,但不可避免的控制器层还会带进来大量技术问题需要解决,比如配管、部署、日志监控、运维工具、SOA、加解密、事务、缓存策略、消息队列、异步调用、安全问题,总有避不开的暗礁。对阿里目前的后端技术栈来说,这些技术背后是无数的系统和平台,缺一不可,midway目前还是个玩具。更何况nodejs/web framework本身都在飞速演变之中,ES5到ES6,技术特性变化剧烈。即便由前期探路者完成了基础设施建设,后期他人进入的学习成本也非常高。时间长了,前端工程师本身又自然会分化成纯前端和nodejs工程师,如此前后端天然又产生了隔阂,呵呵,分久必合,合久必分。

 

事实上阿里巴巴有非常多非常多的平台,但对于我这个前端工程师来讲,很多东西在我的知识体系内都无法理解。为了让自己真正能“进化”成一个有理想有抱负的工程师,我计划学习后端相关的内容。

1 日志解析  我来公司做的第一个项目就是基于日志解析出的结果来做的,但如何从海量的日志中解析出东西?

2 事务 事务这种东西应用在什么场景上?

3 消息队列,同事务

4 后端安全,如何保证服务器的稳定性?如何保证服务器在出错或者高并发之类不会挂掉?

5 监控 监控一个系统是否稳定,指标是什么?如何通过某种具体场景来检验/测试某系统的稳定性?

6 数据库操作  事务 脏读,不可重复读,幻读都怎样避免?

7 接口设计,如何设计一个优雅的restful接口?

8 多线程,多进程,多核。。

今天的收获 http://www.cnblogs.com/adforce/archive/2011/04/20/2021929.html

脏读、不可重复读 共享锁、悲观锁 和 事务五种隔离级别

浏览器缩放检测

测试代码

http://jsbin.com/dipijeqi/11

 

效果:

 

chrome

window.devicePixelRatio : 2  (准确)
screen.deviceXDPI / screen.logicalXDPI : NaN
window.outerWidth / window.innerWidth : 2
document.documentElement.offsetHeight / window.innerHeight : 0.020618556701030927 (有相关性)
window.top.outerWidth / window.top.innerWidth : 2

ff
window.devicePixelRatio : 1.5 (准确)
screen.deviceXDPI / screen.logicalXDPI : NaN
window.outerWidth / window.innerWidth : 1.0114583333333333
document.documentElement.offsetHeight / window.innerHeight : 0.023391812865497075  (有相关性)
window.top.outerWidth / window.top.innerWidth : 1.0114583333333333
ie 8
window.devicePixelRatio : undefined
screen.deviceXDPI / screen.logicalXDPI : 1.5416666666666667 (大致准确)
window.outerWidth / window.innerWidth : NaN
document.documentElement.offsetHeight / window.innerHeight : NaN
window.top.outerWidth / window.top.innerWidth : NaN

ie11
window.devicePixelRatio : 1.5 (准确)
screen.deviceXDPI / screen.logicalXDPI : 1.5
window.outerWidth / window.innerWidth : 1.0084033613445377
document.documentElement.offsetHeight / window.innerHeight : 0.02203856749311295 (有相关性)
window.top.outerWidth / window.top.innerWidth : 1.0084033613445377
ie10
window.devicePixelRatio : undefined
screen.deviceXDPI / screen.logicalXDPI : 1.5 (准确)
window.outerWidth / window.innerWidth : 1.0084033613445377
document.documentElement.offsetHeight / window.innerHeight : 1
window.top.outerWidth / window.top.innerWidth : 1.0084033613445377
ie9
window.devicePixelRatio : undefined
screen.deviceXDPI / screen.logicalXDPI : 1.5 (准确)
window.outerWidth / window.innerWidth : 1.0084033613445377
document.documentElement.offsetHeight / window.innerHeight : 1
window.top.outerWidth / window.top.innerWidth : 1.0084033613445377

360 6.3(完全没反应)

window.devicePixelRatio : undefined
screen.deviceXDPI / screen.logicalXDPI : 1
window.outerWidth / window.innerWidth : NaN
document.documentElement.offsetHeight / window.innerHeight : NaN
window.top.outerWidth / window.top.innerWidth : NaN

360极速浏览器
window.devicePixelRatio : 1
screen.deviceXDPI / screen.logicalXDPI : NaN
window.outerWidth / window.innerWidth : 1.5
document.documentElement.offsetHeight / window.innerHeight : 0.015267175572519083
window.top.outerWidth / window.top.innerWidth : 1.5(准确)

搜狗高速浏览器 (完全没反应)

window.devicePixelRatio : undefined
screen.deviceXDPI / screen.logicalXDPI : 1
window.outerWidth / window.innerWidth : NaN
document.documentElement.offsetHeight / window.innerHeight : NaN
window.top.outerWidth / window.top.innerWidth : NaN
淘宝浏览器

window.devicePixelRatio : 1
screen.deviceXDPI / screen.logicalXDPI : NaN
window.outerWidth / window.innerWidth : 2.0710059171597632  (大致准确)
document.documentElement.offsetHeight / window.innerHeight : 0.022988505747126436
window.top.outerWidth / window.top.innerWidth : 2.0710059171597632

 

在canvas中插入html(网页截图技术的实现)(翻译稿)

mdn上翻译的文章,里面其实涉及了非常多的知识,值得学习,这个技术也是一些在线截图工具的解决方案吧。

 

https://developer.mozilla.org/zh-CN/docs/HTML/Canvas/Drawing_DOM_objects_into_a_canvas

 

尽管不常见(出于安全考虑), 但是将DOM内容—比如HTML—绘制到画布中是有可能的. 这篇文章源自Robert O’Callahan的博客, 讲到如何有把握地, 安全地实现它, 并且按照规范来.

概览

你不能把HTML画到canvas上。相反,你需要使用一个SVG图像,其中包含你想要呈现的内容。可以使用<foreignobject> 元素包含HTML内容,之后把这个svg绘制到你的canvas中。

步骤

唯一真正棘手的事情——这可能是一个夸张——创建SVG图像。所有你需要做的是创建一个包含XML字符串的SVG,然后按照下面的步骤构造一个 Blob

  1. blob对象的媒体类型mime为 “image/svg+xml”.
  2.  <svg> 元素.
  3. 在svg元素中包含 <foreignobject> 元素.
  4. (格式化好的) HTML ,被包裹到<foreignobject>中.

By using a object URL as described above, we can inline our HTML instead of having to load it from an external source. You can, of course, use an external source if you prefer, as long as the origin is the same as the originating document.

如上所述通过使用一个object URL,我们可以内联HTML而不是从外部源加载它。当然,如果你喜欢你可以使用外部源,只要域与原始文件相同。

Example

<!DOCTYPE html>
<html>
<body>
<p><canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var data = "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +
             "<foreignObject width='100%' height='100%'>" +
               "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +
                 "<em>I</em> like <span style='color:white; text-shadow:0 0 2px blue;'>cheese</span>" +
               "</div>" +
             "</foreignObject>" +
           "</svg>";
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);
};
img.src = url;
</script>
</body>
</html>

 

例子的效果:

example.png

data变量设置了SVG图像的内容(这包括HTML)我们希望绘制到我们的canvas中。

通过调用 new Image()我们建立一个新的html <img> 元素,添加数据进去,指定一个object URL, 之后在图片onload的时候调用 drawImage() 来把图片绘制到画布中.

安全性

您可能想知道这种方式是否安全,担心canvas会读取敏感数据。答案是这样的:这个解决方案的实现依赖的SVG图像是非常严格的。SVG图像不允许加载任何外部资源,即使似乎来自同一个域。资源(如栅格图像(如JPEG图像)或<iframe>s 需要用 data: URIs来内联引入.

此外,你不能在一个SVG图像中引入脚本文件,所以没有从其他脚本访问DOM的风险,而且DOM元素在SVG图像中不能接收事件的输入,所以没有办法通过把隐私信息加载到一个表单控件(如一个文件的完整路径 <input> 元素)然后渲染出来,之后通过读取像素把这些信息取出。

访问过的链接风格并不应用于SVG图像中呈现的链接,所以历史信息也不能被检索,本地的主题也不呈现在SVG图像中,这使得它很难确定用户的平台。(这里的意思应该是windows跟mac风格吧)

生成的canvas元素是纯净的,意味着你可以通过调用 toBlob(function(blob){…})来返回canvas的blob ,或者 toDataURL()来返回 Base64-编码的 data: URI.

Testing origin from their containing documents.

绘制HTML

SVG必须是合法的XML,你需要解析并把HTML转为规范的符合格式的。下面的代码可以很方便的解析HTML

var doc = document.implementation.createHTMLDocument("");
doc.write(html);

// You must manually set the xmlns if you intend to immediately serialize the HTML
// document to a string as opposed to appending it to a <foreignObject> in the DOM
doc.documentElement.setAttribute("xmlns", doc.documentElement.namespaceURI);

// Get well-formed markup
html = (new XMLSerializer).serializeToString(doc);

 

See also

git如何处理别人的pull request及解决冲突

出过两次了,每次都查很多资料,太蛋疼,记录在此。

 

当你的项目比较牛逼的时候,有人给你贡献代码,但他修改的地方恰恰你前阵子也修改了,这样在github中就不能够自动merge了。

因此你需要手动去解决冲突。首先要在本机安装好命令行工具gitbash,之后用clone拉下你的项目,之后

按照以下命令输入

git checkout -b 某人-master master

git pull https//github.com/某人的/某项目的.git master

这时候命令行会提示你有冲突,冲突文件是啥,那如何解决冲突呢,很简单

在同步代码的过程中,git会自动检查冲突,并尝试进行**自动合并**。最好的情况应该是大家同时修改一个文件,但是大家修改的地方不同了。在这样的情况下,git会进行非冲突合并,这时,在调用 git pull 的时候,git会尝试进行非冲突合并。
而在合并过程中有冲突的时候, git 会把修改记录直接保存在文件中,让开发者判断文件如何解决合并。例如,在一个描述文件中同时修改了一句话,在合并的时候,git会这么做:

<<<<<<< HEAD
It's not a project cool enough for you to enjoy the code but a mix of my thoughts in the year 2012~2013. I didn't know where the project leads to. Hope it will became useful after practice.
=======
It's not a project cool enough for you to enjoy the code but it's a mix of my thoughts in the year 2012~2013. I didn't know where the project leads to. Hope it will became useful after practice.
>>>>>>> 2b41083cf969979d8e4a1eedc987976af544d129

即把两个更改都写在文件上,但是用=======来区别发生冲突的位置,在=======以上是 HEAD,即本地的代码;而=======以下则是来自远程的更改了。这个时候,你可以选择保留远程或本地的修改或者都不要(简单地说,把不需要的内容删除即可)。

 

也就是说我们把文件修改好后,把增加的那几行head >>><<<之类删掉就ok啦。之后冲突修改完毕,我们继续输入

git commit -a //把修改提交到这个人的分支上,会提示你成功merge本地代码到这个人的代码库

git checkout master //切换到自己的分支上

git merge 某人-master //把那个人的分支merge到你的主干上

git push origin master //push上去,成功!

 

还要记着一点,本地修改代码前一定要先pull一下看看,记得慎用github的在线编辑功能

 

node-sass的介绍及使用(官方文档)

其实我很少写第三方库的介绍的,主要是node-sass确实蛮好用,而且我对ruby缺乏好感。。

 

 

node-sass

Build Status NPM version Dependency Status devDependency Status Coverage Status

Node-sass is a library that provides binding for Node.js to libsass, the C version of the popular stylesheet preprocessor, Sass.

It allows you to natively compile .scss files to css at incredible speed and automatically via a connect middleware.

node-sass提供了一个nodejs到libsass的桥梁.libsass是广受欢迎的css预处理器sass的c版本.

这个东东提供了难以想象的效率来本地编译sass到css文件,甚至可以通过中间件的方式自动编译。

Find it on npm: https://npmjs.org/package/node-sass

Install 安装

npm install node-sass 

Usage 使用

var sass = require('node-sass');
sass.render({
    file: scss_filename,
    success: callback
    [, options..]
    });
// OR
var css = sass.renderSync({
    data: scss_content
    [, options..]
});

Options 选项(这里仔细看)

The API for using node-sass has changed, so that now there is only one variable – an options hash. Some of these options are optional, and in some circumstances some are mandatory.

node-sass的api已经变化,只需要一个参数-options对象。有些选项是可选的,有些选项在某种环境下是必须的。

file

file is a String of the path to an scss file for libsass to render. One of this or data options are required, for both render and renderSync.

file表示libsass需要编译的文件,以字符串表示。这个选项或者data选项必须在render或者renderSync中指定

data

data is a String containing the scss to be rendered by libsass. One of this or file options are required, for both render and renderSync. It is recommended that you use the includePaths option in conjunction with this, as otherwise libsass may have trouble finding files imported via the @import directive.

data表示scss字符串.这个选项或file选项必须在在render或者renderSync中指定.我们建议你使用includePaths选项来为@import(sass中的import命令)指定来源,不然有些时候libsass在寻找@import引入的文件时会出错

success

success is a Function to be called upon successful rendering of the scss to css. This option is required but only for the render function. If provided to renderSync it will be ignored.

当scss被编译为css后,success指定的函数被调用.这个选项在render函数中是必须的,但renderSync会忽略

error

error is a Function to be called upon occurance of an error when rendering the scss to css. This option is optional, and only applies to the render function. If provided to renderSync it will be ignored.

当scss被编译为css的过程中出错,error指定的函数被调用.这个选项在render函数中是可选的,但renderSync会忽略

includePaths

includePaths is an Array of path Strings to look for any @imported files. It is recommended that you use this option if you are using the data option and have any @import directives, as otherwise libsass may not find your depended-on files.

includePaths是一个由字符串组成的数组,表示路径,来表明任何@imported所引入的文件在哪。如果你使用了data选项,且包含@import,建议你使用这个选项,否则libsass可能找不到依赖文件。

imagePath

imagePath is a String that represents the public image path. When using the image-url() function in a stylesheet, this path will be prepended to the path you supply. eg. Given an imagePath of /path/to/imagesbackground-image: image-url('image.png') will compile to background-image: url("/path/to/images/image.png")

imagePath 表示图片路径. 当在样式表中使用 image-url() 函数时, 这个函数将会载入你用imagePath指定的图片路径比如说你设置了imagePath为/path/to/images,样式表中写的是background-image: image-url(‘image.png’),将会被编译为 background-image: url("/path/to/images/image.png")

outputStyle

outputStyle is a String to determine how the final CSS should be rendered. Its value should be one of 'nested', 'expanded', 'compact', 'compressed'. [Important: currently the argument outputStyle has some problem which may cause the output css becomes nothing because of the libsass, so you should not use it now!]

outputStyle是一个字符串,表示最终的CSS是什么样的。它的值应该是下列值其中一个:“nested”,“expanded”,“compact”,“compressed”。(重要:目前outputStyle有一些问题,libsass的缘故可能会导致不输出css,所以建议现在不应该使用!)

 

sourceComments

sourceComments is a String to determine what debug information is included in the output file. Its value should be one of 'none', 'normal', 'map'. The default is 'none'. The map option will create the source map file in your CSS destination. [Important: souceComments is only supported when using the file option, and does nothing when using data flag.]

sourceMap

If your sourceComments option is set to mapsourceMap allows setting a new path context for the referenced Sass files. The source map describes a path from your CSS file location, into the the folder where the Sass files are located. In most occasions this will work out-of-the-box but, in some cases, you may need to set a different output.

Examples

var sass = require('node-sass');
sass.render({
    data: 'body{background:blue; a{color:black;}}',
    success: function(css){
        console.log(css)
    },
    error: function(error) {
        console.log(error);
    },
    includePaths: [ 'lib/', 'mod/' ],
    outputStyle: 'compressed'
});
// OR
console.log(sass.renderSync({
    data: 'body{background:blue; a{color:black;}}',
    outputStyle: 'compressed'
}));

Edge-case behaviours

  • In the case that both file and data options are set, node-sass will only attempt to honour the filedirective.
  • 当file跟data选项都设置了,node-sass只会以file选项为准

Connect/Express middleware

connect跟express的中间件

Recompile .scss files automatically for connect and express based http servers

下面的例子可以让node-sass变为express/connect的中间件,来自动编译scss文件

var server = connect.createServer(
  sass.middleware({
      src: __dirname
    , dest: __dirname + '/public'
    , debug: true
    , outputStyle: 'compressed'
    , prefix:  '/prefix'
  }),
  connect.static('/prefix', __dirname + '/public')
);

Heavily inspired by https://github.com/LearnBoost/stylus

DocPad Plugin docpad的插件

@jking90 wrote a DocPad plugin that compiles .scss files using node-sass:https://github.com/jking90/docpad-plugin-nodesass

Grunt extension  grunt的插件(grunt的sass插件就是基于这货)

@sindresorhus has created a set of grunt tasks based on node-sass: https://github.com/sindresorhus/grunt-sass

Gulp extension gulp的插件

@dlmanning has created a gulp sass plugin based on node-sass: https://github.com/dlmanning/gulp-sass

Harp

@sintaxi’s Harp web server implicitly compiles .scss files using node-sass: https://github.com/sintaxi/harp

Meteor plugin

@fourseven has created a meteor plugin based on node-sass: https://github.com/fourseven/meteor-scss

Mimosa module

@dbashford has created a Mimosa module for sass which includes node-sass:https://github.com/dbashford/mimosa-sass

Example App

There is also an example connect app here: https://github.com/andrew/node-sass-example

Rebuilding binaries

Node-sass includes pre-compiled binaries for popular platforms, to add a binary for your platform follow these steps:

Check out the project:

git clone https://github.com/andrew/node-sass.git cd node-sass git submodule init git submodule update npm install npm install -g node-gyp node-gyp rebuild 

Replace the prebuild binary with your newly generated one

cp build/Release/binding.node precompiled/*your-platform*/binding.node 

Command Line Interface

The interface for command-line usage is fairly simplistic at this stage, as seen in the following usage section.

Output will be saved with the same name as input SASS file into the current working directory if it’s omitted.

使用命令行接口是相当简单的,见以下使用部分。
若不指定输出文件,输出文件名将与输入的SASS文件名相同,且保存到当前工作目录。

 

Usage

node-sass [options] <input.scss> [<output.css>]

Options:

 --output-style CSS output style (nested|expanded|compact|compressed) [default: "nested"] --source-comments Include debug info in output (none|normal|map) [default: "none"] --include-path Path to look for @import-ed files [default: cwd] --help, -h Print usage info 

Post-install Build

Install runs a series of Mocha tests to see if your machine can use the pre-built libsass which will save some time during install. If any tests fail it will build from source.

If you know the pre-built version will work and do not want to wait for the tests to run you can skip the tests by setting the environment variable SKIP_NODE_SASS_TESTS to true.

 SKIP_NODE_SASS_TESTS=true npm install 

Contributors

Special thanks to the following people for submitting patches:

Dean Mao Brett Wilkins litek gonghao Dylan Greene

Note on Patches/Pull Requests

  • Fork the project.
  • Make your feature addition or bug fix.
  • Add documentation if necessary.
  • Add tests for it. This is important so I don’t break it in a future version unintentionally.
  • Send a pull request. Bonus points for topic branches.

Copyright

Copyright (c) 2013 Andrew Nesbitt. See LICENSE for details.

转发 viewport双城记

    • about:
      • 原文:http://www.quirksmode.org/mobile/viewports.html
      • 作者简介:
        • Peter-Paul Koch — mobile platform strategist, consultant, and trainer
        • 详细描述
      • 搬运人员:
        • 翻译:承风
        • 较稿:鬼道
      • 名词说明:
        • 本文所有的缩小、放大、缩放都指zoom操作。而非改变浏览器窗口的大小。
  • viewport 双城记(part1)
    • 在这个迷你系列的文章里,我将解释viewports和多种重要的HTML标签元素的宽度是如何工作的,例如<html>标签。同样也会解释windowscreen的宽度问题。
    • 第一部分主要关于桌面(pc)浏览器,基本目的在于为移动端(mobile)浏览器上,本话题的讨论创建舞台。绝大多数web开发人员已经对pc的概念有了直观的认识。mobile拥有相同的概念,但是更加复杂。如你所知,一个友好的预热将极大的帮助你理解mobile浏览器。
    • 概念:设备的pixelsCSS的pixels
      • 首先你应当理解CSS的pixels,以及它和设备的pixels的区别
      • 我们姑且认定设备的pixels为正确(标准)的pixels宽度。这些pixels决定了你工作所用的那些设备上正式的分辨率。在大多数情况下,能够从screen.width/height上取出具体值。
      • 如果你为某个HTML元素赋值width:128px,你的显示器是1024px宽且你最大化了浏览器窗口。忽略后续所言的麻烦的部分,粗略的计算下,该显示器上能横排容纳(1024/128 = 8)个这种元素。
      • 如果用户缩放(zoom)了浏览器,当然必须改变计算方式。例如用户缩放了200%,上诉显示器只能横排容纳4个上诉元素了。
      • 现代浏览器上的缩放,是基于“伸展”pixels。结果是,html元素上的宽度并没有因为缩放200%而由128pix变成256px,而是真实的pixels的被计算成了双倍。html元素在形式上依然是128CSS的pixels,即便它占用了256设备的pixels
      • 换言之,缩放200%将一个单位的CSS的pixels变成了4倍的设备的pixels那么大,即宽度 * 2、高度 * 2,面积扩大了2 * 2.
      • 下列图片将清楚的解释这个概念。如图1-1.有4个1像素,缩放为100%的html元素,CSS的pixels完整的和设备的pixels重叠
      • image 图1-1
      • 当我们缩小浏览器时,CSS的pixels开始收缩,导致1单位的设备的pixels上重叠了多个CSS的pixels,如图1-2
      • image 图1-2
      • 同理,放大浏览器时,相反的事情发生了,CSS的pixels开始扩大,导致1单位的CSS的pixels上重叠了多个设备的pixels,如图1-3
      • image 图1-3
      • 总体而言,你只需要关注CSS的pixels,这些pixels指定你的样式被如何渲染
      • 设备的pixels几乎对你毫无用处。但对用户而言却不是这样。用户会缩放页面,直到他能舒服的阅读内容。但是你不需关心这些缩放级别。浏览器会自动的保证你的CSS的pixels会被伸展还是收缩。
      • 100% 缩放
      • 本例设定缩放级别为100%。现在我们更严谨的定义,如下:

      在缩放级别为100%时,1单位的CSS的pixel是严格相等于1单位的设备pixel

      • 100%缩放的概念非常有利于表述接下来的内容,但你不必在日常工作中过度担忧这个问题。在桌面系统上,你通常会在100%缩放级别下测试你的网站,但即便用户缩放,CSS的pixels的魔法依然能保证你网站外观保存相同的比例
      • 屏幕尺寸 Screen size

      screen.width/height

      • 含义:用户的屏幕的完整大小
      • 度量:设备的pixels
      • 兼容性问题:IE8里,不管使用IE7模式还是IE8模式,都以CSS的pixels来度量

        • 我们先了解一些特殊的尺寸:screen.width 和 screen.height。这两个属性包含了用户屏幕的完整宽度高度。这些尺寸使用设备的pixels来定义,他们的值不会因为缩放而改变:他们是显示器的特征,而不是浏览器。如图1-4所示。
        • image 图1-4
        • 很有趣吧?但是我们拿来何用呢?
        • 简单的说,木有用!用户的显示器宽度对我们而言不重要 – 除非你想要用他们做网络统计数据
        • 浏览器尺寸 Window size

        window.innerWidth/Height

      • 含义:包含滚动条尺寸的浏览器完整尺寸
      • 度量:CSS的pixels
      • 兼容性问题:IE不支持,Opera用设备pixels来度量

        • 相反的,你想要知道的浏览器的内部尺寸。它定义了当前用户有多大区域,可供你的CSS布局占用。你可以通过window.innerWidth 和 window.innerHeight来获取。如图1-5
        • image 图1-5
        • 显然,窗口的内部宽度使用CSS的pixels.你需要知道多少你自己定义的元素能塞入浏览器窗口,而这些数量会随着用户放大浏览器而减少(如图1-6)。所以当用户放大显示时,你能获取的浏览器窗口可用空间会减少,window.innerWidth/Height就是缩小的比例

      Opera浏览器在这个问题上是一朵奇葩,当用户放大浏览器显示时不少。
      所以当用户放大显示时,你能获取的浏览器窗口可用空间会减少。
      window.innerWidth/Height 却并不会减小。
      在桌面浏览器上,这个特性很烦人,但在移动设备浏览器上简直是致命的,后面我们会讨论

      • image 图1-6
      • 注意,窗口内部宽度和高度的尺寸,包含了滚动条的尺寸。(这主要是来至于历史原因)
      • 滚动移位 Scrolling offset

      window.pageX/YOffset

      • 含义:页面的移位
      • 度量:CSS的pixels
      • 兼容性问题:pageXOffset 和 pageYOffset 在 IE 8 及之前版本的IE不支持, 使用”document.body.scrollLeft” and “document.body.scrollTop” 来取代

        • window.pageXOffset 和 window.pageYOffset,定义了页面(document)的相对于窗口原点的水平、垂直位移。因此你能够定位用户滚动了多少的滚动条距离。如图1-7
        • image 图1-7
        • 该属性也以CSS的pixels来度量.同上面的问题,你想要知道在用户放大窗口的情况下,用户向上滚动了多少的滚动条。
        • 原理上来说,在用户放大浏览器时,向上滚动了页面,window.pageX/YOffset会改变。但当用户放大页面时,浏览器会尝试着保存用户当前可见的页面的元素依然在可见位置。虽然该特性表现得不如预期,但它意味着:在理论上 该情况下 window.pageX/YOffset并没有改变,被用户滚出屏幕的CSS的pixels几乎保存不变。如图1-8。
        • image 图1-8
    • 概念:视窗 viewport
      • 在我们继续讨论更多的JavaScript特性properties之前,先介绍另外一个概念:viewport
      • viewport的功能在于控制你网站的最高块状(block)容器:<html>元素.
      • 听起来有点玄乎,举个例子~假设你定义了一个可变尺寸的布局(liquid layout),且你定义一个侧边栏的宽度为width: 10%。当你改变浏览器窗口大小时,该侧边栏会自动扩张和收缩。这是什么原理呢?
      • 技术上讲,原理是侧边栏的宽度为它父元素宽度的10%,我们设它的父元素是<body>且你未指定宽度。那么问题就变为了<body>的宽度到底是多少?
      • 通常,一个块级元素占有起父元素的100%的宽度(这里有异常情况,暂时忽略)。所以<body>的宽度就是其父元素<html>的宽度。
      • 那么<html>元素到底有多宽?因为它的宽度恰好为浏览器的宽度。所以你的侧边栏宽度width: 10%会占用10%的浏览器宽度。所以的web开发人员都直观的知道和使用该特性了。
      • 但是你也许不知道原理。在原理上,<html>的宽度受viewport所限制,<html>元素为viewport宽度的100%。
      • 反过来,viewport是严格的等于浏览器的窗口:定义就是如此。viewport不是一个HTML的概念,所以你不能通过CSS修改它。它就是为浏览器窗口的宽度高度 – 在桌面浏览器上如此,移动设备浏览器上有点复杂。
      • 影响 Consequences
      • 缩放事件有一些奇怪的影响,你可以在本站上实验(http://www.quirksmode.org/mobile/viewports.html)。页面滚动到最上面,放大浏览器2-3倍,网站的宽度会超过浏览器窗口。再将页面滚动到最右边,你会发现网站最上面的蓝色栏目不再对齐了。如图2-1
      • image 图2-1(作者还在玩IE6!)
      • 这个效果反应了viewport是如何被定义的。我定义了最上面蓝色栏目的宽度为width: 100%。什么的100%?当然是<html>的宽度,同样是viewport的宽度,同样是浏览器窗口的宽度。
      • 重点:缩放比例100%的情况下很正常,现在我们放大浏览器,viewport变得比网站的总宽度更小。对viewport无影响,但页面的内容溢出了<html>元素,但它却有属性overflow: visible。意味着溢出的部分依然会被显示。
      • 但蓝色栏目却不会溢出。我定义了它宽度为width: 100%,结果浏览器为他赋值宽度为viewport的宽度。浏览器不会在乎这个栏目的宽度是不是过窄了。如图2-2
      • image 图2-2
      • 页面宽度 document width ?
      • 我真正想要知道的是页面内容的总大小,包括超出浏览器窗口的部分。到目前为止,据我所知并没有办法找到这个值(当然,除非你计算页面所有部分的宽度包括所有元素的margin,但是这种计算很容易出错)
      • 我开始相信我们需要一个JavaScript特性对(property pair)来标示我所谓的页面宽度 document width(当然,以CSS的pixels来度量)。如图2-3
      • image 图2-3
      • 如果我们真的感觉对这事儿很烦躁:为什么不在CSS中揭露这些值?我期望定义width: 100%来控制页面蓝色栏目的宽度,它基于页面的宽度而不是<html>元素的宽度。这似乎很棘手(This is bound to be tricky),如果这成功的被实现我也不会感倒惊讶
      • 度量viewport Measuring the view port

        document. documentElement. clientWidth/Height

        • 含义:viewport的尺寸
        • 度量:CSS的pixels
        • 兼容性问题:无

      • 你也许想要知道viewport的尺寸,他们可以通过document. documentElement. clientWidth/Height来获取。如图2-4
      • image 图2-4
      • 如果你熟悉DOM,你会知道document.documentElement实际上就是<html>元素:HTML文档的根元素。然而viewport是比<html>更高级别的元素,打个比喻,它是容纳<html>元素的元素。那会和你是否给<html>元素赋值width相关(我不建议这么做,但是却是可行的)
      • 在那种情况下document. documentElement. clientWidth/Height依然给出了viewport的尺寸,而不是<html>元素。(这是特殊的规则只针对这个特殊的元素针对这个特性对。在其余任何情况下元素使用实际的宽度)如图2-5。为<html>元素赋值25%。但document. documentElement. clientWidth/Height的值不变。它虽然貌似从<html>元素取值,但实际描述的确是viewport的尺寸。
      • image 图2-5
      • 所以document. documentElement. clientWidth/Height只会给出viewport的尺寸,而不管<html>元素尺寸如何改变
      • 两个特性对 two property pairs
      • 但是viewport的尺寸不是也通过window.innerWidth/Height来描述的么?嗯,是,也不是。
      • 这两个特性对有严格的区别,几乎算是吹毛求疵了
        • window.innerWidth/Height包含滚动条
        • document. documentElement. clientWidth/Height不包含
      • 我们能获取这两个特性对是因为他们是浏览器大战的残留。过去Netscape只支持window.innerWidth/HeightIE 只支持document. documentElement. clientWidth/Height。从那时候开始所有其余浏览器都支持这两个特性。但IE一直未支持window.innerWidth/Height
      • 在桌面系统中,拥有这两个特性对只是一点小麻烦,但在移动设备中却变成了一种祝福。后面我们会看到
      • 度量<html>元素 measuring the <html> element

        document. documentElement. offsetWidth/Height

        • 含义:<html>的尺寸
        • 度量:CSS的pixels
        • 兼容性问题:IE用这个值标示viewport的尺寸而非<html>

      • 如果clientWidth/Height一直用以标示viewport的尺寸,我们该如何去获取<html>元素的尺寸呢?— document.documentElement.offsetWidth/Height。如图2-6
      • image 图2-6
      • 这个特性对真实的让你访问块级元素<html>元素,如果你为<html>元素赋值了宽度,offsetWidth会真实的反应出来。如图2-7
      • image 图2-7
      • 事件坐标 Event coordinates

        pageX/Y, clientX/Y, screenX/Y

        • 含义:见下文
        • 度量:见下文
        • 兼容性问题:IE不支持pageX/Y,IE使用CSSpixels来度量screanX/Y

      • 详细描述
        • pageX/Y:从<html>原点到事件触发点的CSS的 pixels
        • clientX/Y:从viewport原点(浏览器窗口)到事件触发点的CSS的 pixels
        • screenX/Y:从用户显示器窗口原点到事件触发点的设备 的 pixels
      • 如图2-8、2-9和2-10
      • image 图2-8
      • image 图2-9
      • image 图2-10
      • 9成可能你会用到pageX/Y而1成左右会使用clientX/Y,screenX/Y基本没啥用
      • Media查询 media queries

        mediaqueries

        • 含义:见下文
        • 度量:见下文
        • 兼容性问题:IE不支持.

      • 最后一点文字关于@media的css属性。出发点很简单:你可以根据页面的特定宽度来定义特殊的CSS规则。举个例子。

        div.sidebar {

        width: 300px;

        }

        @media all and (max-width: 400px) {

        // styles assigned when width is smaller than 400px;

        div.sidebar {

        width: 300px;
        }

        }

      • 如果宽度大于400px,那么sidebar宽度为300px。反之,sidebar宽度为100px
      • 有两个相关的media查询width/height 和 device-width/device-height。如图2-11

        • device-width/height使用screen.width/height来做为的判定值。该值以设备的pixels来度量
        • width/height使用documentElement.clientWidth/Height即viewport的值。该值以CSS的pixels来度量

      • image 图2-11
      • 到底该使用那个呢?一个很无脑的结果:width。web开发中不需要对设备的宽度感兴趣,而width却使按照浏览器窗口的大小计算的
      • 所以在桌面浏览器中使用width而忘记device-width。接下来我们会看到在移动设备中有点凌乱
    • 总结
      • 在此结束对桌面浏览器的特性的简短讨论,第二部分主要涉及移动设备和其与桌面浏览器的重要区别
  • viewport 双城记(part2)
    • 在这个迷你系列的文章里,我将解释viewports和多种重要的HTML标签元素的宽度是如何工作的,例如<html>标签。同样也会解释windowscreen的宽度问题。
    • 本页我们将讨论移动设备的浏览器。如果你是移动开发的纯菜,建议先阅读第一部分:关于pc浏览器,以建立基本的概念
    • 移动设备浏览器的问题
    • 设备的宽度是移动设备浏览器和桌面浏览器的最大区别。移动设备的显示通常比桌面浏览器显示同一网站的内容要少。或者缩放浏览器变小导致文字无法阅读,或者只显示网站适合设备大小的部分内容。
    • 移动设备的屏幕宽度比桌面浏览器小,经常最大就400px宽,而且通常会更小。(有些手机号称大宽度,但他们确是在说谎 – 或起嘛给了我们一些无用的信息)
    • 一些中间宽度的pad设备(table device)如iPad或传说中HP的webOS设备填补了桌面和移动设备的缺口,但却没有解决根本的问题。网站还是必须在移动设备上工作,我们不得不让她们在小屏幕上显示得表现良好。
    • 问题的风暴中心在于CSS,特别是viewport的尺寸。如果我们只是拷贝桌面的样式到移动设备,我们的CSS会丑得崩溃
    • (假设移动设备的宽度400px)我们回到width: 10%的侧边栏。如果在移动设备上同理处理,会显示出40px宽,实在太窄了。你的可变布局看起来被可怕的压扁了。
    • 其中一个解决方式是为移动设备重新建设一个特殊的网站。即使跳开这些基本的问题:你到底该怎么处理,现实的问题是只有很少的站长准备好了加入迎合移动设备而做的改变。
    • 移动设备浏览器供应商期望他们的客户端提供最好的可能性体验,即现在意味着“尽可能的像桌面浏览器”。因此许多处理手段是必须的。
    • 两种viewport
    • 因此viewport太窄,不能很好为你的基本CSS布局服务了。最显然的解决方式是让viewport更宽。因此这个需求分为了2个方面:虚拟的viewportvisualviewport和布局的viewportlayoutviewport
    • George Cummins在Stack Overflow上解释了这个基本概念,猛击

    想象下layoutviewport是一张大的不能改变大小和角度的图片。现在你有个更小的框来观看这张大图片,这个框被不透明的材料包围,因而你只能看到大图片的一部分。你通过这个框子看到的大图片的部分被称为虚拟viewport(visual viewport)。你能拿着这个框站得离大图片远点(用户的缩小页面功能),以一次性看到这个大图片。或者你能站得近点(用户的放大页面功能)以看到一部分。你能改变这个框子的方向,但这张大图片的大小和形状都不会改变。

    • 你可以参见解释详情by Chris
    • visualviewport是当前显示在屏幕上的部分页面。用户会滚动页面来改变可见部分,或者缩放浏览器来改变visualviewport的尺寸。见图1-1.
    • image 图1-1
    • 但是CSS 布局,特别是感性的宽度(percentual widths)通常是按照layoutviewport来定义,而比visualviewport宽很多
    • 然而<html>元素的宽度继承于layoutviewport,你的CSS应预先准备着需要处理的屏幕(layoutviewport)是不是远远超过手机屏幕宽度。这用以保证你的网站外观特性而恰如在桌面浏览器上一样
    • layoutviewport到底有多宽?每个浏览器都不同。iPhone上的Safari使用980px、Opera 850px,安卓的Webkit核心800px,IE974px。
    • 一些浏览器有特别的特性
    ------ * 塞班webkit试着保存`layoutviewport`和`visualviewport`同样宽度。因此,定义百分比宽度的元素会变得巨难看。当然,如果页面有特定的宽度而不是适合`visualviewport`的宽度,那么该宽度的最大值会被设置为850px * 三星的WebKit([bada](https://zh.wikipedia.org/zh/Bada_(操作系统))上)会设置`layoutviewport`和最宽的元素一样宽 * 黑莓上`layoutviewport`和`visualviewport`在100%缩放时一样宽。 ------ 
    • 缩放 Zooming
    • 两种viewports都以CSS的 pixels来度量。当你通过缩放改变visualviewport时,layoutviewport保存不变。
    • 理解layout viewport
    • 为了理解layoutviewport的尺寸,我们先看下页面完全缩小时发生了什么。许多移动设备浏览器在初始默认打开以最小缩放模式打开网站。(即在手机屏幕上展示完整宽度的页面)。如图1-2.
    • 重点:浏览器已经选择好他们的layoutviewport的尺寸,它完整的覆盖了最小缩放模式下的移动浏览器的屏幕。
    • image 图1-2
    • 这时候layoutviewport的宽度高度和最小缩放模式下能在页面上显示的内容的宽度高度一致。即便用户缩放,它依然保存不变。如图1-3
    • image 图1-3
    • layoutviewport宽度通常保存不变。如果你旋转你的手机,visualviewport改变,但浏览器会缩放页面以自适应,以达到layoutviewport再次和visualviewport同样宽。如图1-4。
    • image 图1-4
    • 这影响到了layoutviewport的高度,它突然变得比竖着模式更小(portrait model肖像模式),但web开发者并不关心高度,只在乎宽度。如图1-5.
    • image 图1-5
    • 度量layout viewviewport

      document. documentElement. clientWidth/Height

      • 含义:layoutviewport尺寸
      • 度量:CSS的pixels
      • 完整支持:Opera, iPhone, Android, Symbian, Bolt, MicroB, Skyfire, Obigo
      • 问题:在Iris上它标示visualvieport
        • 三星的Webkit核心浏览器,仅当在页面上写入<meta viewport>标签,才正确表示。否则就代表着<html>的尺寸
        • FireFox设备的pixels来度量
        • IE返回1024 x 768 px,而准确的尺寸保存在document.body.clientWidth/Height
        • NetFront仅当100%缩放时候才正确
        • 塞班的Webkit1(在S60v3设备)不支持这些属性
      • 不支持:黑莓

    • 很幸运浏览器由于浏览器大战而遗留给我们2个特性对来度量这两种viewport
    • document.documentElement.clientWidth/Height传递layoutviewport的尺寸,如图1-6
    • image图1-6
    • 旋转只关系到高度,而不是宽度。如图1-7

    *image图1-7

    • 度量visual viewport

      window.innerWidth/Height

      • 含义:visualviewport尺寸
      • 度量:CSS的pixels
      • 完整支持:iPhone, Symbian, BlackBerry
      • 问题:
        • FireFoxOpera设备的pixels返回该数值
        • Android, Bolt, MicroB, 和 NetFront 以CSS的pixels返回该数值,且为layoutviewport的值
      • 不支持:
        • IE,它使用document. documentElement. offsetWidh/Height来表示
        • 三星的Webkit核心浏览器,仅当在页面上写入<meta viewport>标签,才正确表示。否则就代表着<html>的尺寸
      • 混乱:Iris, Skyfire, Obigo返回的值不知所云

    • 我们使用window.innerWidth/Height来度量visualviewport。显然,随着用户缩放浏览器,这值会改变,更多、更少的CSS pixels放进了屏幕。如图1-8
    • image图1-8
    • 很不幸这是一个待完善的部分,许多浏览器依然没有支持对visualviewport的度量。到现在为止,没有浏览器将该度量存储在其他地方,我猜测window.innerWidth/Height会成为标准,albeit是最强力的支持者
    • 屏幕 Screen

      screen.width and screen.height

      • 含义:屏幕尺寸
      • 度量:设备的pixels
      • 完整支持:Opera Mini, Android, Symbian, Iris, Firefox, MicroB, IE, BlackBerry
      • 问题:
        • Opera在Windows Mobile下只给出横向尺寸(landscape size)。在S60上工作正确
        • 三星的Webkit核心浏览器,仅当在页面上写入<meta viewport>标签,才正确表示。否则就代表着<html>的尺寸
        • iPhoneObigo仅给出竖直尺寸(portrait sizes)
        • Android, Bolt, MicroB, 和 NetFront 以CSS的pixels返回该数值,且为layoutviewport的值
      • 不支持:
        • IE,它使用document. documentElement. offsetWidh/Height来表示
        • 三星的Webkit核心浏览器,仅当在页面上写入<meta viewport>标签,才正确表示。否则就代表着<html>的尺寸
      • 混乱:Iris, Skyfire, Obigo返回的值不知所云

    • 和pc浏览器一样,screen.width/height标示了设备屏幕的尺寸,以设备的pixels度量。和pc浏览器一样,作为web开发人员你永远不需要这些信息。你不关心屏幕的物理宽度,而关心当前有多少CSS的pixels能供你使用。如图1-8
    • image 图1-8
    • 缩放等级 Zoom level
    • 无法直接获取缩放等级,但可以使用screen.width除以window.innerWidth来计算。当然,只有这两个特性被完美支持时才能使用。
    • 幸运的是,缩放等级并不重要。你只需要知道当前有多少CSS的pixels能供你使用。你可以从window.innerWidth获取这些信息 – 如果当前浏览器支持。
    • 滚动位移 scrolling offset

      window.pageX/YOffset

      • 含义:见描述
      • 度量:CSS的pixels
      • 完整支持:iPhone, Android, Symbian, Iris, MicroB, Skyfire, Obigo
      • 问题:
        • Opera, Bolt, Firefox, and NetFront 总是返回 0.
        • 三星的Webkit核心浏览器,仅当在页面上写入<meta viewport>标签,才正确表示。
      • 不支持:

        * IE,它使用document. scrollLeft/Top来表示

    • 你同意需要知道当前visualviewport相对于layoutviewport的距离。这就是滚动位移,如同在桌面浏览器一样,使用window.pageX/YOffset存储。如图1-9
    • image 图1-9
    • <html>元素

      document. documentElement. offsetWidth / Height

      • 含义:html元素的整体尺寸
      • 度量:CSS的pixels
      • 完整支持:Opera, iPhone, Android, Symbian, Samsung, Iris, Bolt, Firefox, MicroB, Skyfire, BlackBerry, Obigo
      • 问题:
        • NetFront只在100%缩放时返回正确的值.

        * IE,使用这个特性对来表示visualviewport的尺寸。它使用document. body. clientWidth/Height来表示

        • 和在桌面系统一样,document.documentElement.offsetWidth/Height给出了<html>元素以CSS的pixels度量的尺寸。如图1-10
        • image 图1-10
        • Media查询 media queries

        Mediaqueries

      • 含义:以CSS的pixels度量<html>元素或以设备 的pixels度量设备
      • 完整支持:Opera, iPhone, Android, Symbian, Samsung, Iris, Bolt, Firefox, MicroB.
      • 不支持:Skyfire, IE, BlackBerry, NetFront, Obigo
      • 备注:

        * 我只测试了浏览器是否从正确的特性对里提取这些值。而特性对里的值是否正确并不在这里进行详细测试。

        • media查询如同桌面系统一样。width/height使用以CSS的pixels度量的layoutviewportdevice-width/height使用以设备的pixels度量的设备屏幕(device screen)
        • 换句话说,width/height 反映document. documentElement. clientWidth/Height的值, device-width/height 反映screen.width/height. (所有浏览器遵循同样原理,即使取值是错误的)。如图1-11.
        • image 图1-11
        • 哪个度量对web开发人员更有用呢?我也不知道。
        • 我起初认为device-width更重要,因为它给予了设备的信息,我们也许可以使用。例如,你能根据设备的宽度改变网站的外观。但是你同样可以使用<meta viewport>标签做到这些。因此使用device-width并不是必须的。
        • 那么width就更有用了么?也许是。浏览器的制造商认为他们给出了一些对网站有用的宽度的细节。但这些内容却含糊(混乱),因而width media 查询并不真正给出其余信息。
        • 所以我没有做决定。现在我认为media查询在标识网站处于桌面浏览器、pad浏览器或手机浏览器方面很重要,而在区别不同pad和手机设备方面并不有用
        • 事件坐标 Event coordinates

        Eventcoordinates

      • 含义:见下文
      • 度量:见下文
      • 完整支持:Symbian, Iris
      • 问题:
        • Opera 只有pageX/Y,但滚动页面过远时这个值会出错。
        • 在iPhone, Firefox, 和 BlackBerry 上clientX/Y 和pageX/Y相等
        • 在 Android 和 MicroB screenX/YclientX/Y相等,也就是它们以CSS的pixels度量屏幕尺寸
        • 在FireFox里screenX/Y值不正确
        • IE, BlackBerry, 和 Obigo 不支持 pageX/Y.
        • NetFront 所以三个值都是screenX/Y.
        • Obigo clientX/YscreenX/Y.
        • Samsung WebKit 总是返回pageX/Y.
      • 未测试:Opera Mini,Bolt,Skyfire

        • 事件坐标在桌面浏览器上多多少少是支持的。不幸的是,移动设备上在所测试的12个主流浏览器中只有Symbian WebKit 和 Iris完全正确的支持这3个坐标特性。其余浏览器多多少少都存在问题。
        • pageX/Y,该特性依然是基于页面的CSSpixels度量的值,如图在桌面浏览器一样,它是三个特性里面最有用的。如图1-12
        • image 图1-12
        • clientX/Y是基于visualviewport的,以CSSpixels度量的值. 这样做比较靠谱,虽然我不是很确信这样计算的好处。
        • screenX/Y基于设备屏幕以设备的pixels度量的值。显然,它使用和clientX/Y同样的参考,而设备的pixels没什么用。所以我们不需要在意screenX/Y,同在桌面浏览器一样,每个bit都是没用的。如图1-13.
        • image 图1-13
        • viewport的meta标签 meta viewport

        Metaviewport

      • 含义:设置layoutviewport的宽度
      • 度量:CSS的pixels
      • 完整支持:Opera Mobile, iPhone, Android, Iris, IE, BlackBerry, Obigo
      • 不支持:Opera Mini, Symbian, Bolt, Firefox, MicroB, NetFront
      • 问题:
        • Skyfire 不能处理我的测试页面。
        • 在三星的wibkit浏览器下,出现<meta viewport>会改变一些特性对的值。

        * Opera Mobile, iPhone, Samsung, and BlackBerry 不允许用户在设置viewport后再进行缩小操作(do not allow the user to zoom out.)

        • 最后我们讨论<meta name="viewport" content="width=320">;最初这是Apple的一个html扩展标签,但被许多浏览器复用,意义是设置layoutviewport的宽度。为了理解它的含义,我们退一步看看基础。
        • 假设你创建一个页面,并不为它赋值width。那么它会伸展开来占据100%的viewlayout的宽度。绝大多数浏览器缩小这个页面以在一屏的宽度上显示这个layoutviewport。我们获得如下效果。图2-1.
        • image 图2-1
        • 用户会立马放大页面,虽然会起到效果,但绝大多数浏览器会保存元素完整的宽度(保持元素定位的不变),而导致阅读困难(文字超过屏幕),如图2-2
        • image 图2-2
        • (唯一不同的是Android下的Webkit核心浏览器,他会剪短长串文字的html元素,以让他们适应屏幕。这简直太有才了,我觉得其余所有浏览器都应该复用这个特性。我会在再以后全面的写这方面内容)
        • 现在你可以尝试着设置htm{width: 320px}。现在<html>元素收缩,随之所有的会计元素都占有100%的<html>宽度:320px。当用户放大浏览器显示时这样做工作得挺好,但在最初加载时的缩小显示下,用户感觉很糟糕,因为页面几乎没内容。如图2-3.
        • image 图2-3
        • 为了解决这个问题,Apple引入了metaviewport。当你设置<meta name="viewport" content="width=320">,你网站的layoutviewport变成了320px。页面的初始状态就很正确了。如图2-4
        • image 图2-4
        • 你能任意设置layoutwidth的宽度,甚至包括device-widthdevice-width由以设备的pixels度量screen.width来设置。
        • 在这里有个钩子(There’s a catch here)。有时严格的screen.width一点意义都没有,因为pixels的值太大了。例如,Nexus One上的严格宽度是480px,但Google的工程师觉得在用户设置device-width时,将layoutviewport设置为480太大了。他们砍成了2/3,提供320px,和iPhone上一致。
        • 加入,像传言中,新的iPhone将提供一个巨大的pixel值(并不等于一个巨大的屏幕,只是分辨率),如果他们沿用这个特性:device-width为320,我一点都不会惊讶。或许最终device-width会直接意味着320px。
        • 相关研究
        • 许多相关研究将会在以后展开:

      • position: fixed。一个固定位置的元素,如我们所知,定位于viewport。但到底是哪个viewport?我的研究结果如下:猛击
      • 其余media 查询:dpi, orientation, 特别是dpi是个灾难性的区域,不仅仅因为所以浏览器都返回96dpi(通常这个值是错误的),而且因为我们不知道web开发人员到底对哪部分感兴趣。[一个相关问题](http://stackoverflow.com/questions/11722442/is-there-a-way-to-use-dpi-in-css-media-queries-instead-of-px)
        • 当我们的元素大于layoutviewport<html>时会发生什么?如果我们在layoutvwport为320px的页插入了一个1500p元素,如果我们为<html>设置了overflow: visible时,它会超出。是否意味着实际的viewport能比layoutviewport更宽?此外,这种情况发生时一个旧的Android设备(Nexus One)扩大HTML元素。这是个好主意么?

点击链接不发送referer的方法

我们在从一个网站点击链接进入另一个页面时,浏览器会在header里加上Referer值,来标识这次访问的来源页面。但是这种标识有可能会泄漏用户的隐私,有时候我不想让其他人知道我是从哪里点击进来的,能否有手段可以让浏览器不要发送Referer呢?

基于HTML标准,可以在a标签内使用rel="noreferrer"来达到这一目的。
目前大部分基于Webkit的浏览器已经支持
提供跨浏览器支持的更好的办法是使用一个第三方的库noreferrer.js,它可以自动识别浏览器并选择最优方案。

 

如:   <a href=”http://example.com/” rel=”noreferrer”>noreferrer!</a>

当服务器接收到了由从某个网页上点击这个链接发起的HTTP请求时,HTTP请求的Referer字段将是空的,这就好像用户在 IE浏览器(当然IE目前并不支持HTML5)地址栏直接从about:blank状态开始输入地址并访问这个网站一样的效 果,example.com并不会知道这次访问的来源信息。

当链接中的同时使用 target=”_blank” 时,WebKit同样将会把window.opener属性设为空(null)。对于这个用法的解释是:一个由于点击了网页中锚点而发起的请求,之后目标 页面执行的任何脚本应该运行在一个新的上下文环境中,即使这个目标页面通常被认为有着同样的源头。

“noreferrer”这个链接属性值只是HTML5 spec中定义的许多链接属性值的一个。在WebKit中,它是第一个被实现的。其实我们只是希望这样会让那些关心用户隐私和安全的Web开发人员的工作和生活轻松一些。

 

我看了下源码跟网上其他的文章,不发送referer有几种方式,本质是一样的,都是打开一个能刷新页面的小刷新器,再刷新页面

用window.open的方式打开一个中转页面,再在里面执行代码打开(新窗口打开)

function open_new_window(full_link){
    window.open('javascript:window.name;', '<script>location.replace("'+full_link+'")<\/script>');
 }

其中location.replace刷新页面的方式也可以替换成html自刷新的方式

var html = '<html><head><meta http-equiv='Refresh' content='0; URL=" 路径 + "' /></head><body></body></html>'

var a = window.open(null, 打开方式(_self或者_blank))
a = a.document;
a.clear();
a.write(e);
a.close();

用iframe添加到body后,仍然用javascript的方式替换链接

function open_without_referrer(link){
document.body.appendChild(document.createElement('iframe')).src='javascript:"<script>top.location.replace(\''+link+'\')<\/script>"';
}

用data schema的方式替换href,仍然打开一个刷新器

var html = '<html><head><meta http-equiv='Refresh' content='0; URL=" 路径 + "' /></head><body></body></html>'

html = encodeURIComponent(html)

$(链接).click(function (){
this.href = html;
return !0
})

 

补充 这个东西有啥使用场景呢,比如百度百科之前会判断禁止从别的搜索引擎的链接跳过来。。

 

还有一点,防盗链。比如http://hi.baidu.com/aullik5/item/d677bec02a6b2e300931c6ca

比如下载链接时判断来源,有些下载站只允许本站下载。