八月 10, 2010
by 小寒
3 comments
很多网站在填写表单的时候,都可以看到这样一种UI,input[type=text]里面有提示的文字,当鼠标点进去之后提示文字就消失了。关于这种UI,之前有写过文章介绍过http://www.zhoumingzhi.com/?p=182。在本文中主要是介绍以HTML 5的实现方式以及兼容方案。
一,HTML 5的实现方式
HTML 5的input元素引入了placeholder的属性,就是为了实现本文开头所说的效果,代码也很简单。
<input type="text" placeholder="请输入一些文字" />
二,对不支持HTML 5浏览器的兼容方案
对于不支持HTML 5的浏览器,上面的方法就不可行了。但是placeholder这个属性可以利用起来,结合JS实现想达到的效果。下面结合代码说明实现方法:
首先要用JS检测一下浏览器支不支持placeholder这个属性。
(function() {
var tmp = document.createElement("input");
window.supports = {
// 检测input是否支持placeholder特性
placeholder: "placeholder" in tmp
}
})();
如果支持的话就什么也不做,浏览器会帮你实现这个效果。
如果不支持则要写段JS。为了方便说明用到了jQuery,代码如下:
// 绑定input的placeholder
function bindPlaceholder(input) {
if(!window.supports.placeholder) {
var jqInput = $(input),
placeholder = jqInput.attr("placeholder");
if(placeholder) {
if(input.value == "") {
input.value = placeholder;
$(input).addClass("placeholder");
}
jqInput.focus(function() {
if(this.value == placeholder) {
$(this).removeClass("placeholder");
this.value = "";
}
}).blur(function() {
if(this.value == "") {
$(this).addClass("placeholder");
this.value = placeholder;
}
});
}
}
}
上述代码中有个叫placeholder的CSS类,这个主要是让占位符的字体颜色变灰。CSS如下:
.placeholder {
color: #a9a9a9;
}
实现上面的函数之后,就可以在页面初始化的时候调用了。
$("input[placeholder]").each(function() {
bindPlaceholder(this);
});
三,结论
HTML 5中有很多很方便的特性,但是目前不是所有浏览器都支持,所以在用HTML 5的时候要考虑到兼容方案。
UI
八月 2, 2010
by 小寒
0 comments
在很多场景下,要判断一个元素是不是包含另一个元素,总结了一下,有下列的方法:
一,遍历节点树,这个方法是最容易的,也没有什么兼容性问题。在“mouseenter和mouseleave”这篇日志中有演示,可以看一下。
二,对于IE浏览器,DOM元素有个contains的方法可以判断包含关系。比如div1.contains(div2),如果返回的结果为true就说明div1包含了div2,反之亦然。
三,DOM3的Node.compareDocumentPosition方法。
(div1.compareDocumentPosition(div2) & 0×10) === 0×10如果为true的话,说明div1包含div2。
详细的文档见:https://developer.mozilla.org/en/DOM/Node.compareDocumentPosition
四,强大的位置关系函数。
// Compare Position - MIT Licensed, John Resig
function comparePosition(a, b){
return a.compareDocumentPosition ?
a.compareDocumentPosition(b) :
a.contains ?
( a != b && a.contains(b) && 16 ) +
( a != b && b.contains(a) && 8 ) +
( a.sourceIndex >= 0 && b.sourceIndex >= 0 ?
(a.sourceIndex < b.sourceIndex && 4 ) +
(a.sourceIndex > b.sourceIndex && 2 ) :
1 ) :
0;
}
JavaScript
七月 23, 2010
by 小寒
1 comment
Demo
原理:在标准浏览器下用position: fixed的方式就可以了。IE6下面用overlay.className = overlay.className迫使浏览器重新布局,以达到position: fixed的效果。
<!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>出师表</title>
<style type='text/css'>
html, body {
margin: 0;
padding: 0;
}
body {
/* 这里不能加position: relative */
}
#content {
font-family: 微软雅黑;
font-size: 36px;
line-height: 60px;
width: 960px;
margin: 0 auto;
}
#content p {
text-indent: 2em;
}
#overlay {
opacity: .5;
filter: alpha(opacity=50);
background: #ccc;
width: 100%;
height: 100px;
position: fixed;
_position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<div id='content'><p>先帝创业未半,而中道崩殂;今天下三分,益州疲敝,此诚危急存亡之秋也。然侍卫之臣,不懈于内;忠志之士,忘身于外者:盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气;不宜妄自菲薄,引喻失义,以塞忠谏之路也。宫中府中,俱为一体;陟罚臧否,不宜异同:若有作奸犯科,及为忠善者,宜付有司,论其刑赏,以昭陛下平明之治;不宜偏私,使内外异法也。侍中、侍郎郭攸之、费依、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下:愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰"能",是以众议举宠为督:愚以为营中之事,事无大小,悉以咨之,必能使行阵和穆,优劣得所也。亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也!侍中、尚书、长史、参军,此悉贞亮死节之臣也,愿陛下亲之、信之,则汉室之隆,可计日而待也。</p><p>臣本布衣,躬耕南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,谘臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间:尔来二十有一年矣。先帝知臣谨慎,故临崩寄臣以大事也。授命以来,夙夜忧虑,恐付托不效,以伤先帝之明;故五月渡泸,深入不毛。今南方已定,甲兵已足,当奖帅三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都:此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、依、允等之任也。愿陛下托臣以讨贼兴复之效,不效则治臣之罪,以告先帝之灵;若无兴复之言,则责攸之、依、允等之咎,以彰其慢。陛下亦宜自谋,以谘诹善道,察纳雅言,深追先帝遗诏。臣不胜受恩感激!今当远离,临表涕泣,不知所云。</p>
</div>
<div id='overlay'></div>
<!--[if IE 6]>
<script type="text/javascript">
(function(){
var overlay = document.getElementById('overlay'), t;
window.onscroll = function() {
t && clearTimeout(t);
t = setTimeout(function() {
// reflow
overlay.className = overlay.className;
}, 13);
};
})();
</script>
<![endif]-->
</body>
</html>
CSS, JavaScript, UI
七月 21, 2010
by 小寒
0 comments
今天下午有人在群里提出个问题,能不能把自定义样式应用到HTML 5中的range元素上。晚上研究了一下,是可以实现上述的需求的。请用Chrome查看Demo。代码如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>自定義樣式的input[type=range]</title>
<style type="text/css">
#range {
width: 600px;
height: 10px;
background: rgba(60, 114, 230, .8);
border: 1px solid #333;
-webkit-border-radius: 5px;
-webkit-appearance: none !important;
}
#range::-webkit-slider-thumb{
width: 28px;
height: 28px;
background: -webkit-gradient(
linear,
left top,
left bottom,
from(#fff),
to(#ccc)
);
border: 1px solid #000;
-webkit-box-shadow: 0 0 6px #000;
-webkit-border-radius: 14px;
-webkit-appearance: none !important;
}
#result {
border: 2px solid #ccc;
width: 32px;
}
</style>
</head>
<body>
<input type='range' min='0' max='1000' value='0' id='range' />
<input type='text' id='result'/>
<script type='text/javascript'>
var result = document.getElementById('result');
document.getElementById('range').onchange = function() {
result.value = this.value;
}
</script>
</body>
</html>
代码中的”-webkit-appearance: none !important”很重要,要先把-webkit-appearance设置为none才能自定义样式。
CSS, HTML
七月 8, 2010
by 小寒
0 comments
C#版
static Func<T, TResult> Fix<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> f)
{
return x => f(Fix(f))(x);
}
static Func<T1, T2, TResult> Fix<T1, T2, TResult>(Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> f)
{
return (x, y) => f(Fix(f))(x, y);
}
JavaScript版
var Y = function (F) {
return (function (x) {
return F(function (y) { return (x(x))(y);});
})
(function (x) {
return F(function (y) { return (x(x))(y);});
}) ;
} ;
应用
// var g = λf.λn.(n <= 1 ? 1 : n * f(n - 1))
var g = function(f) {
return function(n) {
if(n <= 1) {
return 1
} else {
return n*f(n-1);
}
}
}
alert(Y(g)(5))
C#, JavaScript
七月 6, 2010
by 小寒
1 comment
在firebug下面用console.debug($(‘a’))打印jQuery()返回值时,会发现控制台输出是一个数组,但我们知道jQuery()返回的确实一个对象,只不过这个对象有length属性和数字的下标,最重要的是还有一个splice方法。只要满足这三点,就会在控制台输出一个数组。自己建了个例子模拟一下。
function Foo() {
return new Foo.prototype.init();
}
Foo.prototype = {
init: function() {
this.length = 1;
this[0] = 'hello world';
return this;
},
say: function() {
alert('hi');
},
length: 0,
splice: [].splice
}
Foo.prototype.init.prototype = Foo.prototype;
Foo();
PS: 如果想用firebug打印完整的jQuery对象,请用console.dir()。
JavaScript
七月 2, 2010
by 小寒
0 comments
做了一下动态生成内容的客户端缓存测试,记录一下用到的代码。
C#的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Globalization;
namespace WebApplication
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class demo : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// 设置缓存的秒数。
TimeSpan timeout_duration = TimeSpan.FromSeconds(10);
context.Response.ContentType = "application/javascript";
context.Response.Cache.SetCacheability(HttpCacheability.Public);
DateTime modifiedSince;
// 解析请求的头的If-Modified-Since信息。
DateTime.TryParse(context.Request.Headers["If-Modified-Since"], DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.AdjustToUniversal, out modifiedSince);
DateTime utcNow = DateTime.UtcNow;
if (modifiedSince.AddTicks(timeout_duration.Ticks) < utcNow)
{
// 内容已过期,重新生成信息,响应200。
context.Response.Cache.SetMaxAge(timeout_duration);
context.Application["counter"] = int.Parse(context.Application["counter"].ToString()) + 1;
context.Response.Cache.SetLastModified(utcNow);
context.Response.StatusCode = 200;
context.Response.Write(string.Format("document.write({0})", context.Application["counter"]));
}
else
{
// 内容未更改,响应304。
context.Response.Cache.SetMaxAge(modifiedSince + timeout_duration - utcNow);
context.Response.Cache.SetLastModified(modifiedSince);
context.Response.StatusCode = 304;
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
php的代码:
<?php
// 设置缓存的秒数。
$timeout_duration = 10;
// 解析请求的头的If-Modified-Since信息。
// 按CTRL+F5强制刷新的时候,这里将被设置为NULL。
$client_time_stamp = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
$client_time_stamp = (isset($client_time_stamp)? strtotime($client_time_stamp): 0);
$now = time();
$server_now_time_str = gmdate('D, d M Y H:i:s'). ' GMT';
header('Content-Type: application/javascript');
if(($client_time_stamp + $timeout_duration) < $now) {
// 内容已过期,重新生成信息,响应200。
header("Last-Modified: $server_now_time_str", true, 200);
header("Cache-Control: max-age={$timeout_duration}");
$micro = microtime();
$script = <<<SCRIPT
document.write('{$micro} <br />');
SCRIPT;
echo $script;
} else {
// 内容未更改,响应304。
header("Last-Modified: {$_SERVER['HTTP_IF_MODIFIED_SINCE']}", true, 304);
$max_age = $client_time_stamp + $timeout_duration - $now;
header("Cache-Control: max-age={$max_age}");
}
exit(0);
?>
ASP.NET, 个人日记
六月 28, 2010
by 小寒
0 comments
文章部分内容来自:RGBa Browser Support
老版本的IE不支持RGBa的背景色,不过我们可以用滤镜实现同样的效果。上代码:
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<style type="text/css">
#div1 {
padding: 10px;
width: 380px;
height: 205px;
background: url(shuizhu.jpg);
}
#div2 {
color: #FFF;
font-size: 40px;
font-weight: bold;
text-align: center;
height: 205px;
line-height: 205px;
background: rgba(125, 0, 0, .3);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#4B7D0000
,endColorstr=#4B7D0000);
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">
Hello world!
</div>
</div>
</body>
</html>
DXImageTransform.Microsoft.gradient滤镜里的startColorstr参数值是#AARRGGBB形式的,其中的AA是代表不透明度的十六进制,00表示完全透明,FF就是全不透明,化成十进制的范围就是0~255,剩下的RRGGBB就是颜色的十六进制代码。例子中background: rgba(125, 0, 0, .3);表示的是30%不透明度的红色背景。如何把30%的不透明度转换成十六制呢?很简单,先计算#AA的的十进制x,x/255 = 3/10,解得x=3*255/10,然后再把x换算成十六进制,约等于4B。
下面附上示例中用到的图片:

CSS
六月 26, 2010
by 小寒
3 comments
一,什么是.clearfix
很多网站都讲到一个盒子清除内部浮动时可以用到.clearfix。
.clearfix:after {
content: " ";
display: block;
clear: both;
height: 0;
}
.clearfix {
zoom: 1;
}
<div class="clearfix">
<div class="floated"></div>
</div>
上面的代码就是.clearfix的定义和应用,简单的说下.clearfix的原理:
二,总结
在IE6, 7下面只要是触发了hasLayout的元素就可以清除内部浮动了。而在标准浏览器下面清除元素内部浮动的方法有很多,大多数的情况下.clearfix:after都可以满足需求。除了.clearfix:after这种方式,其余的方法无非就是产生新的Block Formatting Context以达到目的……
CSS
六月 24, 2010
by 小寒
10 comments
转载须写明出处,附带本文链接。关于文中的示例,请忘掉IE浏览器,用标准浏览器查看。
一,啥是Block Formatting Context
当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。
为了让我们有个感性的认识,举个不太合适的例子。你可以把一个页面想象成大的集装箱,这个集装箱里装的货物就是HTML元素。在现实生活中为了避免不同人的货物相互混淆,都是把货物打好包装再装入集装箱,这样的话无论你包装里面的货物怎么摆放,都不会影响到其他人的货物。那么这个包装就可以被想象成Block Formatting Context。
二,怎样才能形成Block Formatting Context
当一个HTML元素满足下面条件的任何一点,都可以产生Block Formatting Context
- float的值不为none。
- overflow的值不为visible。
- display的值为table-cell, table-caption, inline-block中的任何一个。
- position的值不为relative和static。
三,Block Formatting Context在生产中有什么作用
-
Block Formatting Context可以阻止边距折叠(margin collapsing)。我们知道在一般情况下,两个上下相邻的盒子会折叠它们垂直方向接触到的边距,这种情况只会发生在同一个Block Formatting Context中。换句话说,在同一个布局环境中(Block Formatting Context)是边距折叠的必要条件。这也就是为什么浮动的元素和绝对定位元素不会发生边距折叠的原因(当然还有很多种情况也不会折叠)。
- Block Formatting Context可以包含内部元素的浮动。考虑一下下面的例子(请用标准浏览器查看):
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<style type="text/css">
html, body {
margin: 0;
padding: 0;
}
#red, #orange, #yellow, #green {
width: 100px;
height: 100px;
float: left;
}
#red {
background: red;
}
#orange {
background: orange;
}
#yellow {
background: yellow;
}
#green {
background: green;
}
</style>
</head>
<body>
<div id="c1">
<div id="red"></div>
<div id="orange"></div>
</div>
<div id="c2">
<div id="yellow"></div>
<div id="green"></div>
</div>
</body>
</html>
在上面的代码本意是做一个两行两列的布局,但是由于#red, #orange, #yellow, #green这四个div同在一个布局环境中,即便通过#c1, #c2这两个div划分,浮动之后它们还会一个接着一个排列,并不会换行。我们要做的就是把这四个div两两划分到不同的布局环境之中,从而闭合浮动。通过上面的分析,让#c1形成新的Block Formatting Context就可以解决问题。
- Block Formatting Context可以阻止元素被浮动覆盖。请看示例:
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<style type="text/css">
html, body {
margin: 0;
padding: 0;
}
#left {
width: 100px;
height: 100px;
background: red;
float: left;
}
#right {
height: 200px;
background: yellow;
}
</style>
</head>
<body>
<div id="left"></div>
<div id="right"></div>
</body>
</html>
在标准浏览器下可以看到,普通的#right元素被浮动的#left元素所覆盖了。要想避免这种情况,有一种方法就是让#right形成新的Block Formatting Context。但是这里一定要注意的是,浮动不会覆盖的只是Block Formatting Context的border-box。换句话说,形成Block Formatting Context元素的margin还是会被浮动所覆盖掉的。
如果想全面了解Block Formatting Context,请看CSS 101: Block Formatting Context这篇文章。
CSS, 原创