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

  • 原文: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 结构,你可以自己定义:

<div id="toggle">
    <a href="?fixedwidth=1">Switch to fixed width layout</a>
&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)来检查预加载技术帮你做了多少。

HTML5 标签 hgroup 已经被废除

HTML5 增加了很多语义化的标签,hgroup 就是其中一个,它用来表明标题的集合。如果有主标题、副标题,可以使用这个来包裹一下,一般比较常见的就是网站的标题和网站描述:网站标题和副标题常用 hgroup 包裹

但是这样做并不是太必要,而且还有一些麻烦。一般来说,很难有单纯的 hn 标题标签集合在一起,通常还包含一些其他内容,但是使用 hgroup 包裹的内容,必须是 hn 标题标签,否则不会通过 HTML5 验证。又有谁会为了这么一个增强语义性用处不大的标签专门去生成一堆 hn 标签?

然后好消息是,这个标签在最新的 HTML5.1 版中被废除了,以后可以不再用了。但是又面临了一些问题,如果我有类似这种 声明主标题和对应副标题说明 的需求,我应该怎样增强语义性?

W3 给了一些结构建议,查看原文请点击这里。下面引用原文然后用我自己的博客标题做一个例子。

用其他方法模拟 hgroup 的语义性

使用标点符号分割

最简单的方法就是使用标点符号分割主标题和副标题:

<h1>潜行者m: 关注前端开发热爱简约设计。</h1>

这种类型比较适合于文章标题,很显然不适合网站标题。

使用 span 标签标注副标题说明

<h1>潜行者m
   <span>关注前端开发热爱简约设计。</span>
</h1>

这种方式比上面好一点,但是感觉还是怪怪的,但是结构比较简单,如果不怕麻烦,推荐下面一种方法。

使用 header 标签包裹标题和描述

header 也是 HTML5 新增的语义性标签,用来表示头部信息,一般不会被废弃。我们可以这样做:

<header>
<h1>潜行者m</h1>
<p>关注前端开发热爱简约设计。</p>
</header>

强烈推荐这种写法,这样保证了语义性的同时,也保证了代码的整洁。

HTML5 video 跨浏览器兼容的方法

在过去 flash 是网页上最好的解决视频的方法,截至到目前还算是主流,像那些优酷之类的视频网站、虾米那样的在线音乐网站,仍然使用 flash 来提供播放服务。但是这种状况将会随着 HTML5 的发展而改变。就视频而言,HTML5 新增了 video 来实现在线播放视频的功能。

使用 HTML5 的 video 可以很方便的使用 JavaScript 对视频内容进行控制等等,功能十分强大,同时代码比较少加快加载速度。此外跨平台性比较好,特别是一些平板、手机等。例如苹果公司的产品不支持 flash 仅支持 HTML5 中的 video 功能。

但是 HTML5 的兼容性问题是个硬伤,我们可以在网页中使用 video 来播放视频,但使用早期浏览器的访问者可能无法正常观看这个视频。此外,由于视频编码器的历史渊源导致各种浏览器支持的视频格式不同。应对这些问题,想在网页中使用 HTML5 video 功能,可以按照下面三个步骤操作。

第一步:提前准备好多格式视频文件

由于编码器的版权问题,导致不同浏览器对视频格式的兼容性不同。目前没有一个视频格式兼容所有浏览器,唯一的解决方法就是把视频转换成多种格式。

首先要准备一个 mp4 格式的视频,可以在苹果设备中使用;其次要准备 ogv 格式的视频,用在火狐浏览器中;最后要准备一下 webm 格式的视频,这个可以用在谷歌浏览器等。webm 是谷歌提出的,开源、免费,很有可能成为兼容所有浏览器的视频格式。

准备多格式浏览器的麻烦之处在于转换格式。视频转换工具国内的功能比较少,转换格式可能没有上面后两个,而且质量良莠不齐,往往需要注册才能使用。推荐一个国外的工具 Online converter ,在线免费视频转换工具。甚至不用安装软件,直接选择相应的目标格式,然后上传视频,配置一下参数就可以转换出来了。没有合适工具的朋友,可以尝试一下。

第二步:编写对应 HTML5 video 代码

HTML5 中的 video 实际上就是一个简单的标签,包含了一些视频相关信息等。下面我直接给出具体代码,然后简单解释一下:

<video width=”800” height=”374”>
<source src=”my_video.mp4” type=”video/mp4” />
<source src=”my_video.ogv” type=”video/ogg” />
<source src=”my_video.webm” type=”video/webm” />
你浏览器不支持 video 功能,点击这里下载视频: <a href=”video.webm”&gt下载视频</a&gt.
</video>

video 标签表示这里是一个视频,width、height 属性分别表示这个视频内容的宽高(单位像素)。video 标签中可以包含 source 标签,source 标签用来表示引用的视频和视频的格式、类型。为了保证向下的兼容性,我们还在 video 标签中加了一句提示,这句话在支持 video 标签的浏览器中是不会显示的,如果不支持就会显示出来。这里,还增加了一个视频的下载地址,如果浏览器不支持,可以让用户选择下载下来看。

特别需要注意一点,你的主机必须能正确的处理这事些视频请求。确保你的主机被请求这些视频的时候会在 Content-Type 头发送正确的 MIME 类型。如果你不清楚,可以咨询一下主机服务商,也可以自己添加。如果主机支持 .htaccess ,可以在 .htaccess 文件中增加下面语句:

AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm

大体就是这样,比较简单,更加具体的关于 video 的使用方法,可以搜索一下,也可以见本文扩展阅读链接,在这里不再赘述。

第三步:为旧版浏览器做兼容

前面说过,如果浏览器不支持 video ,将会把 video 中的提示内容显示出来。那么对付老旧浏览器,我们可以用传统的 flash 来替换这个提示内容。这样,当浏览器不兼容 video 标签的时候,就会显示出 flash 版本的视频。例如:

<video width=”800” height=”374”>
<source src=”my_video.mp4” type=”video/mp4” />
<source src=”my_video.ogv” type=”video/ogg” />

&lt;object width="800" height="374" type="application/x-shockwave-flash" data="fallback.swf"&gt;
    &lt;param name="movie" value="fallback.swf" /&gt;
    &lt;param name="flashvars" value="autostart=true&amp;amp;file=video.flv" /&gt;
&lt;/object&gt;

</video>
直接按照原来正常的 flash 引入方法写进 video 标签中即可。这样,我们就实现了跨浏览器兼容的 video 功能使用。

参考文章和扩展阅读

Blink 浏览器内核来了

之前 Web 界有一个重磅信息,那就是 Opera 抛弃了自己的内核 Presto 而改用 WebKit 内核。大家都在议论缺乏了渲染内核的多样性,会不会影响到浏览器和 Web 标准之类的进步和发展。而现在,应该不用讨论了,因为一个新内核 Blink 要来了。

Blink 是由 WebKit 内核衍生出来的,是由 Chromium 开发维护的新项目。在官方的博客上有详细的说明:Blink: A rendering engine for the Chromium project。关于这个浏览器的更加详细的特性和目标,可以看这里:http://www.chromium.org/blink。大体就是一大堆的优化,提高速度,各种支持。

之前的 WebKit 内核是由 谷歌 chrome 和 苹果 safari 共同开发,谷歌不干了,从 WebKit 中衍生分离出 Blink 不知道是何居心,不过浏览器渲染内核的多样性是肯定有了,以谷歌的技术,这种多样性应该会促进 Web 的发展。

对于国内来说,Blink 是开源引擎,X60 、X狗 之类的浏览器,又可以再增加一个核了,因为 Blink 对速度做了优化,应该会比 WebKit 还要快,所以可能会被命名为超急速三核切换功能。总之,妈妈再也不用担心我的浏览器核心不够用了。

最害怕的是增加前端工程师的压力,万戈前辈好像很蛋碎,以谷歌的技术,应该不会像对 IE 那样费力的去 Hack,至于那些前缀什么的,随着标准的确立,就自然去掉了。

Opera 怎么办?当然,它也会使用 Blink 内核的。还是让我们拭目以待吧,看看这个内核究竟怎么样。

此外,Firefox 也耐不住寂寞了,前几天也在官方博客上发表了关于联手三星共同开发下一代浏览器内核(servo)的声明(点击这里查看官方声明),这是要干什么?Web 界还是不太平啊,期待国内有哪个技术团队能开发一个自主的内核啊。

使用原生 JavaScript 在页面加载完成后处理多个函数

JavaScript 脚本语言的执行,是需要触发的。一般的做法就是在网页中,直接编写几个函数,有的在代码被加载的时候就被浏览器处理,或者使用类似下面的代码来触发实现函数的相关功能。

<div id=”link” onclick=”fun()” ></div>

上面代码的意思就是,当鼠标点击 id 为 link 的元素的时候,就触发了它的 onclick 事件,然后执行使用 JavaScript 定义的 fun 函数。这样的做法肯定是很不合理的,因为触发操作直接写进了 HTML 结构里面,内容和行为没有隔离开,对日后的二次开发或者修改带来不便。

需要注意的是,当事件处理与对应元素绑定起来的时候,只有在那个元素加载完之后才能进行操作。如果说把处理的脚本放在了 head 区域,浏览器会报错。因为下面的 HTML 元素还没有加载出来,head 中的处理脚本已经被处理了。

一个好的执行 JavaScript 代码的方法应该是 行为内容分离的在页面加载后处理 的。所以,处理 JavaScript 代码我们要用到 监听器 window 对象的 load 事件

监听器

监听器实际上的功能就是行为与内容分离的。以前需要在 HTML 中加上一些触发事件来触发 JavaScript 的相关函数,而现在直接在 JavaScript 中对某个元素的使用监听器,监听这个元素的事件,如果这个元素被触发了某些事件,在监听器中又定义了这个事件对应的处理函数,那么就会处理这个函数。

W3C 的标准方法叫做 addEventListener ,被IE9,chrome,firefox,opera所支持,写法:

window.addEventListener(‘load’,function,false);

早期 IE 中有 attachEvent 方法效果类似:

window.attachEvent(‘onload’,function);

使用监听器的方法也很简单,就是先获取页面中的某个元素,然后对这个元素使用监听器,定义监听的事件和对应的事件处理函数,就上文例子:

document.getElementById(‘link’).addEventListener(‘click’,fun,false);

关于监听器更加详细的使用说明,请见文末补充资料。

window.onload 事件

onload 事件只有在整个页面已经完全载入的时候才会被触发,我们将 JavaScript 代码写进 onload 事件中,就可以保证在 HTML 元素被加载完成之后,浏览器才会处理我们的 JavaScript 代码。基础的写法:

window.onload = function(){
//code
}

这样,这个函数里面的 code 会在加载完成之后被处理。但是,这种方法有个缺陷,就是只能用于这一个函数。页面中无法出现多个 window.onload 事件,如果出现了多个 onload 事件,那么后面的内容会覆盖前面的。

那么,我们可以这样做,在一个 window.onload 事件中,写上所有需要加载的函数名,然后在外面定义函数:

window.onload = function(){
func1();
func2();
}

function func1(){…}
function func2(){…}
这样做虽然可以,但是很不方便,因为我们需要把所有要加载的函数名都写进去,修改起来就会很麻烦。当然办法肯定是有的,jQuery 就特别提供了很强大的多脚本加载方法,那么原生的 JavaScript 肯定也有办法。

window.onload 同时处理多个函数

我们需要编写一个处理函数,先看一下代码:

    function addLoadListener(fn){
if (typeof window.addEventListener != ‘undefined’){
window.addEventListener(‘load’,fn,false);
}else if(typeof document.addEventListener != ‘undefined’){
document.addEventListener(‘load’,fn,false);
}else if (typeof window.attachEvent != ‘undefined’){
window.attachEvent(‘onload’,fn);
}else{
var oldfn = window.onload;
if(typeof window.onload != ‘function’){
window.onload = fn;
}else{
window.onload = function(){
oldfn();
fn();
};
}
}
}

简单的来解析一下,这个自定义的 addLoadListener 函数,传递一个 函数名称 作为参数。它首先判断浏览器是否支持相关的 监听器,如果支持 监听器,就使用 监听器 监听 window 对象的 onload 事件,然后处理这个函数。这段代码使用 if 语句判断了所有浏览器的监听事件,是跨浏览器兼容的。

我们把这段代码放在 JavaScript 代码段的最上面,然后在下面定义相关函数,然后使用下面语句来加载 JavaScript 函数了。

addLoadListener(func);
function func() {…}

这样,有什么 JavaScript 函数是需要在页面加载完成之后处理的,直接使用 addLoadListener 函数即可,而且可以使用多个。通常来说,所有的 JavaScript 最好都使用 onload 事件加载,以避免意外情况发生。

引用和补充资料

将 WordPress 博客从 SAE 迁出搬回 JustHost

前几天不知道为什么,SAE 老是抽风,然后打开很慢甚至无法打开,然而 ping 确实可以 ping 的通。不通过顶级域名而是直接使用 SAE 提供的二级域名也无法打开。

我一直以为 SAE 是非常正规、高质量的,可能偶尔遇到几次抽风问题,事实上这是我第一次遇到。写了一篇文章,结果等了一个下午也没有发表出去。期间,我找了一些网友进行测试,发现不是我个人网络的问题,他们也都打不开。然后 哼哼猪 跟我说,我的博客经常遇到这种很慢的情况。难道是我之前都没有怎么管理导致的吗?

我打算再等等看,第二天恢复正常了。然后第三天一大清早的,又是这种问题。我上网搜索了一下其他放在 SAE 上面的网站,没有这个问题。我开始忍受不了了,忍受不了这种影响用户体验的问题存在。于是打算从 SAE 迁出去。

软矿 的博主 MK 聊了一下,跟我推荐了几个 VPS,我看了半个下午的 VPS 套餐,确定下来之后发现人家卖完了,很无语。于是晚上将博客数据什么的搬回了之前的 JustHost 暂时用一下待日后再解决主机问题。虽然访问速度比较慢,但是至少不会出现那种打不开的抽风问题,使用 又拍云 进行静态文件加速,应该也不会慢到受不了。

WordPress 迁出 SAE 的步骤

这段虽然比较水,但是还是大体说一下,因为搬出来的时候遇到了一些小插曲,可供后来者参考使用。

WordPress 搬家步骤有很多,我个人比较喜欢的是:导出数据》》在目的主机安装 WordPress 》》导入数据。

这时候,强大的资源外链的作用体现出来了,因为图片等都用外链,所以根本不用管那些资源,直接把数据库内容转移即可。看起来步骤非常简单,但实际上从 SAE 迁移到 JustHost 的过程中遇到了很多问题,折腾了一个下午。

SAE 的数据导出问题

导出 WordPress 的数据有两种方式,第一种是在后台使用“工具”里面的“导出”,导出为 xml 文件,然后在新博客的后台直接导入即可。当然,这是一种不完全的导入方式,虽然说是博客全部的数据,但实际上只有文章、页面、简单的配置数据,一些博客名称什么的内容,还需要自己在新博客后台细微调整。

因为这种方式比较傻瓜,所以优先考虑。这时候出现问题了,SAE 上的 WordPress 无法导出所有的数据,只能导出 34kb 的 xml 数据文件。原因不详,看后台提示可能是因为 SAE 限制了数据查询次数还是其他乱七八糟的东西,反正导不出所有数据。不得已,我拿出前天导出的备份 xml 文件,大约 3M 左右大小。这时候要上传新博客的时候,发现服务商把 php 的上传限制在了 2M 大小。好吧,这种方法还得看你的主机参数配置,所以不是好办法。

SAE 上面也附带了 PHPMyAdmin 那就使用它直接把 MySQL 的数据库内容导出,然后在 JustHost 后台的 PHPMyAdmin 中导入好了。SAE 上的东西肯定都是阉割版的,不知道 PHPMyAdmin 是什么版本的,把数据库导出之后,在 JustHost 后台无法导入,因为某些语句出错。后来经过搜索,发现也有网友迁移的时候,遇到了这种问题。

SAE 还提供了一个他们自己开发的数据库管理服务 Deferred Jobs 可以用来导入导出 MySQL 数据库。因为使用这个服务需要排队等,不是立即生效的,所以官方推荐 4M 一下的数据库用 PHPMyAdmin 导入导出,4M 以上的使用这个服务。不管了,直接用了,其实没过多久就直接导出完毕。

下载下来 sql 文件有 3M 多,而使用 PHPMyAdmin 导出的才有 2M 多一点,我怀疑没有完全导出,难道又是被 SAE 阉割限制了?这次的 sql 文件非常正常,使用 JustHost 的后台 PHPMyAdmin 直接上传导入就可以了。

再全面的检查一下,增加一下固定链接伪静态,把主题文件、插件上传到新博客,这样搬家完成了,顺带升级成了最新版的 WordPress,SAE 上用的是 3.2.1 阉割版的 WordPress 大家都懂的。

感谢 SAE

我从2012年10月16号左右,把 WordPress 博客从 JustHost 迁移到了 SAE,后来总结写了《WordPress 迁移 SAE 完全操作攻略》 这篇文章,下面虽然有评论说看到很多人进去又出来了,但是我觉得我不会。因为我对 SAE 的服务挺有好感的,一直以为 新浪 是大公司,放在上面很安全,不会丢失数据也不会轻易被黑客攻击,可以安心写文章。以至于后面的这段时间,我连数据都没有备份过几次。

截止到今年3月份,博客在 SAE 上面已经5个多月了,这段时间内访问速度还是挺不错的,当然是相对于 JustHost 来说。对于小型的博客来说,花费非常少,我也做了很多优化,消耗资源很少,所以截止到现在的5个月的使用,算起来只花了2块钱的短信验证费,其他都是实名认证送的云豆。

同时通过 SAE,还学到了一些简单的 SVN 使用等。总之,虽然搬出了 SAE 还是要感谢它,日后一些小应用的开发什么的,说不定还会放在上面。感谢 SAE !

为什么不要用 SAE

在刚开始使用 SAE 的时候,对 SAE 充满了好感,曾经强烈推荐周围的朋友试用 SAE,也曾建议 多说 他们使用 SAE 或者 阿里云 主机,这样可以减少成本、人力消耗。因为他们的服务器都是自己购买,自己维护的,如果使用第三方稳定的服务,就可以仅仅专注于 多说 的开发了。但是他们拒绝了,我现在明白了。

东西只有掌握在自己手里,才是最安全的。SAE 或许比一些低端主机靠谱的多,但是为了开发或者资源限制,功能什么的阉割的太严重了。开发、修改等,都得按照他们的套路来,而放在自己的主机或者服务器上,想怎么处理就怎么处理(当然,你得有相关技术),无论是备份还是什么,都是很方便的。我想,多说团队之所以自己维护服务器,就是这个原因吧。

对我个人来说,可能也不会在 SAE 上寄放博客了,因为我本身要折腾 WordPress 所以在自己的主机上折腾比较方便,SAE 上的是早期阉割版本的 WordPress。

博客未来的发展

JustHost 虽然便宜,但是速度实在是比较慢,之前也是因为经常抽风宕机所以才想搬到 SAE 上面的。但是最近手头太紧,买好点的 VPS 又没有足够的资金,此外还有几个筹划中的网站项目等待上线。所以先暂时使用 JustHost,多写一些文章,等访问量大了,也有足够的资金,就会更换好点的主机,例如 linode 啥的。暂时先忍忍吧。