高考完之后,我终于轻松了,可以做自己喜欢的事情,注册了几个域名买空间,开始做网站。于是当然需要有这样一个独立博客。
刚开始的时候,写一些乱七八糟的文章,包括自己的上网经验,计算机使用技巧等等等等。而且质量、排版都很糟糕。
其中还有一段时间(大约在 2011年末 大学第一个寒假)停止了3个多月的更新,重新审视这个博客存在的必要性。
后来在 我爱水煮鱼 上看了 WordPress 主题的制作教程,结合自己的一些 HTML、CSS、PHP 基础,就开始自己做主题。之后思考了两个方向,分别是安卓开发和网页制作。
毕竟有一些网站建设的基础,我最终还是选择了网页制作这个方向。博客也恢复了生机,不断专注的写一些技术文章,制作自己使用的很丑陋的主题,并不断的升级。
由于之前有一些基础,所以学习起来非常快。在 2012年3月 就有了自己第一个小业务,帮一个电影院网站从表格变成 div + css 的,然后进行一下居中优化。
之后不断的买书学习,通过不断的升级主题来实践,在 2012年的暑假末期,我做出了第一套稍微好点的主题,也就是现在的 Qetro,当然还是非常烂的,但是对于当时的我,还是很高兴的。
国庆之后,偶然接到了一个 WordPress 整站的大单,这是第一次接到稍微正规一点的任务。帮客户从零开始,做设计然后转换成 WordPress 主题,安装到客户的网站上。第一次赚那么多钱,很激动的差点没睡着,也让我坚定了这条路。
此间也不断的在博客发表一些总结性的技术文章等,写作风格和技术都随之不断增强,这点翻翻之前的文章都可以看出来。我的人生也从此发生了改变。
后来的单子就源源不断的找上们来,都是通过博客等。
一个偶尔的相遇,让我认识了 Denis ,就是 我爱水煮鱼 的博主。我竟然有幸成为了我爱水煮鱼的兼职作者,昔日经常上去学习膜拜的网站,如今我成了它的一个作者,可以将自己写的文章发上去跟别人交流。
再到后来,各种合作等等等等,都是因为这个博客在帮助我。可以说,这个博客记录了我的人生轨迹也改变了我的人生轨迹。
在高考之后,我重新申请了一套网络 ID,其中就有网名 潜行者m,这个博客就是以网名拼音作为域名的博客。
但是现在看来,这个网名并不好,无论是从国内还是国外的角度。
我爱水煮鱼 之前一直用的是 www.fairyfish.net 这个域名,这个就是 Denis 随便注册的一个拿来用,没想到后来会慢慢变成名博。越到后来,数据越多,访问量越大,越不容易更换域名。但是出于战略的考虑(推销他的 WPJAM 团队),最终还是整站 301 到 blog.wpjam.com 上了。影响还是很大的,特别是在百度这样的垃圾搜索引擎上,至今,你搜索 我爱水煮鱼 ,出现的仍然是老域名,期间也有几次被百度K掉,收录大规模减小。
而谷歌半个月之内,就全部正常了,都转移到 blog.wpjam.com 上了,但无奈国内还是用百度的多。
没错,我也是出于“战略”的考虑,特别是这个名字上的考虑。
本博的停止我也思考了一段时间,毕竟积累了一些人气和友情。不过死亡是为了更好的重生。
下一步,我会建立一个新博客,放置到我个人的名字域名上 yujiangshui.com 。但是并不会 301 转向到新博客上。这个博客的文章内容质量参差不齐,特别是早期写的一些,而且结构目录、标签层次等,经过几次修改整理都非常混乱了,所以我会建立一个全新的网站,从头开始写文章。并且每个月只会更新几篇,目的是为了文章质量,也能更好的体现我的个人水平,让更高质量的合作找上我。
但是这个博客还有非常多的保存价值,所以我不在乎每年几百块的服务器费用,还会放在这里,作为一个留念,但是不会更新文章了,如果想要继续关注本人的文章,可以到新网站去看。
至此,潜行者m 这个 ID 以后也不再会用了,以后直接像张鑫旭大神那样,用真名以及拼音。
]]>.ie{color:red; /* for all browsers*/_color:green; /* hack for IE6*/*color:black; /* hack for IE6 IE7*/color:white\9; /* hack for IE6+(IE6 IE7 IE8 IE9 IE10)*/color:yellow\0; /* hack for IE8+(IE8 IE9 IE10)*/color:orange\9\0; /* hack for IE9+(IE9 IE10)*/}
暂时还没有比较好的 hack 方式,使用一些另类的方法可以实现,但是不太好。此外,IE10 不再支持 IE 条件注释了。也就是说,面对下面的代码,IE10 会直接像其他浏览器那样忽略:
至于为什么,可能是因为微软对 IE10 已经拥有足够的自信,可以做到跟普通正常浏览器效果差不多,不再需要单独的 hack 了吧。
详细的了解 IE10 的更多细节和特性以及新技术,可以观看 MSDN 上的 IE10 develop 部分:http://msdn.microsoft.com/en-us/ie/aa740473
(未完,会继续发现添加。。)
]]>Lorem Ipsum
表示一段随机看不懂的文字。Lorem Ipsum
的文字让人看不懂,这样才能忽略内容的含义而专注内容的排版,作为测试数据填充用的。使用 Emmet 生成 Lorem Ipsum
文本非常简单,只需要使用 lorem
这一条命令即可,敲击 Tab 键之后,就会生成如下一段文字:
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui, dolor, aperiam ab repellendus blanditiis eum exercitationem. Quae, reprehenderit repellat impedit asperiores consequatur? Illum quos magnam odit omnis recusandae natus similique.
h1>lorem10
。但是这项功能对于使用中文的网页测试来说,好像没有多大用处,毕竟中文和英语单词的排版是不同的。写代码一般要用到两只手,有时候需要跳转到别的代码段等,你可以使用键盘方向键也可以使用鼠标。但是这都有缺陷,使用键盘方向键移动太慢了,而且需要按住 shift 键和方向键选中代码;使用鼠标的话,手就必须离开键盘,来回也会浪费一些时间。而 Emmet 提供了一个很实用的功能,就是整块的跳转。
为了方便理解,先看一下官方的 Demo 动画。这个功能,使用 Shift+Ctrl+.
和 Shift+Ctrl+,
分别向下或者向上移动,选取的是一整块,先从标签开始,再是整个属性,再是属性值。这样,比键盘的方向键移动高效多了。
有时候,我们需要给 <img> 标签增加对应的 width、height 属性来表示图片的大小或者给通过 background-image 属性引用的背景图片一个尺寸大小。通常的做法是看一下图片的尺寸,然后加上,而现在,你只需要将光标移动到代码段,摁下 Ctrl+U
即可让 Emmet 自动读取图片的尺寸添加上。前提条件是图片比较存在并且正确引用进来了。
如果是针对 <img> 标签的,会在后面加上 width、height 属性,如果是 background 引入的,会在下面加上 width、height 的 CSS 属性。可以看一下官方的 Demo 。但是这里有个问题,官方的 Demo 中,实现这个功能的快捷键是 Shift+Ctrl+U
但实际使用中,这个快捷键不起作用。关于 Emmet 的 Mac、Win 下的快捷键,以这个页面上的为准:https://github.com/sergeche/emmet-sublime#available-actions。
我们在写 CSS 的时候,有时候为了 hack 写很多带有前缀的属性。例如:
-webkit-transform: rotate(30deg);
-moz-transform: rotate(30deg);
-ms-transform: rotate(30deg);
-o-transform: rotate(30deg);
transform: rotate(30deg);
Shift+Ctrl+R
键即可更新其他的相关属性值。data url 图片具有很多优点,在某些情况下比较实用,但是将图片转换成 data url 格式就比较麻烦了,得使用一些工具。而在 Emmet 中,将光标移动到 background: url() 中的图片位置的地方,按下Ctrl+’
即可将图片编码成 data url 格式。当然,前提条件是图片资源引用正确。
除此之外,Emmet 还有一些其他的诸如快速跳转、计算等等常用功能,在这里只是介绍了几个更常用的功能,有兴趣的朋友可以打开Emmet Action 的官方文档看一下 Demo,这里不再赘述。
]]>text-overflow:ellipsis
属性通常用于隐藏超出长度的文本,并在文本最后面增加省略号。456bereastreet 发现:如果在网页的交互等过程中,出现一个新层(例如鼠标移动到下拉菜单,弹出下拉菜单内容),在 Firefox 下,文本内容当然会被新弹出内容遮住,但是省略号并不会。它会出现在新层的上面。
可以使用 Firefox 打开 Demo 看一下具体效果。
如果你也遇到了这个问题,解决方法很简单,只需要为新弹出的覆盖层的 z-index 属性赋值为 >1
的数值即可,这样就可以解决了。你可以在上面的 Demo 中,使用 Firebug 增加一下。
在网页中,有时候我们会需要一些符号,例如:倒三角 ▼。如果要让网页显示这种符号,显然用字符的方式比较好,体积小到可以忽略不计同时还可以方便用 CSS 定义样式等。但是直接把这个倒三角复制进网页中的话,虽然可以,但是不合理,这时候我们就要用到对应图标的实体字符,例如通过查询可以看到倒三角对应的 Unicode HTML 代码为 & #9660 ;
将前面代码中的空格删掉,复制进 HTML 文件中就可以看到了。
当然,这个 HTML 文件必须保存为 UTF-8 编码,如果你看不懂,推荐这篇文章《网页编码就是那点事》。那么,我该从哪里寻找自己需要的符号呢?
搜索一下就可以看到很多相关内容,但是很多只是列了一部分,或者就是维基百科那样直接给出一个又长又丑的表格。在这里推荐一个网站 Unicode Character Table ,这个网站罗列了所有的 Unicode 字符,同时做了美化,当你点击某个字符的时候,会弹出字符序号和 HTML 实体字符,是不是很方便呢?马上收藏备用吧!网址:http://unicode-table.com
]]>但是这种方法由于浏览器之间滚动的距离不同等缘故,会导致闪烁等问题,只在 Firefox 效果完美。同时会影响性能,在中低端安卓设备中效果很差。这种影响用户体验的事情,是肯定要避免的。还是得回来使用 fixed,但是从未发现过 fixed 失效的情况啊,只能挨个测试一下。
先写了一个 div ,赋值 fixed 属性,然后在普通网页中效果正常。将其插入无效代码平级位置,结果失效。将其插入 body 标签下级,正常。说明问题出在其父属性值中。
然后使用 Firebug 依次取消父属性值,当去掉 transform 属性值之后,fixed 生效。原来问题出在 transform 上。
这是一个坑,如果不知道的,可以记一下。因为 transform 是一个 CSS3 中比较重要的动画属性,以后的应用会越来越多。对于 position 的其他属性尚未测试,因为 fixed 比较特殊,效果比较明显。在 google 上搜索了一下,发现了一篇 Eric 写的 Un-fixing Fixed Elements with CSS Transforms ,不过没看懂,还望各位有知道的指点一下。
]]>基本原理很简单,就是使用 JS 切换对应的 CSS 样式表。例如导航网站 Hao123 的右上方就有网页换肤功能。除了切换 CSS 样式表文件之外,通常的网页换肤还需要通过 Cookie 来记录用户之前更换过的皮肤,这样下次用户访问的时候,就可以自动使用上次用户配置的选项。
那么基本工作流程就出来了:访问网页——JS 读取 Cookie ——如果没有,使用默认皮肤——如果有,使用指定皮肤;用户点击换肤选项——JS 控制替换对应的 CSS 样式表——将皮肤选项写进 Cookie 保存。
首先你可能要准备多套 CSS 样式表文件,当点击换肤按钮的是,使用 JS 来切换对应的 CSS 样式表。之后,就是在网页上增加一个 ul li 列表,用 CSS 修饰一下做成换肤选项。例如:
下面我们就来看具体功能代码。
首先,我们的皮肤选项的 HTML 结构是这样的
<div class="skin"> <ul> <li class="skin1 hover"></li> <li class="skin2"></li> <li class="skin3"></li> <li class="skin4"></li> </ul></div>
然后在网页的顶部偏下的位置放上一个空的 link 标签,我们将会使用 jQuery 为这个 link 标签赋予不同的 CSS 文件实现切换效果
<link rel="stylesheet" href="" data-href="style-Teal.css" type="text/css" media="screen" class="skincsslittle" />
其中,我自定义了一个 data-href 属性来存放系统默认的皮肤,这样当页面加载完成之后,如果 JS 没有检测到 Cookie 中的皮肤信息,就会把 data-href 中的内容赋值上去。之后就是大家熟悉的 jQuery 代码:
jQuery('.skin li').click(function(){ var currentClass = jQuery(this).attr('class'); jQuery(this).siblings().removeClass('hover'); jQuery(this).addClass('hover'); var cc = currentClass.substring(0,5); cc = convertcsslittle(cc); var skincssurl = jQuery('.stylecssurl').attr('href').substring(0,jQuery('.stylecssurl').attr('href').indexOf('style')) + cc; jQuery('.skincsslittle').attr("href",skincssurl); createCookie('skin',currentClass,365);});
大体的逻辑就是获取到当前皮肤的 class 然后截取出来 skin* 然后通过一个函数得到其对应的 CSS 文件。skincssurl 记载的是网页的非皮肤 CSS 文件,主要用来获取当前网页的 CSS 目录 URL ,最后将混合好的 CSS 皮肤文件赋值准备好的空 link 中,实现换肤。
这里主要用到两个自定义的函数,用来创建、读取 Cookie 内容。
function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return false;}function createCookie(name,value,days) { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = "; expires="+date.toGMTString(); } else expires = ""; document.cookie = name+"="+value+expires+"; path=/";}
你只需要把这两个函数复制到 JS 代码区域即可。在 jQuery 点击换肤的功能代码中,最后一句就创建了一个 Cookie,等网页加载完成之后,我们需要使用 JS 读取 Cookie 内容,然后使用 if 判断:
var cccc = readCookie("skin");if (cccc){ cccc = cccc.substring(0,5); jQuery('.'+cccc).addClass('hover').siblings().removeClass('hover'); ccc = convertcsslittle(cccc); var skincssurl = jQuery('.stylecssurl').attr('href').substring(0,jQuery('.stylecssurl').attr('href').indexOf('style')) + ccc; jQuery('.skincsslittle').attr("href",skincssurl);}else{ var currentcss = jQuery('.skincsslittle').attr("data-href"); var currentcssname = currentcss.substring(currentcss.indexOf('style'),currentcss.length); currentcssname = defaulttoclass(currentcssname); jQuery('.'+currentcssname).addClass('hover').siblings().removeClass('hover'); jQuery('.skincsslittle').attr("href",jQuery('.skincsslittle').attr("data-href"));}
不要被这么乱的代码吓晕了,实际上逻辑很简单,先获取 Cookie 的皮肤值,如果有就为对应的皮肤选项高亮并且转换得到对应的 CSS 皮肤文件赋值。如果没有 Cookie 内容,就将 data-href 属性中记录的值赋值进去。
网页换肤中,会遇到闪烁的问题。就是当点击切换按钮的时候,更换颜色或者图片会闪烁一下。或者使用 Cookie 记录之后,用户使用了非默认的皮肤,也会闪烁一下,先出现默认的样式然后再闪烁切换成用户自己选择的样式。
这种影响用户体验的现象肯定要彻底消灭,但是一直没有找到完美的解决方法。因为浏览器默认的是优先渲染 CSS 之后再加载 JS,特别是使用 Cookie 记录的皮肤,先渲染现有的 CSS 之后,JS 才能读取然后切换到皮肤。原理是这样的,跟客户协商之后,客户给出了一个“无闪烁”的换肤效果示例,是 MG12 很早的一款主题。同样的 Cookie 记录等,但是他的作品确实没有闪烁情况。
于是我就查看了他的 JS 代码,没有发现特殊之处,后来才想明白,这种闪烁问题,在图片比较多的网页中效果尤其明显,因为切换的 CSS 需要加载图片需要更多时间。而 MG12 那款主题中,切换的 CSS 文件只是改变了几个 background 颜色,加载速度快到你眼球反应不过来就造成了不闪烁的假象。
不完美解决方案也是有的,点击切换按钮之后的闪烁情况,也是因为要加载图片等,那么我们可以在访问网页的时候,使用预加载技术将其他皮肤图片预加载或者使用 CSS Sprite 技术做成一张大图片。
至于 Cookie 记录闪烁的问题,这是浏览器渲染的硬伤,只能尽量减少换肤需要改变的地方,尽量压缩图片减小体积。然后优先加载没有任何皮肤的基础样式,之后使用 JS 加载默认样式或者读取 Cookie 获取的皮肤选项。这样处理,访问网页的时候会先显示白色或者无颜色,之后直接切换成之前选择的皮肤的颜色,而不会从默认的颜色闪烁变成另一种颜色从而提升一定的用户体验。
如果你在这方面有经验,知道更好的解决闪烁问题的方法,麻烦跟我说一下哈,先谢过了!
]]>距离上次 1.4 版本发布时间 2月8日,已经过去了三个多月了,这么长时间没有改动、升级主题,一个是比较忙没有太多时间,另一个是在不断深入 WordPress ,学到了不少的新东西,准备应用在主题上,一时间难以慢慢消化,所以等有时间一口气重新升级。然后就是本人的拖延症,一拖再拖拖到现在。
这次升级,先从界面开始,几乎又重写了 CSS 文件,而且把原有的 HTML 结构重新正规的命名了下。从极简的角度出发,专注于内容的展示,去掉了绝大部分不必要的内容,保持内容的突出和优化显示。色调进行了统一,不再像之前那样,采用四种颜色,而是使用了 蓝色系 的颜色,在后面将会做多种颜色版。使用了近期流行的响应式布局设计(具体响应式设计还未完成)。然后就是根据官方以及其他成熟主题的做法,更新了很多函数和相关的使用方法,使主题代码更加合理。高度优化边栏样式,增加了跟随滚动模块等等。然后着重编写增强了 1.4 弱爆的评论模块。
目前,2.0 主题的基本界面和功能已经完成,可以上线让大家帮忙测试。但是这仅仅完成了不到 50% 的工作。
我先把未完全完成版上传测试,希望大家能提提建议或者发现一些 Bug 等,如果你有好的想法和建议,下面有我的联系方式,希望能告诉我一下。测试评论模块,多说也先去掉了。
这段时间,我也见到很多关于主题是否应该公开的讨论。有种言论说,主题一旦公开,就死掉了,版权全部被改掉什么都没了。确实有这个问题。而且做一款真正好的主题,真的很不容易,我越来越体会得到。所以,2.0 版本的主题将不会公开发布,同时 1.4 版本的主题做的太烂了,所以将会停止共享。抱歉!
如果不出意外,这套主题将会作为本人自用主题。也有可能因为我最近比较缺钱,搞出个限量版来买然后提供 VIP 服务。这些还需要等主题完全完成再说。
]]>首先,Sublime Text 2 已经提供了比较强大的 CSS 样式所写方法来提高 CSS 编写效率。例如编写 position: absolute; 这一个属性,我们只需要输入 posa 这四个字母即可。它会弹出缩写样式的提示:
你不妨在编写 CSS 的时候,留意一下 ST2 提供了哪些属性的缩写方法,这样就可以提高一定的效率了。但是 Emmet 提供了更多的功能,请往下看。
如果你想生成 width:100px; 你只需要输入 w100 就可以了,因为 Emmet 的默认设置 w 是 width 的缩写,后面紧跟的数字就是属性值。默认的属性值单位是 px ,你可以在值的后面紧跟字符生成单位,可以是任意字符。例如,w100foo 会生成 width:100foo; 这样一条语句。你同样也可以简写属性单位,如果你紧跟属性值后面的字符是 p ,那么将会生成 width:100%; 这样的语句,其中 p 表示百分比单位。与此类似的还有:e
→ em; x
→ ex。
例如 margin 这样的属性,可能并不是一个属性值,生成多个属性值需要用横杠(-)连接两个属性值,因为 Emmet 的指令中是不允许空格的。例如使用 m10-20 这条命令可以生成 margin: 10px 20px; 这样一条语句。如果你想生成负值,多加一条横杠即可。需要注意的是,如果你对每个属性都指定了单位,那么不需要使用横杠分割。例如使用 m10ff20ff 这条命令可以生成 margin: 10ff 20ff; 这条语句,如果你在 20ff 前面加了横杠的话,20ff 就会变成负值了。
如果你想一次生成多条语句,可以使用 ‘+’ 连接两条语句,例如使用 h10p+m5e
可以生成 height: 10%;margin: 5em; 这两条语句。
颜色值也是可以快速生成的,例如 c#3
→ color: #333;,更复杂一点的,使用 <code>bd5#0s
可以生成 border: 5px #000 solid; 这样一句。下面是规则:
#1 → #111111#e0 → #e0e0e0#fc0 → #ffcc00
生成 !important 这条语句也当然很简单,只需要一个 ‘!’ 就可以了。
使用 @f 即可生成 CSS3 中的 font-face 的代码结构:
@font-face {
font-family:;
src:url();
}
但是这个结构太简单,不包含一些其他的 font-face 的属性,诸如 background-image、 border-radius、 font、@font-face、 text-outline、 text-shadow 等属性,我们可以在生成的时候输入 ‘+’ 生成增强的结构,例如我们可以输入 @f+ 命令,即可输出选项增强版的 font-face 结构:
@font-face {
font-family: ‘FontName’;
src: url(‘FileName.eot’);
src: url(‘FileName.eot?#iefix’) format(‘embedded-opentype’),
url(‘FileName.woff’) format(‘woff’),
url(‘FileName.ttf’) format(‘truetype’),
url(‘FileName.svg#FontName’) format(‘svg’);
font-style: normal;
font-weight: normal;
}
CSS3 等现在还没有出正式的 W3C 规范,但是很多浏览器已经实现了对应的功能,仅作为测试只用,所以在属性前面加上自己独特的实验性前缀,不同的浏览器只会识别带有自己规定前缀的样式。然而为了实现兼容性,我们不得不编写大量的冗余代码,而且要加上对应的前缀。使用 Emmet 可以快速生成带有前缀的 CSS3 属性。
ST2 已经内置了一些常见的需要实验性前缀的 CSS3 属性,例如输入 trf 会弹出提示,然后敲击回车键即可生成。而 Emmet 增强了这个功能。在任意字符前面加上一条横杠(-),即可生成该属性的带前缀代码,例如输入 -foo-css,会生成:
-webkit-foo-css: ; -moz-foo-css: ; -ms-foo-css: ; -o-foo-css: ; foo-css: ;
虽然 foo-css 并不是什么属性,但是照样可以生成。此外,你还可以详细的控制具体生成哪几个浏览器前缀或者先后顺序,使用 -wm-trf
即可生成:
-webkit-transform: ; -moz-transform: ; transform: ;
可想而知,w 就是 webkit 前缀的缩写,m 是 moz 前缀缩写,s 是 ms 前缀缩写,o 就是 opera 浏览器前缀的缩写。如果使用 -osmw-abc 即可生成:
-o-abc: ; -ms-abc: ; -moz-abc: ; -webkit-abc: ; abc: ;
CSS3 中新增加了一条属性 linear-gradient 使用这个属性可以直接制作出渐变的效果。但是这个属性的参数比较复杂,而且需要添加实验性前缀,无疑需要生成大量代码。而在 Emmet 中使用 lg() 指令即可快速生成,例如:使用 <code>lg(left, #fff 50%, #000) 可以直接生成:
background-image: -webkit-gradient(linear, 0 0, 100% 0, color-stop(0.5, #fff), to(#000)); background-image: -webkit-linear-gradient(left, #fff 50%, #000); background-image: -moz-linear-gradient(left, #fff 50%, #000); background-image: -o-linear-gradient(left, #fff 50%, #000); background-image: linear-gradient(left, #fff 50%, #000);
直接帮你生成好了浏览器前缀。
Emmet 的还有一些其他的强大功能,将在后面继续讲解介绍,尽请关注。
]]>网站换肤是老东西了,大体的思路就是写上一些 li 作为皮肤选项,点击之后使用 JavaScript 代码,修改网页中引用的 CSS 文件,达到换肤的目的。为了提供更好的用户体验,可以增加 cookie 记录功能,记录当前用户选择的皮肤。当下次用户再访问的时候,先读取 cookie 的内容,然后根据 cookie 内容自动切换到上次选择的皮肤。
很正常的写完了 JavaScript 代码,测试都已经通过,在 IE10 的 IE7、8、9 渲染模式下也测试通过。这时候,客户反馈在 XP 下的 IE8 有问题:初次登陆无法显示默认皮肤、点击切换刷新之后无法显示切换后的皮肤。
因为是通过 cookie 来判断是否显示默认皮肤还是上次用户选择的皮肤,所以很理所当然就想到了无法读取 cookie 。启动 VMware 虚拟机,打开 IE8 和 IE Developer ToolBar 工具进行调试,发现点击之后 cookie 已经成功的创建,但是代码无法执行,使用控制台看了一下问题,原来是不支持 console 。
console 命令是控制台命令,用来调试 JavaScript 代码用的,通常使用 console.log() 函数来代替 alert() 来迅速得到某变量的内容等。由于 XP 下的 IE 不支持 console,导致后续代码无法运行。
解决方法就是删掉所有调试用的语句,这时候已经可以显示默认的皮肤样式了。
这里之所以说某些,是因为我也不知道哪句代码写的不完善。当我使用最基础的 alert(document.cookie) 返回所有的 cookie 内容时,返回值为空,使用 cookie 读取函数读取某值的时候,返回 undefined 。而在其他浏览器中都可以正常返回。
而奇怪的地方在于,我使用 IE developer toolbar 调试的时候,可以看到当前浏览器下面有 cookie 值。最初我以为是 cookie 读取函数写的有问题,因为毕竟有 cookie 的内容却读取不出来。前后换了 5 个不同写法的 cookie 读取函数。后来一想不对,因为使用 alert(document.cookie) 也无法返回任何内容,IE 不会连 document.cookie 都不支持吧?!难道是因为 cookie 生成函数?
这时候,客户给了个功能类似的示例网站,我打开测试了一下功能正常。既然别人的正常,肯定能实现。我阅读了一下它的代码,换肤功能使用的 styleswitcher.js 这个 JS 插件做出来的。由于实现步骤与现有网站不符,我无法使用这个插件整合,只能把它的生成 cookie 、读取 cookie 的函数抠下来用。代码如下:
function readCookie(name) {
var nameEQ = name + “=”;
var ca = document.cookie.split(‘;’);
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==’ ‘) c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return false;
}
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days2460601000));
var expires = “; expires=”+date.toGMTString();
}
else expires = “”;
document.cookie = name+”=”+value+expires+”; path=/“;
}
然后问题就解决了,仔细看了一下代码,我写的也差不多,没有看出问题在哪。日后再仔细研究一下吧,如果你遇到了这样的问题,不妨使用上面这两个函数操作 cookie ,如果你知道问题所在,还望告知!
直接打开 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>
仅供娱乐和恶搞哈,相信应该没有太多人喜欢在访问你网页的时候,听到你网页在放屁哈哈。
]]>现在,打开你的 ST2 然后新建一个 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 标签,我们只需要编写下面指令:
#aaaEmmet 默认的标签为 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>`
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}+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 的技巧。
]]>你可能听说过一款强大的功能相似的工具:Zen Coding,那个比较老了,而现在的 Emmet 则是 Zen Coding 的升级版,由 Zen Coding 的原作者进行开发等。
Emmet 严格意义上来说,并不是一款软件或者工具,它是一款编辑器插件,必须要基于某个编辑器使用。目前它支持如下编辑器:
Sbulime text 2 安装插件肯定要通过 Package Control 这个插件了,如果你还没有安装这个插件,抓紧先去安装一下吧。安装完成之后,我们摁下“shift + ctrl + p”呼出面板,输入“pci”即可锁定“Package Control:Install Package”这个功能,回车之后就可以看到一个列表,我们继续输入“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 键->生成!
]]>CSS3 中的滤镜(filter)功能让我们轻松方便简单的处理图片,而不需要使用 PhotoShop 或者使用很多 JavaScript、PHP 代码。这个属性已经得到比较新的 Firefox、Safari、Chrome 浏览器支持,而且我们可以通过综合的可替代的技术来模拟实现这个效果——甚至是 IE 浏览器。
本文中,我们将使用标准测试图片 Lena Söderberg (译者注:Lena 这张裸体美女照片,被作为图片压缩的标准测试用图片)作为演示,使用 CSS 将其转换成黑白图片。在下面我将讲解如何使用 CSS 的这个功能实现调整色调、模糊、亮度、对比度和一些其他的效果。效果图:
使用 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>
这就可以了。
这个功能目前只在 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 00.3333 0.3333 0.3333 0 00.3333 0.3333 0.3333 0 00 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);}
到现在我们的代码可以兼容未来的浏览器,和最新版的 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 属性,最重要的目的就是作为结构的标识,可以被 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/
应用的话,以后代码就丰富多彩了哈哈。
]]>有时候修改一些网站上的文件,通常是下面这样的流程:使用 FTP/SFTP 连接到远程服务器 -> 下载要修改的文件 -> 使用 ST2 修改文件 -> 保存然后拖进 FTP 中 -> 刷新网站。
很明显这样的工作流程效率很低,特别是你修改一句代码的时候,为了即时生效,也需要重复切换几个窗口重复这个过程。于是就有了 SFTP 这个插件。
它主要功能就是通过 FTP/SFTP 连接远程服务器并获取文件列表,可以选择下载编辑、重命名、删除等等操作,点下载编辑之后,可以打开这个文件进行修改。修改完成之后,保存一下会自动上传到远程的服务器上面。
使用这个插件之后,工作流程就变成了:使用 SFTP 插件打开文件 -> 使用 ST2 编辑修改文件 -> 保存文件 -> 刷新页面。效率提升了至少一倍以上,下面就来介绍一下具体的使用方法。
先要安装这个插件,打开 Sublime Text 2 ,摁下 shift + ctrl + p 键,呼出面板,使用 Package Control 这个插件安装。输入 “pci” 敲击回车,再输入 “sftp” 即可安装这个插件。安装完之后,就要开始配置服务器使用了。
安装完插件之后,找到 “文件” 菜单,找到 “SFTP/FTP” 选项,点击配置:
点击之后,会弹出一个新的窗口,这是一个配置文件
一般就是配置一下我箭头所指的四个参数,包括连接方式、服务器地址、用户名、密码等。如果你的服务器还有其他配置,你也可以对照注释设置一下。一般为了方便,还会设置一下“路径”,这样直接可以看到想要修改的文件列表。
配置完成之后,我们保存,然后输入一个名字作为标识。
还是点击 “文件” 选择 “SFTP/FTP” 中的查看服务器列表
会弹出刚刚配置好的服务器,我们可以点击需要连接的 FTP 服务器,这时候就链接上了并且弹出文件列表
这时候点击一个文件,就可以弹出一些选项
就可以根据你自己的需要,对文件编辑、重命名什么的了。点击编辑之后,会在本地打开,然后可以修改。摁下 ctrl + s 保存文件的时候,就会自动上传文件。
如果需要查看服务器上的别的文件,或者需要更多的功能,可以直接在当前文件中右击,选择 “SFTP/FTP” 就会弹出更多选项可以使用,没法截图所以不再赘述。更多的功能,就交给你自己探索了!
]]>虽然我不认为这会影响一大批人,但是绝大多数人肯定不懂响应式网站设计。如果有个人在电脑、平板电脑或者智能手机上访问同一个网站结果发现外观效果不同,他可能会感到很困惑。Bruce Lawson 在文章 Turning off responsive web design 中就提到了一个真实的例子。
一个同事也提到了另一个案例,响应式布局并没有很完美的客户端支持。客户经常提到布局问题等等。试想一下,如果你收到了一个邮件提到的是关于你用电脑访问看到的外观或内容,那么你用平板或者智能手机可能看不到相同的外观或者内容。当然,这种情况可能不多,但是这时候如果有一个可以切换或者关掉响应式布局的功能就好多了。
尽管这个功能不会让很多人受益,但是做这么个功能也并不是很复杂的事情。所以我在一些项目中增加了这个功能,现在想跟大家分享一下。这个方法跟 Adrian Roselli 写的 Letting Mobile Users See Desktop View of RWD Site 这篇文章中的很相似。这个功能不是很复杂,更不是什么革命性的改进,但是可以通过很多方法来实现。
有必要讨论一下怎么在网页中称呼这个功能。通常的名字是:查看桌面版布局、桌面版、完整版。而我称呼它为:查看固定宽度下的布局(当切换之后变成“查看弹性宽度下的布局”)。我并不确定这样可以帮助用户明白之间的异同,但是我认为这比起“桌面端”和“手机端”来说,描述的更加准确。有些人的浏览器窗口可能比 960px 还窄,也可能比 1200px 窄,或者是他们自己拖动设置的大小,虽然满足了媒体查询中定义的宽度,但是能在网页中显示“切换成桌面版”?
我做了一个 Disable responsive layout 演示页面来展示效果。如果你打开了这个页面,并且调整你的浏览器窗口小于 960px ,一个就跟超链接似的开关就会显示出来,点击就可以切换。我觉得只有在媒体查询工作的时候才显示这个切换开关——如果响应式布局没有被触发,那切换个毛啊。
我选择直接把这个切换链接写进 HTML 中,而不是使用 JavaScript 临时生成。这是因为我使用后台(可以是任何后台语言,本文中使用 PHP 做演示)来处理 cookie ,这样就可以记录你是否选择了禁用响应式布局。
在前面的 demo 页面中,写入了如下的 HTML 结构,你可以自己定义:
<div id="toggle"> <a href="?fixedwidth=1">Switch to fixed width layout</a></div>`</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>`<script>if ( !document.documentElement.className.match(/(\\s|^)fixed(\\s|$)/) ) { // Responsive scripts go here, likely with additional checks // for viewport width, media query support etc.}</script>`</pre>## PHP 代码在本文 Demo 中,我使用 PHP 来处理 cookie 和提供切换响应式布局的功能。你可以使用 JavaScript 来实现这样的功能,但是这样在禁用 JavaScript 的客户端无法生效。毕竟这不是很关键的功能,如果你选择使用 JavaScript 请记住如果客户端不支持 JavaScript 的时候,也要显示出一个可以看到的链接。下面就是一个简单的 HTML 结构和必须的 PHP 代码:<pre>`<?php $fixedwidth = ''; //检查是否有 $fixedwidth 这个变量,然后获取 if ( isset($_GET['fixedwidth']) && ($_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, '/'); }?><!DOCTYPE html><html lang="en" <?php if ($fixedwidth == '1') { echo 'class="fixed"'; } ?>><head> <meta charset="utf-8" /> <title>Document title</title><?php// 只在响应式布局可用的时候插入 meta[name="viewport"] 对象if ( $fixedwidth != '1' ): ?> <meta name="viewport" content="width=device-width, initial-scale=1" /><?php endif; ?> <link rel="stylesheet" href="main.css" /><?php// 只在响应式布局可用的时候,插入 CSS 文件if ( $fixedwidth != '1' ): ?> <link rel="stylesheet" href="mq.css" /><?php endif; ?></head><body> <h1>Document title</h1> <div id="toggle"><?php// Responsive is disabled, so insert a switch to flexible widthif ( $fixedwidth == '1' ): ?> <a href="<?php echo $_SERVER["SCRIPT_NAME"] ?>?fixedwidth=0">Switch to flexible width layout</a><?php// Responsive is not disabled, so insert a switch to fixed widthelse: ?> <a href="<?php echo $_SERVER["SCRIPT_NAME"] ?>?fixedwidth=1">Switch to fixed width layout</a><?php endif; ?> </div> <script> if ( !document.documentElement.className.match(/(\\s|^)fixed(\\s|$)/) ) { // Responsive scripts go here } </script></body></html>
上面的 PHP 代码肯定能进一步改进,这里只是抛砖引玉给你一个思路,你可以自己编写更符合你要求的代码。
你可能会产生浏览器是否应该增加切换响应式布局功能的疑问。浏览器可能需要禁止他们自身对媒体查询的支持,而是通过网站的设置来默认显示“全尺寸”或者“桌面版”。这就是为什么我个人喜好直接开发网站,但是其他开发者却相反的先使用媒体查询功能开发“手机端”的网站,然后再开发“桌面端”布局。
如果你使用媒体查询为老的浏览器隐藏 CSS3 的功能,这也会产生问题。一个浏览器的禁用媒体查询的功能,可能会禁用所有的媒体查询中的代码,这样会产生很多布局的问题。
所以,这个功能应该交给咱们 Web 开发者来做。如果你需要这个功能,上面提供了一个不错的思路。
禁用响应式布局确实是一个必要的功能。Bruce Lawson 在 Turning off responsive web design 这篇文章中,提到了一个小故事。说他的父亲在用手机访问一个网站的时候,发现跟电脑访问时不一样,而怀疑自己是不是在访问想访问的网站,然后关掉了。
潜行者m 曾经使用平板和智能手机做过测试,虽然智能设备上的浏览器通常可以设置“使用什么样的客户端模式(桌面、手机)来访问网站”,但是响应式布局使用的媒体查询技术,直接根据设备的参数等进行改变,不会因为客户端的代理模式(User-Agent)。特别是使用手机想要看到网站的桌面版效果,就很难实现了。
通过 JavaScript 来实现这个功能也非常简单,但是使用 PHP 更加有优势。这样可以减少不必要的 CSS 、JS 文件的引入,增强前端性能。但是 PHP 的移植性不太好。所以也可以考虑使用 JavaScript 来实现。
如果想要你的网站更加完善,如果使用了响应式布局的设计,最好加上一个禁用选项。
]]>就文章的标题来说,本文介绍两个小要点:PHP 获取内容、PHP 解析 JSON 并显示。
你如果想解析 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 进行进一步处理,才能被调用显示在网页中。在 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
细心的朋友会发现 潜行者 m 博客的边栏最下面多了一个“友文推荐”模块,里面推荐了一些琼台博客的文章。
友文推荐是琼台博客倡议的一种博客之间交流方式,比传统的友情链接更有效,同时实现了博客内容互补。由于琼台博客的博客程序是他自己本人编写的,所以他提供了 JSON api 接口,可以获取到最新的可推荐的文章。
本人使用 PHP 获取这个 JSON 接口,然后输出到自己博客的边栏中,下面来实战操作一下。
调用之前,你肯定要看一下对方的 api 调用手册,包括调用地址、如何调用、数据输出格式等等。琼台博客的 api 说明地址如下:http://www.qttc.net/openapi.html。
根据文档,我使用了 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 变量中,因为可以肯定 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 数据的方法大同小异。
]]>有很多方法可以实现预加载,但是这里有三种比较简单实用的方法。
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+ –>
即使看上去只是节省了几百毫秒而已,但是合计起来也是不少的时间。它是一种安全的优化方法同时很容易实现。我很好奇有多少网站使用了这项技术,我打开了 Alexa 排名前 100K 的网站。但是只有 552 个网站(使用率 0.55%)正确的使用了 DNS 预加载技术。这么简单的技术应该被更多的网站使用。
在现在的网站中,网页的大小很大程度上取决于网页中图片的大小。如果提前请求并且下载这些图片,可以有明显的提速效果。大多数情况下,网页作者知道一个图片什么时候需要加载这样就不需要提前在浏览器中声明,例如使用 ajax 或者浏览者浏览页面时触发的一些事件来加载一个图片。资源预加载就是提前让浏览器加载图片、脚本、样式或者其他资源。不仅仅用于加载图片,可以让所有类型的资源提前被缓存在浏览器的缓存中。
这项技术是最久远古老和最经常使用的,抱歉,我无法给出具体的统计数字。仍然有很多网站没有正确的使用这项技术,然而仅仅预加载几张图片就可以制造巨大的用户体验差异。
页面预加载就像资源预加载,不同的是页面预加载提前加载了它本身。这项技术首先在 Firefox 浏览器中可以使用。你可以使用下面的标签来测试一下别的浏览器看看这个页面(或者相关资源)能否被提前加载:
<link href=”/my-next-page.htm” rel=”prefetch” />
<link href=”http://mydomain.com/my-next-page.htm" rel=”prerender” />
预加载一直是有争议的话题。很多人们认为它没有效果而且在浪费宽带。而且它还用到一些不重要的客户端的资源(尤其是很多手机设备)。此外值得一提的是,预加载、预渲染页面可能会导致一些浏览者统计和访问日志记录的问题,因为系统不知道浏览者是否真正访问过这个页面还是通过预加载请求的。
尽管有一些问题,但是预加载还是有很大优势的。请求的速度我们一般无法控制,所以把资源提前尽可能多的放入缓存是我们解决问题的方法。当用户在等待请求的时候,成本太高了,我们可以使用这些技术大大的提升性能。如果你还没有做这些,建议你去应用这些技术到你的网站上。结果可能不一样,所以你可以使用专业工具(例如:Torbit)来检查预加载技术帮你做了多少。
]]>