让你的网页在滚动的时候 放屁

放屁绝对不是一个很高雅的行为,但是如果你比较喜欢恶搞,或者在愚人节,或者是一些比较特殊的网页设计中,可以通过 fartscroll.js 这个插件让你的网页在滚动的过程中 放屁。

直接打开 fatscroll.js 的官方页面(http://theonion.github.io/fartscroll.js/),滚动一下,你就可以听到了放屁声音了,你滚动的距离和速度不同,放屁的声音也不同。

使用方法也很简单,先下载插件包,解压出来之后,在网页中引入 fartscroll.min.js 这个文件,然后配置下面的参数等,启用这个插件:

    // 在文档中滚动 400 像素就放屁
$(document).fartscroll();

// 文档中每滚动 800 像素就放屁
$(document).fartscroll(800);

// 网页中没滚动 100 像素就放屁
$("body").fartscroll(100);

// 很多很多的屁
$("body").fartscroll(5);</pre>

仅供娱乐和恶搞哈,相信应该没有太多人喜欢在访问你网页的时候,听到你网页在放屁哈哈。

Emmet 生成 HTML 的语法

在上篇文章前端开发神器 Emmet 介绍中,我简单的介绍了一下 Emmet ,并且用了一句指令迅速生成了一大片 HTML 代码。本文,就会介绍 Emmet 的 HTML 语法,看完之后,你就会看懂并且写出那句代码了。

现在,打开你的 ST2 然后新建一个 HTML 文档,跟着文章,即时输入对应的指令然后亲自尝试一下!

生成 HTML 文档初始结构

HTML 文档的初始结构,就是包括 doctype、html、head、body 以及 meta 等内容。你只需要输入一个 “!” 就可以生成一个 HTML5 的标准文档初始结构,你没有看错,输入一个感叹号(当然是英文符号),然后摁下 TAB 键,就会发现生成了下面的结构:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
</html>
这就是一个 HTML5 的标准结构,也是默认的 HTML 结构。如果你想生成 HTML4 的过渡型结构,那么输入指令 `html:xt` 即可生成如下结构:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
</head>
<body>

</body>
</html>
Emmet 会自动把 doctype 给你补全了,怎么样,这样的功能会不会让你动心?简单总结一下常用的 HTML 结构指令: * `html:5` `或者 !` 生成 HTML5 结构 * `html:xt` 生成 HTML4 过渡型 * `html:4s` 生成 HTML4 严格型 ## 生成带有 id 、class 的 HTML 标签 Emmet 的语法有点类似 CSS 的语法,生成 id 为 aaa 的 div 标签,我们只需要编写下面指令:
#aaa
Emmet 默认的标签为 div ,如果我们不给出标签名称的话,默认就生成 div 标签。如果编写一个 class 为 bbb 的 span 标签,我们需要编写下面指令:
span.bbb
然后就生成了对应的结构。同理,如果想要编写一个 id 为 ccc 的 class 为 ddd 的 ul 标签,我们可以这样写:
ul#ccc.ddd
很简单吧?比你用手写 id 、class 方便多了吧 ## 生成后代:> 大于号表示后面要生成的内容是当前标签的后代。例如我要生成一个无序列表,而且被 class 为 aaa 的 div 包裹,那么可以使用下面指令:
div.aaa>ul>li
可以生成如下的结构:
<div>
    <ul>
        <li></li>
    </ul>
</div>

生成兄弟:+

上面是生成下级元素,如果想要生成平级的元素,就需要使用 + 号。例如下面指令:

div+p+bq`
就可以生成如下的 HTML 结构:

`<div></div>
<p></p>
<blockquote></blockquote>`

生成上级元素:^

上级 (Climb-up)元素是什么意思呢?前面咱们说过了生成下级元素的符号“>”,当使用 div>ul>li 的指令之后,再继续写下去,那么后续内容都是在 li 下级的。如果我想编写一个跟 ul 平级的 span 标签,那么我需要先用 “^” 提升一下层次。例如:

div>ul>li^span
就会生成如下结构:
<div>
    <ul>
        <li></li>
    </ul>
    <span></span>
</div>
如果我想相对与 div 生成一个平级元素,那么就再上升一个层次,多用一个“^”符号:
div>ul>li^^span

重复生成多份:*

特别是一个无序列表,ul 下面的 li 肯定不只是一份,通常要生成很多个 li 标签。那么我们可以直接在 li 后面 * 上一些数字:

ul>li*5
这样就直接生成五个项目的无序列表了。如果想要生成多份其他结构,方法类似。 ## 生成分组:() 用括号进行分组,这样可以更加明确要生成的结构,特别是层次关系,例如:
`div>(header>ul>li*2>a)+footer>p`
这样很明显就可以看出层次关系和并列关系,生成如下结构:
`<div>
    <header>
        <ul>
            <li><a href=""></a></li>
            <li><a href=""></a></li>
        </ul>
    </header>
    <footer>
        <p></p>
    </footer>
</div>`
此外,分组还可以很方便的结合上面说的 “*” 符号生成重复结构:
`(div>dl>(dt+dd)*3)+footer>p`
生成结构:
`<div>
    <dl>
        <dt></dt>
        <dd></dd>
        <dt></dt>
        <dd></dd>
        <dt></dt>
        <dd></dd>
    </dl>
</div>
<footer>
    <p></p>
</footer>`

生成自定义属性:[attr]

a 标签中往往需要附带 href 属性和 title 属性,如果我们想生成一个 href 为 “http://www.qianxingzhem.com” ,title 为“潜行者m 博客”的 a 标签,可以这样写:

a[href="http://www.qianxingzhem.com" title="潜行者m 博客"]
其他标签和属性都类似。 ## 对生成内容编号:$ 例如无序列表,我想为五个个 li 增加一个 class 属性值 item1 ,然后依次递增从 1-5,那么就需要使用 $ 符号:
`ul>li.item$*5`
这样就生成了如下结构:
<ul>
    <li class="item1"></li>
    <li class="item2"></li>
    <li class="item3"></li>
    <li class="item4"></li>
    <li class="item5"></li>
</ul>
$ 就表示一位数字,只出现一个的话,就从1开始。如果出现多个,就从0开始。如果我想生成三位数的序号,那么要写三个 $:
`ul>li.item$$$*5`
输出:
`<ul>
    <li class="item001"></li>
    <li class="item002"></li>
    <li class="item003"></li>
    <li class="item004"></li>
    <li class="item005"></li>
</ul>`
只能这样单调的生成序号?对于强大的 Emmet 来说,肯定不会会了,我们也可以在 $ 后面增加 @- 来实现倒序排列:
`ul>li.item$@-*5`
生成如下结构:
`<ul>
    <li class="item5"></li>
    <li class="item4"></li>
    <li class="item3"></li>
    <li class="item2"></li>
    <li class="item1"></li>
</ul>`
同样,我们也可以使用 @N 指定开始的序号:
`ul>li.item$@3*5`
这样就会从 3 开始排序,生成如下代码:
`<ul>
    <li class="item3"></li>
    <li class="item4"></li>
    <li class="item5"></li>
    <li class="item6"></li>
    <li class="item7"></li>
</ul>`
配合上面倒序输出,可以这样写:
`ul>li.item$@-3*5`
生成的就是以 3 为底倒序:
`<ul>
    <li class="item7"></li>
    <li class="item6"></li>
    <li class="item5"></li>
    <li class="item4"></li>
    <li class="item3"></li>
</ul>`

生成文本内容:{}

上面讲解了如何生成 HTML 标签,那里面的内容呢?当然也可以生成了:

a[href="http://www.qianxingzhem.com"]{点击这里到 潜行者m 的博客}

这样就生成了一个到我博客的超链接了。在生成内容的时候,特别要注意前后的符号关系,虽然 a>{Click me} 和 a{Click me} 生成的结构是相同的,但是加上其他的内容就不一定了,例如:

`<!– a{click}+b{here} –>
<a href=””>click</a><b>here</b>

<!– a>{click}+b{here} –>
<a href=””>click<b>here</b></a>`
这样就生成了完全不同的结构,注意这些小细节哦。

不要有空格

在写指令的时候,你可能为了代码的可读性,使用一些空格什么的排版一下。这就会导致代码无法使用。例如下面这句:

`(header > ul.nav > li*5) + footer

而去掉空格之后,就可以正常执行生成结构了。HTML 语法部分说完了,现在回头看看第一篇文字,你是否已经看懂了那一串指令?下一篇将会讲解快速编写 CSS 的技巧。

前端开发神器 Emmet 介绍

在前端开发的过程中,一大部分的工作是写 HTML、CSS 代码。特别是手动编写 HTML 代码的时候,效率会特别低下,因为需要敲打很多尖括号,而且很多标签都需要闭合标签等。于是,就有了 Emmet,它可以极大的提高代码编写的效率,它提供了一种非常简练的语法规则,然后立刻生成对应的 HTML 结构或者 CSS 代码,同时还有多种实用的功能帮助进行前端开发。

你可能听说过一款强大的功能相似的工具:Zen Coding,那个比较老了,而现在的 Emmet 则是 Zen Coding 的升级版,由 Zen Coding 的原作者进行开发等。

Emmet 严格意义上来说,并不是一款软件或者工具,它是一款编辑器插件,必须要基于某个编辑器使用。目前它支持如下编辑器:

在 Sublime text 2 中安装 Emmet

Sbulime text 2 安装插件肯定要通过 Package Control 这个插件了,如果你还没有安装这个插件,抓紧先去安装一下吧。安装完成之后,我们摁下“shift + ctrl + p”呼出面板,输入“pci”即可锁定“Package Control:Install Package”这个功能,回车之后就可以看到一个列表,我们继续输入“emmet”即可找到这个插件,回车之后等待一会就安装完成了。

sublime text 2 安装 emmet

开始使用 Emmet

Emmet 可以快速的编写 HTML、CSS 以及实现其他的功能。它根据当前文件的解析模式来判断要使用 HTML 语法还是 CSS 语法来解析。例如当前文件的后缀为 .html 那 Sublime text 2 就会用 HTML 的解析模式来解析高亮这个文件,Emmet 遇到里面的指令就会根据 HTML 的语法把它编译成 HTML 结构。如果是在一个 .c 的 C 语言 文件中,你写出来的用于编译 HTML 指令就不会被 Emmet 识别编译。

此外,在没有后缀的文件中,你可以摁下“shift + ctrl + p”呼出面板,输入“seth”就可以设置当前文件的解析模式为 HTML 。了解这些之后,下面我们来见证强大的 Emmet 。

如果让你编写下面的这个 HTML 结构,你需要多长时间?

<div id="page">
    <div class="logo"></div>
    <ul id="navigation">
        <li><a href="">Item 1</a></li>
        <li><a href="">Item 2</a></li>
        <li><a href="">Item 3</a></li>
        <li><a href="">Item 4</a></li>
        <li><a href="">Item 5</a></li>
    </ul>
</div>

然而,这一切你只需要编写下面这一句按照 Emmet 语法写出来的语句,然后用 Emmet 编译一下,就可以生成了!

#page>div.logo+ul#navigation>li*5>a{Item $}

我们把它复制到 Sublime text 2 中已经打开的 HTML 文件中,这时候紧跟着敲击一下 TAB 键,见证奇迹的时刻到来了。

怎么样?很神奇吧,仅仅写一行代码,就可以生成这么一个复杂的 HTML 结构,而且还可以生成对应的 class 、id 和有序号的内容。而且 Emmet 的语法很简单,虽然你现在可能还看不懂,后面的系列教程会详细讲解它的语法,你现在只需要知道 Emmet 的工作流程:打开 HTML 或 CSS 文件->按语法编写指令->摁下 TAB 键->生成!

使用 CSS 将彩色图片转换成黑白图片

  • 原文:Convert Images To Black And White With CSS
  • 原作者:Dudley Storey 译者:潜行者 m
  • 版权声明:版权归原作者所有,翻译仅作学习参考交流使用。
    PS:最近翻译不少国外的优秀文章,不是没有写作灵感,是马上就要四级考试了 T _ T,哥现在还没开始正式复习。为了锻炼一下英语,所以选择翻译一些优秀的国外文章。

CSS3 中的滤镜(filter)功能让我们轻松方便简单的处理图片,而不需要使用 PhotoShop 或者使用很多 JavaScript、PHP 代码。这个属性已经得到比较新的 Firefox、Safari、Chrome 浏览器支持,而且我们可以通过综合的可替代的技术来模拟实现这个效果——甚至是 IE 浏览器。

本文中,我们将使用标准测试图片 Lena Söderberg (译者注:Lena 这张裸体美女照片,被作为图片压缩的标准测试用图片)作为演示,使用 CSS 将其转换成黑白图片。在下面我将讲解如何使用 CSS 的这个功能实现调整色调、模糊、亮度、对比度和一些其他的效果。效果图:

lena

CSS3 的灰阶滤镜

使用 CSS3 来稀释一个图片的颜色,再简单不过了。我们可以把这个 CSS 语句写成一个类,这样遇到想要效果的图片,直接加上个类就可以了。

img.desaturate { filter: grayscale(100%); }

当然,当前的浏览器在使用 CSS3 的时候,要加上他们自己的浏览器功能实验性前缀,所以,我们首先要做的,就是写上浏览器的前缀:

img.desaturate { filter: grayscale(100%);
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
}

想要用在某个图片上很简单,加上一个类:

<img src=lena-söderberg.png alt="Lena Söderberg" style=width:512px;height:512px class=desaturate>

这就可以了。

增加一个 SVG 的滤镜效果

这个功能目前只在 Chrome 18+ 有效,其他浏览器马上就会增加支持。为了在 Firefox 4+ 中得到相同的效果,我们可以需要使用 SVG 滤镜。我把新建了一个单独的文件 的 saturate.svg ,代码如下:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter id="greyscale">
<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>

不要被这段 SVG 代码吓住了——虽然上面的矩阵数列有点复杂。这段代码我推荐你直接复制粘贴成一个通用的“小文件”。我会再写一篇文章详细介绍一下上面矩阵变化,在这里不再赘述。

加上上面的 SVG 文件引用,我们要插入 HTML 页面的 CSS 代码如下:

img.desaturate{
filter: grayscale(100%);
-webkit-filter: grayscale(100%); -moz-filter: grayscale(100%);
-ms-filter: grayscale(100%); -o-filter: grayscale(100%);
filter: url(desaturate.svg#greyscale);
}

为 IE 做兼容

到现在我们的代码可以兼容未来的浏览器,和最新版的 Chrome 、 Firefox 4+。为了让 IE 6-9 加入兼容列表,我们需要使用微软的笨拙但是有效的 filter 滤镜:

img.desaturate{
filter: grayscale(100%);
-webkit-filter: grayscale(100%); -moz-filter: grayscale(100%);
-ms-filter: grayscale(100%); -o-filter: grayscale(100%);
filter: url(desaturate.svg#greyscale);
filter: gray;
}

如果你还想做老版本的 Webkit 内核浏览器的兼容:

img.desaturate{
filter: grayscale(100%);
-webkit-filter: grayscale(100%); -moz-filter: grayscale(100%);
-ms-filter: grayscale(100%); -o-filter: grayscale(100%);
filter: url(desaturate.svg#greyscale);
filter: gray;
-webkit-filter: grayscale(1);
}

不幸的是,Safari 和 Opera 仍然不支持,但是 Safari 5.2 ——很快就会发布——应该会支持 webkit CSS3 滤镜功能,同时 Opera 对 CSS3 的支持正在不断提升。

注意

如果你想要在所有的浏览器中实现这个视觉效果(假设你的访问者都支持 JavaScript)你可以使用 jQuery 或者 Greyscale.js 来修改你的图片,使其去色。

上面咱们写的 CSS 代码可以让我们不需要使用 PhotoShop 就可以把图片变成黑白的。使用 CSS 来实现这个功能,可以非常容易修改:例如,你可以看到当我们把去色程度参数从 100% 变成 50% 的时候图片会是原色和黑白融合在一起的效果。

HTML 的 id 和 class 可以使用 Unicode 编码的特殊字符命名

先简单的普及一下 Unicode 编码的基础知识,关于网页中的编码,详情请看 潜行者m 的文章:网页编码就是那点事。好了普及完毕,开始正文内容。

HTML 结构中的 id 和 class 属性,最重要的目的就是作为结构的标识,可以被 CSS 选择器和 JS 选择器获取,增加样式和行为。由于结构通常比较复杂,id、class 的命名就成了一个大问题。于是出现了很多种命名方案,什么驼峰命名法等等。此外还有很多团队规范,规定命名规则等等。

但是这些命名,通常都逃不过:数字、字母、下划线、横杠。虽然这些比较直观,但是会不会太枯燥?其实 HTML、CSS、JS 支持的命名字符,远不止这点,你可以使用 Unicode 编码的特殊字符来让你的命名变得丰富多彩。

Unicode 由于有很多存储空间,所以拿出了很多 Unicode 编码代表一些比较常用的“字符图像”。比较常见的是 copyright 的图标:©,这就是一个 Unicode 编码存储的图标。其他的各种字符:Ϭ、ϻ、Ѽ 等,都是 Unicode 编码的字符。而 HTML、CSS、JS 支持使用它们来做命名。所有的 Unicode 字符列表,请看这里:http://en.wikipedia.org/wiki/List_of_Unicode_characters

在使用之前,请先确保你理解 Unicode 等这些编码,你必须让你的文件保存成 UTF-8 等格式才能使用,否则可能会显示成乱码。

然后我做了一个 Demo 来做测试,Demo 中就使用特殊字符来命名,你可以在不同的测试环境浏览器进行测试,可以反馈一下看下有没有平台不支持。具体的代码不再贴出,请看 Demo 页面中代码。Demo 地址:http://www.qianxingzhem.com/demo/1927/

应用的话,以后代码就丰富多彩了哈哈。

在 Sublime Text 2 中使用 SFTP 插件快速编辑远程服务器文件

Sublime Text 2 本身并不强大,但是它方便使用插件扩展功能,所以变得很强大。今天 潜行者 m 介绍一个很实用的插件 SFTP ,可以大大提高前端工作效率。

常见的工作流程

有时候修改一些网站上的文件,通常是下面这样的流程:使用 FTP/SFTP 连接到远程服务器 -> 下载要修改的文件 -> 使用 ST2 修改文件 -> 保存然后拖进 FTP 中 -> 刷新网站。

很明显这样的工作流程效率很低,特别是你修改一句代码的时候,为了即时生效,也需要重复切换几个窗口重复这个过程。于是就有了 SFTP 这个插件。

它主要功能就是通过 FTP/SFTP 连接远程服务器并获取文件列表,可以选择下载编辑、重命名、删除等等操作,点下载编辑之后,可以打开这个文件进行修改。修改完成之后,保存一下会自动上传到远程的服务器上面。

使用这个插件之后,工作流程就变成了:使用 SFTP 插件打开文件 -> 使用 ST2 编辑修改文件 -> 保存文件 -> 刷新页面。效率提升了至少一倍以上,下面就来介绍一下具体的使用方法。

SFTP 使用方法

先要安装这个插件,打开 Sublime Text 2 ,摁下 shift + ctrl + p 键,呼出面板,使用 Package Control 这个插件安装。输入 “pci” 敲击回车,再输入 “sftp” 即可安装这个插件。安装完之后,就要开始配置服务器使用了。

第一步:配置 FTP/SFTP 服务器信息

安装完插件之后,找到 “文件” 菜单,找到 “SFTP/FTP” 选项,点击配置:

在 SFTP 中配置远程服务器信息

点击之后,会弹出一个新的窗口,这是一个配置文件

SFTP 中服务器的配置参数

一般就是配置一下我箭头所指的四个参数,包括连接方式、服务器地址、用户名、密码等。如果你的服务器还有其他配置,你也可以对照注释设置一下。一般为了方便,还会设置一下“路径”,这样直接可以看到想要修改的文件列表。

配置完成之后,我们保存,然后输入一个名字作为标识。

第二步:连接服务器获取文件列表

还是点击 “文件” 选择 “SFTP/FTP” 中的查看服务器列表

使用 SFTP 连接远程服务器

会弹出刚刚配置好的服务器,我们可以点击需要连接的 FTP 服务器,这时候就链接上了并且弹出文件列表

SFTP 连接服务器获取文件列表

这时候点击一个文件,就可以弹出一些选项

使用 SFTP 操作远程文件

就可以根据你自己的需要,对文件编辑、重命名什么的了。点击编辑之后,会在本地打开,然后可以修改。摁下 ctrl + s 保存文件的时候,就会自动上传文件。

如果需要查看服务器上的别的文件,或者需要更多的功能,可以直接在当前文件中右击,选择 “SFTP/FTP” 就会弹出更多选项可以使用,没法截图所以不再赘述。更多的功能,就交给你自己探索了!

让浏览者禁用响应式布局界面

  • 原文:Letting users disable responsive layout
  • 作者:456 Berea Street 翻译者:潜行者m
  • 版权声明:版权归原作者所有,翻译仅作学习交流目的!
    响应式网站设计(Responsive Web Design)使用强大的媒体查询(media querie)让网站可以根据浏览者的浏览设备分辨率进行样式调整。但是,这样也产生了一个问题:有些人并不希望网站的外观在不同的浏览设备中发生改变。因为改变了之后,可能会让人产生疑问,认为自己在访问另一个网站。

虽然我不认为这会影响一大批人,但是绝大多数人肯定不懂响应式网站设计。如果有个人在电脑、平板电脑或者智能手机上访问同一个网站结果发现外观效果不同,他可能会感到很困惑。Bruce Lawson 在文章 Turning off responsive web design 中就提到了一个真实的例子。

一个同事也提到了另一个案例,响应式布局并没有很完美的客户端支持。客户经常提到布局问题等等。试想一下,如果你收到了一个邮件提到的是关于你用电脑访问看到的外观或内容,那么你用平板或者智能手机可能看不到相同的外观或者内容。当然,这种情况可能不多,但是这时候如果有一个可以切换或者关掉响应式布局的功能就好多了。

尽管这个功能不会让很多人受益,但是做这么个功能也并不是很复杂的事情。所以我在一些项目中增加了这个功能,现在想跟大家分享一下。这个方法跟 Adrian Roselli 写的 Letting Mobile Users See Desktop View of RWD Site 这篇文章中的很相似。这个功能不是很复杂,更不是什么革命性的改进,但是可以通过很多方法来实现。

如何命名响应式布局开关

有必要讨论一下怎么在网页中称呼这个功能。通常的名字是:查看桌面版布局、桌面版、完整版。而我称呼它为:查看固定宽度下的布局(当切换之后变成“查看弹性宽度下的布局”)。我并不确定这样可以帮助用户明白之间的异同,但是我认为这比起“桌面端”和“手机端”来说,描述的更加准确。有些人的浏览器窗口可能比 960px 还窄,也可能比 1200px 窄,或者是他们自己拖动设置的大小,虽然满足了媒体查询中定义的宽度,但是能在网页中显示“切换成桌面版”?

HTML 和 CSS 代码

我做了一个 Disable responsive layout 演示页面来展示效果。如果你打开了这个页面,并且调整你的浏览器窗口小于 960px ,一个就跟超链接似的开关就会显示出来,点击就可以切换。我觉得只有在媒体查询工作的时候才显示这个切换开关——如果响应式布局没有被触发,那切换个毛啊。

我选择直接把这个切换链接写进 HTML 中,而不是使用 JavaScript 临时生成。这是因为我使用后台(可以是任何后台语言,本文中使用 PHP 做演示)来处理 cookie ,这样就可以记录你是否选择了禁用响应式布局。

在前面的 demo 页面中,写入了如下的 HTML 结构,你可以自己定义:

&lt;div id="toggle"&gt;
    &lt;a href="?fixedwidth=1"&gt;Switch to fixed width layout&lt;/a&gt;
&lt;/div&gt;`</pre>
使用 CSS 让其隐藏,不要写进媒体查询中:
<pre>`#toggle {
    display:none;
}
.fixed #toggle {
    display:block;
}`</pre>
为了方便切换,我们增加了 fixed 类。这样切换的时候,只需要对 html 对象加上 fixed 类就可以了。如果 html 对象中有这个类,就说明用户已经禁用了响应式布局,所以需要显示开关,方便他们再次启用。

下面 CSS 片段包含进媒体查询中:
<pre>`@media only screen and (max-width:960px) {

    #toggle {
        display:block;
    }

}`</pre>
上面代码实现当宽度小于 960px 的时候,触发媒体查询功能显示这个开关。如果用户已经禁用了响应式布局,上面代码将不会被加载(实现方法见下文)。

如果你的媒体查询 CSS 文件没有在一个单独的文件,要实现这个功能,可能需要做的更多工作。你可以在媒体查询的规则前面加上前缀 html:not(.fixed) 或者不使用媒体查询创建单独的文件。

##  JavaScript 代码

如果媒体查询的 CSS 代码被禁用,你要确保与响应式布局无关的 JavaScript 和 CSS 代码也被禁用。为了达到这个目的,你可以将下面的脚本放在单独的文件中,你也可以使用这种方法处理对应的 CSS (使用 PHP 处理),不加载这个文件。如果你没有分割成单独的文件,那么就通过检查 HTML 元素中是否有 fixed 这个类名在启用响应式布局功能脚本:
<pre>`&lt;script&gt;
if ( !document.documentElement.className.match(/(\\s|^)fixed(\\s|$)/) ) {
    // Responsive scripts go here, likely with additional checks
    // for viewport width, media query support etc.
}
&lt;/script&gt;`</pre>

##  PHP 代码

在本文 Demo 中,我使用 PHP 来处理 cookie 和提供切换响应式布局的功能。你可以使用 JavaScript 来实现这样的功能,但是这样在禁用 JavaScript 的客户端无法生效。毕竟这不是很关键的功能,如果你选择使用 JavaScript 请记住如果客户端不支持 JavaScript 的时候,也要显示出一个可以看到的链接。

下面就是一个简单的 HTML 结构和必须的 PHP 代码:
<pre>`&lt;?php
    $fixedwidth = '';
    //检查是否有 $fixedwidth 这个变量,然后获取
    if ( isset($_GET['fixedwidth']) &amp;&amp; ($_GET['fixedwidth'] != "") ) {
        $fixedwidth = $_GET['fixedwidth'];
    }
    //检查是否有对应的 cookie 内容
    if ( isset($_COOKIE['fixedwidth']) ) {
        if ( $fixedwidth == '0' ) {
            // 如果值为 0 就清除 cookie
            setcookie('fixedwidth', '', time() - 60, '/');
        } else {
            // 如果值不为零,就获取
            $fixedwidth = '1';
        }
    } else if ( $fixedwidth == '1') {
        // 浏览者想要禁用响应式布局功能,设置一个 cookie
        $expires = 60 * 60 * 24 * 60 + time(); 
        setcookie('fixedwidth', '1', $expires, '/');
    }
?&gt;
&lt;!DOCTYPE html&gt;
&lt;html lang="en" &lt;?php if ($fixedwidth == '1') { echo 'class="fixed"'; } ?&gt;&gt;
&lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;title&gt;Document title&lt;/title&gt;
&lt;?php
// 只在响应式布局可用的时候插入 meta[name="viewport"] 对象
if ( $fixedwidth != '1' ): ?&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
&lt;?php endif; ?&gt;
    &lt;link rel="stylesheet" href="main.css" /&gt;
&lt;?php
// 只在响应式布局可用的时候,插入 CSS 文件
if ( $fixedwidth != '1' ): ?&gt;
    &lt;link rel="stylesheet" href="mq.css" /&gt;
&lt;?php endif; ?&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Document title&lt;/h1&gt;
    &lt;div id="toggle"&gt;
&lt;?php
// Responsive is disabled, so insert a switch to flexible width
if ( $fixedwidth == '1' ): ?&gt;
        &lt;a href="&lt;?php echo $_SERVER["SCRIPT_NAME"] ?&gt;?fixedwidth=0"&gt;Switch to flexible width layout&lt;/a&gt;
&lt;?php
// Responsive is not disabled, so insert a switch to fixed width
else: ?&gt;
        &lt;a href="&lt;?php echo $_SERVER["SCRIPT_NAME"] ?&gt;?fixedwidth=1"&gt;Switch to fixed width layout&lt;/a&gt;
&lt;?php endif; ?&gt;
    &lt;/div&gt;
    &lt;script&gt;
    if ( !document.documentElement.className.match(/(\\s|^)fixed(\\s|$)/) ) {
        // Responsive scripts go here
    }
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

上面的 PHP 代码肯定能进一步改进,这里只是抛砖引玉给你一个思路,你可以自己编写更符合你要求的代码。

这个功能应该在客户端中吗?

你可能会产生浏览器是否应该增加切换响应式布局功能的疑问。浏览器可能需要禁止他们自身对媒体查询的支持,而是通过网站的设置来默认显示“全尺寸”或者“桌面版”。这就是为什么我个人喜好直接开发网站,但是其他开发者却相反的先使用媒体查询功能开发“手机端”的网站,然后再开发“桌面端”布局。

如果你使用媒体查询为老的浏览器隐藏 CSS3 的功能,这也会产生问题。一个浏览器的禁用媒体查询的功能,可能会禁用所有的媒体查询中的代码,这样会产生很多布局的问题。

所以,这个功能应该交给咱们 Web 开发者来做。如果你需要这个功能,上面提供了一个不错的思路。

译者总结

禁用响应式布局确实是一个必要的功能。Bruce Lawson 在 Turning off responsive web design 这篇文章中,提到了一个小故事。说他的父亲在用手机访问一个网站的时候,发现跟电脑访问时不一样,而怀疑自己是不是在访问想访问的网站,然后关掉了。

潜行者m 曾经使用平板和智能手机做过测试,虽然智能设备上的浏览器通常可以设置“使用什么样的客户端模式(桌面、手机)来访问网站”,但是响应式布局使用的媒体查询技术,直接根据设备的参数等进行改变,不会因为客户端的代理模式(User-Agent)。特别是使用手机想要看到网站的桌面版效果,就很难实现了。

通过 JavaScript 来实现这个功能也非常简单,但是使用 PHP 更加有优势。这样可以减少不必要的 CSS 、JS 文件的引入,增强前端性能。但是 PHP 的移植性不太好。所以也可以考虑使用 JavaScript 来实现。

如果想要你的网站更加完善,如果使用了响应式布局的设计,最好加上一个禁用选项。

使用 PHP 获取并解析 JSON 显示在页面中

很久没写过 PHP 的文章了,也很久没有用 PHP 了,差点忘了怎么做了。JSON 是现在比较流行的数据交流方式,比 XML 都流行,一般用作 api 接口进行数据获取、交流。

就文章的标题来说,本文介绍两个小要点:PHP 获取内容、PHP 解析 JSON 并显示。

PHP 获取接口内容

你如果想解析 JSON 数据并且显示在页面中,第一步肯定要先得到 JSON 接口文件的内容。在 PHP 中获取一个页面的内容,可以使用 fopen() 函数远程页面然后使用 fread() 函数循环获取内容。

假设接口文件页面为:http://www.qttc.net/api.php?action=open_getBlogList&only_recommend=1&limit=5 ,那么我们可以使用下面语句获取这个接口文件内容:

$handle = fopen("http://www.qttc.net/api.php?action=open_getBlogList&only_recommend=1&limit=5","rb");
$content = "";
while (!feof($handle)) {
    $content .= fread($handle, 10000);
}
fclose($handle);

这样 content 保存的就是 JSON api 内容。

PHP 解析 JSON 并显示

原始的内容是无法直接调用的,必须被 PHP 进行进一步处理,才能被调用显示在网页中。在 PHP 5.2 及后续版本中,使用 json_decode() 函数来解析 JSON 数据,将其转换成 PHP 可以调用的数据格式。例如:

$content = json_decode($content);

解析之后呢,我们就可以按照 PHP 中调用数组数据的方法一样的调用 JSON 中的数据。这个调用方法需要按照具体的 JSON 数据格式来写,演示请看下面。关于 json_decode 函数的使用,具体看 PHP 手册,这里不再赘述:http://php.net/manual/en/function.json-decode.php

实战调用琼台博客的 api

细心的朋友会发现 潜行者 m 博客的边栏最下面多了一个“友文推荐”模块,里面推荐了一些琼台博客的文章。

友文推荐

友文推荐是琼台博客倡议的一种博客之间交流方式,比传统的友情链接更有效,同时实现了博客内容互补。由于琼台博客的博客程序是他自己本人编写的,所以他提供了 JSON api 接口,可以获取到最新的可推荐的文章。

本人使用 PHP 获取这个 JSON 接口,然后输出到自己博客的边栏中,下面来实战操作一下。

第一步,查看 api 调用方式

调用之前,你肯定要看一下对方的 api 调用手册,包括调用地址、如何调用、数据输出格式等等。琼台博客的 api 说明地址如下:http://www.qttc.net/openapi.html

根据文档,我使用了 http://www.qttc.net/api.php?action=open_getBlogList&only_recommend=1&limit=5 这样的参数,意思就是调用五条他推荐的文章。

第二步,获取 api 结构数据

很简单,上面说过了,具体代码如下:

$handle = fopen("http://www.qttc.net/api.php?action=open_getBlogList&only_recommend=1&limit=5","rb");
$content = "";
while (!feof($handle)) {
    $content .= fread($handle, 10000);
}
fclose($handle);

先打开这数据文件,然后把所有内容保存到 content 变量中,因为可以肯定 api 数据不会超过 10000 个字符,所以用 10000 作为 fread 函数的第二个参数。这样,api 返回的 JSON 数据就保存在了 content 变量中。

第三步,解析并输出内容

使用下面代码解析数据,然后调用输出

$content = json_decode($content);
foreach ($content->data as $key) {
    echo '<li><a target="_blank" href="'.$key->b_url.'">'.$key->b_title.'</a></li>';
}

首先对 content 变量中的 JSON 数据处理,然后变成 PHP 可以调用的数据,再使用 foreach 遍历输出这五条内容,按照我需要的 HTML 格式,将内容插入进去即可。

再加上样式修饰,这样就完成了 获取并解析 JSON 显示在页面中了。调用其它 api 数据的方法大同小异。

使用预加载提速你的网站

  • 原文:Speed Up Your Site Using Prefetching
  • 原作者:Jon Fox 译者:潜行者m
  • 版权声明:版权归原作者所有,翻译仅供学习使用,内容有修改,转载请先开启节操模式,保留上面信息。
    预加载(prefetching)这个东西很好理解。我们都知道浏览器可能会在渲染之前需要一些资源。预加载不仅仅提前告诉浏览器这个页面或者可能用到的资源,而且还通常提前保存这个资源到浏览器的缓存,这样就可以以非阻塞的方式请求、下载对应资源提高效率。

有很多方法可以实现预加载,但是这里有三种比较简单实用的方法。

DNS 预加载

DNS 是将域名转换成服务器 IP 地址的协议。DNS 的解析速度通常是非常快的一般在 100ms 以内,但是因为 DNS 解析要发生在任何对服务器的请求之前,这样会造成一个级联效应(cascade effect),这样就会增加页面加载的时间。浏览器解析页面或者 session 的时候会访问静态文件加速服务器的域名,会使用诸如 images.mydomin.com 等域名来加载静态文件。有些浏览器支持 meta 标签可以提前声明这些需要用到的静态加速服务器域名,这样浏览器就可以预先解析它们,调用资源直接通过解析后的 IP ,不需要再进行 DNS 解析。写法如下:

<link href=”//my.domain.com” rel=”dns-prefetch” />
<link href=”http://my.domain.com/" rel=”prefetch” /> <!– IE9+ –>

增加了这个标签之后,支持它的浏览器将会提前进行域名的 DNS 解析,而不用等待请求资源的时候再去解析它。这项技术一般用在浏览者有可能去的页面,提前对页面进行 DNS 的预加载。Chrome、Firefox 和 IE9+ 支持这个功能。

即使看上去只是节省了几百毫秒而已,但是合计起来也是不少的时间。它是一种安全的优化方法同时很容易实现。我很好奇有多少网站使用了这项技术,我打开了 Alexa 排名前 100K 的网站。但是只有 552 个网站(使用率 0.55%)正确的使用了 DNS 预加载技术。这么简单的技术应该被更多的网站使用。

资源预加载

在现在的网站中,网页的大小很大程度上取决于网页中图片的大小。如果提前请求并且下载这些图片,可以有明显的提速效果。大多数情况下,网页作者知道一个图片什么时候需要加载这样就不需要提前在浏览器中声明,例如使用 ajax 或者浏览者浏览页面时触发的一些事件来加载一个图片。资源预加载就是提前让浏览器加载图片、脚本、样式或者其他资源。不仅仅用于加载图片,可以让所有类型的资源提前被缓存在浏览器的缓存中。

这项技术是最久远古老和最经常使用的,抱歉,我无法给出具体的统计数字。仍然有很多网站没有正确的使用这项技术,然而仅仅预加载几张图片就可以制造巨大的用户体验差异。

页面预加载、预渲染

页面预加载就像资源预加载,不同的是页面预加载提前加载了它本身。这项技术首先在 Firefox 浏览器中可以使用。你可以使用下面的标签来测试一下别的浏览器看看这个页面(或者相关资源)能否被提前加载:

    <link href=”/my-next-page.htm” rel=”prefetch” />

不同于预渲染,浏览器不仅仅会下载这个页面,而且还会把这个页面需要用到的资源一块下载下来。通常在内存中渲染这个页面(不会被浏览者看到)这样当请求这个页面的时候就可以很快显示在浏览者面前。预渲染最先在 chrome 中可以使用。你可以在页面中添加下面标签来实现预渲染:

    <link href=”http://mydomain.com/my-next-page.htm" rel=”prerender” />

这项技术在目前非常有争议,在其他技术中也很有风险。预渲染的那个页面必须非常确定是浏览者即将浏览的页面。比较常见的例子是 Google 搜索,它将会预渲染页第一个返回页面。在 Alexa 排行榜前 100K 个站点中,我只发现了 95 个使用这项技术的例子。即使这项技术还不是很成熟也无法适应所有需求,但是我认为很多网站应该用一下来提升用户体验。

争议

预加载一直是有争议的话题。很多人们认为它没有效果而且在浪费宽带。而且它还用到一些不重要的客户端的资源(尤其是很多手机设备)。此外值得一提的是,预加载、预渲染页面可能会导致一些浏览者统计和访问日志记录的问题,因为系统不知道浏览者是否真正访问过这个页面还是通过预加载请求的。

总结

尽管有一些问题,但是预加载还是有很大优势的。请求的速度我们一般无法控制,所以把资源提前尽可能多的放入缓存是我们解决问题的方法。当用户在等待请求的时候,成本太高了,我们可以使用这些技术大大的提升性能。如果你还没有做这些,建议你去应用这些技术到你的网站上。结果可能不一样,所以你可以使用专业工具(例如:Torbit)来检查预加载技术帮你做了多少。