《CSS3 经典教程系列》上篇文章介绍了 linear-gradient(线性渐变),这篇文章向大家介绍 radial-gradient(径向渐变)以及重复渐变(线性重复、径向重复)。在以前,渐变效果和阴影、圆角效果一样都是做成图片,现在 CSS3 可以直接编写 CSS 代码来实现。
- Web 开发人员和设计师必读文章推荐
- 20个非常绚丽的 CSS3 特性应用演示
- 35个让人惊讶的 CSS3 动画效果演示
- 推荐12个漂亮的 CSS3 按钮实现方案
- 24款非常实用的 CSS3 工具终极收藏
CSS3 径向渐变和线性渐变是很相似的,我们首先来看其语法:
-webkit-radial-gradient([<bg-position> || <angle>,]? [<shape> || <size>,]? <color-stop>, <color-stop>[, <color-stop>]*);
除了您已经在线性渐变中看到的起始位置,方向,和颜色,径向梯度允许你指定渐变的形状(圆形或椭圆形)和大小(最近端,最近角,最远端,最远角,包含或覆盖 (closest-side, closest-corner, farthest-side, farthest-corner, contain or cover))。 颜色起止(Color stops):就像用线性渐变,你应该沿着渐变线定义渐变的起止颜色。下面为了更好的理解其具体的用法,我们主要通过不同的示例来对比CSS3径向渐变的具体用法
示例一:
background: -webkit-radial-gradient(#ace, #f96, #1E90FF);
效果:
示例二:
background: -webkit-radial-gradient(#ace 5%, #f96 25%, #1E90FF 50%);
效果如下:
从以上俩个示例的代码中发现,他们起止色想同,但就是示例二定位了些数据,为什么会造成这么大的区别呢?其实在径向渐变中虽然具有相同的起止色,但是在没有设置位置时,其默认颜色为均匀间隔,这一点和我们前面的线性渐变是一样的,但是设置了渐变位置就会按照渐变位置去渐变,这就是我们示例一和示例的区别之处:虽然圆具有相同的起止颜色,但在示例一为默认的颜色间隔均匀的渐变,而示例二每种颜色都有特定的位置。
示例三:
background: -webkit-radial-gradient(bottom left, circle, #ace, #f96, #1E90FF);
效果如下:
示例四:
background: -webkit-radial-gradient(bottom left, ellipse, #ace, #f96, #1E90FF);
效果如下:
示例三和示例四我们从效果中就可以看出,其形状不一样,示例三程圆形而示例四程椭圆形状,也是就是说他们存在形状上的差异。然而我们在回到两个示例的代码中,显然在示例三中设置其形状为 circle,而在示例四中 ellipse,换而言之在径向渐变中,我们是可以设置其形状的。
示例五:
background: -webkit-radial-gradient(ellipse closest-side, #ace, #f96 10%, #1E90FF 50%, #f96);
效果如下:
示例六:
background: -webkit-radial-gradient(ellipse farthest-corner, #ace, #f96 10%, #1E90FF 50%, #f96);
效果如下:
从示例五和示例六中的代码中我们可以清楚知道,在示例五中我人应用了closest-side而在示例六中我们应用了farthest-corner。这样我们可以知道在径向渐变中我们还可以为其设置大小(Size):size的不同选项(closest-side, closest-corner, farthest-side, farthest-corner, contain or cover)指向被用来定义圆或椭圆大小的点。 示例:椭圆的近边VS远角 下面的两个椭圆有不同的大小。示例五是由从起始点(center)到近边的距离设定的,而示例六是由从起始点到远角的的距离决定的。
示例七:
background: -webkit-radial-gradient(circle closest-side, #ace, #f96 10%, #1E90FF 50%, #f96);
效果如下:
示例八:
background: -webkit-radial-gradient(circle farthest-side, #ace, #f96 10%, #1E90FF 50%, #f96);
效果如下:
示例七和示例八主要演示了圆的近边VS远边 ,示例七的圆的渐变大小由起始点(center)到近边的距离决定,而示例八的圆则有起始点到远边的距离决定。
示例九:
background: -webkit-radial-gradient(#ace, #f96, #1E90FF);
效果如下:
示例十:
background: -webkit-radial-gradient(contain, #ace, #f96, #1E90FF);
效果如下:
示例九和示例十演示了包含圆 。在这里你可以看到示例九的默认圈,同一渐变版本,但是被包含的示例十的圆。
最后我们在来看两个实例一个是应用了中心定位和full sized,如下所示:
background: -moz-radial-gradient(circle, #ace, #f96);
/* Safari 4-5, Chrome 1-9 */
/* Can't specify a percentage size? Laaaaaame. */
background: -webkit-gradient(radial, center center, 0, center center, 460, from(#ace), to(#f96));
/* Safari 5.1+, Chrome 10+ */
background: -webkit-radial-gradient(circle, #ace, #f96);
效果如下:
下面这个实例应用的是Positioned, Sized,请看代码和效果:
本系列文章列表和翻译进度,请移步:Node.js高级编程:用Javascript构建可伸缩应用(〇)
本文对应原文第三部分第七章:Files, Processes, Streams, and Networking:Querying, Reading from, and Writing to Files
文章是从Word复制到过来的,版面有些不一致,可以点这里下载本文的PDF版。
第七章:查询和读写文件
本章内容:
- 处理文件路径
- 从文件路径萃取信息
- 理解文件描述符
- 使用fs.stat()获取文件信息
- 打开,读写,关闭文件
- 避免文件描述符泄露
Node有一组数据流API,可以像处理网络流那样处理文件,用起来很方便,但是它只允许顺序处理文件,不能随机读写文件。因此,需要使用一些更底层的文件系统操作。
本章覆盖了文件处理的基础知识,包括如何打开文件,读取文件某一部分,写数据,以及关闭文件。
Node的很多文件API几乎是UNIX(POSIX)中对应文件API 的翻版,比如使用文件描述符的方式,就像UNIX里一样,文件描述符在Node里也是一个整型数字,代表一个实体在进程文件描述符表里的索引。
有3个特殊的文件描述符——1,2和3。他们分别代表标准输入,标准输出和标准错误文件描述符。标准输入,顾名思义,是个只读流,进程用它来从控制台或者进程通道读取数据。标准输出和标准错误是仅用来输出数据的文件描述符,他们经常被用来向控制台,其它进程或文件输出数据。标准错误负责错误信息输出,而标准输出负责普通的进程输出。
一旦进程启动完毕,就能使用这几个文件描述符了,它们其实并不存在对应的物理文件。你不能读写某个随机位置的数据,(译者注:原文是You can write to and read from specific positions within the file.根据上下文,作者可能少写了个“not”),只能像操作网络数据流那样顺序的读取和输出,已写入的数据就不能再修改了。
普通文件不受这种限制,比如Node里,你即可以创建只能向尾部追加数据的文件,还可以创建读写随机位置的文件。
几乎所有跟文件相关的操作都会涉及到处理文件路径,本章先会将介绍这些工具函数,然后再深入讲解文件读写和数据操作
处理文件路径
文件路径分为相对路径和绝对路径两种,用它们来表示具体的文件。你可以合并文件路径,可以提取文件名信息,甚至可以检测文件是否存在。
Node里,可以用字符串来操处理文件路径,但是那样会使问题变复杂,比如你要连接路径的不同部分,有些部分以 “/”结尾有些却没有,而且路径分割符在不同操作系统里也可能会不一样,所以,当你连接它们时,代码就会非常罗嗦和麻烦。
幸运的是,Node有个叫path的模块,可以帮你标准化,连接,解析路径,从绝对路径转换到相对路径,从路径中提取各部分信息,检测文件是否存在。总的来说,path模块其实只是些字符串处理,而且也不会到文件系统去做验证(path.exists函数例外)。
路径的标准化
在存储或使用路径之前将它们标准化通常是个好主意。比如,由用户输入或者配置文件获得的文件路径,或者由两个或多个路径连接起来的路径,一般都应该被标准化。可以用path模块的normalize函数来标准化一个路径,而且它还能处理“..”,“.”“//”。比如:
var path = require('path');path.normalize('/foo/bar//baz/asdf/quux/..');
// => '/foo/bar/baz/asdf'
连接路径
使用path.join()函数,可以连接任意多个路径字符串,只用把所有路径字符串依次传递给join()函数就可以:
var path = require('path');path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// => '/foo/bar/baz/asdf'
如你所见,path.join()内部会自动将路径标准化。
解析路径
用path.resolve()可以把多个路径解析为一个绝对路径。它的功能就像对这些路径挨个不断进行“cd”操作,和cd命令的参数不同,这些路径可以是文件,并且它们不必真实存在——path.resolve()方法不会去访问底层文件系统来确定路径是否存在,它只是一些字符串操作。
比如:
var path = require('path');path.resolve('/foo/bar', './baz');
// => /foo/bar/baz
path.resolve('/foo/bar', '/tmp/file/');
// => /tmp/file
如果解析结果不是绝对路径,path.resolve()会把当前工作目录作为路径附加到解析结果前面,比如:
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');// 如果当前工作目录是/home/myself/node, 将返回
// => /home/myself/node/wwwroot/static_files/gif/image.gif'
计算两个绝对路径的相对路径
path.relative()可以告诉你如果从一个绝对地址跳转到另外一个绝对地址,比如:
var path = require('path');path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');
// => http://www.cnblogs.com/impl/bbb
从路径提取数据
以路径“/foo/bar/myfile.txt”为例,如果你想获取父目录(/foo/bar)的所有内容,或者读取同级目录的其它文件,为此,你必须用path.dirname(filePath)获得文件路径的目录部分,比如:
var path = require('path');path.dirname('/foo/bar/baz/asdf/quux.txt');
// => /foo/bar/baz/asdf
或者,你想从文件路径里得到文件名,也就是文件路径的最后那一部分,可以使用path.basename函数:
var path = require('path');path.basename('/foo/bar/baz/asdf/quux.html')
// => quux.html
文件路径里可能还包含文件扩展名,通常是文件名中最后一个“.”字符之后的那部分字符串。
path.basename还可以接受一个扩展名字符串作为第二个参数,这样返回的文件名就会自动去掉扩展名,仅仅返回文件的名称部分:
var path = require('path');path.basename('/foo/bar/baz/asdf/quux.html', '.html');
// => quux
要想这么做你首先还得知道文件的扩展名,可以用path.extname()来获取扩展名:
var path = require('path');path.extname('/a/b/index.html');
// => '.html'
path.extname('/a/b.c/index');
// => ''
path.extname('/a/b.c/.');
// => ''
path.extname('/a/b.c/d.');
// => '.'
检查路径是否存在
目前为止,前面涉及到的路径处理操作都跟底层文件系统无关,只是一些字符串操作。然而,有些时候你需要判断一个文件路径是否存在,比如,你有时候需要判断文件或目录是否存在,如果不存在的话才创建它,可以用path.exsits():
var path = require('path');path.exists('/etc/passwd', function(exists) {
console.log('exists:', exists);
// => true
});
path.exists('/does_not_exist', function(exists) {
console.log('exists:', exists);
// => false
});
注意:从Node0.8版本开始,exists从path模块移到了fs模块,变成了fs.exists,除了命名空间不同,其它都没变:
var fs = require('fs');fs.exists('/does_not_exist', function(exists) {
console.log('exists:', exists);
// => false
});
path.exists()是个I/O操作,因为它是异步
在JS中也一样,everything is object,对象是一切的基础。
对象就是包含一组变量和函数的集合实例。通常对象由类派生而来,而类定义了对象拥有的属性和方法。如果你的脚本都是对象之间的交互操作,那么就可以说这个脚本是面向对象的脚本。JavaScript是一种基于原型(ptototype)的面向对象的语言,没有类的概念,所有的一切都派生自现有对象的一个副本。
JS中的对象分为两类:
1、Function对象,例如alert()函数可以使用参数改变此类对象的功能如:alert('kfkf');
2、Object对象,这类对象无法像Function对象那样调用,而且具有固定的功能。
JS中的继承javascript是基于原型的面向对象,这就导致无法从一个类扩展出另一个类的底层类结构。在JS中继承是通过简单的从一个对象原型向别一个对象原型复制方法而实现的。
我们看下面一个例子:
<script type="text/javascript"> function init(){ var person=new Object(); person.getName=function(){ alert('person name'); } person.getAge=function(){ alert('person age'); } //创建另一个对象 var student=new Object(); //创建一个本身的方法 student.getStuNum=function(){ alert('student num'); }; //继承person的getName方法 student.getName=person.getName; //重新定义person的getName方法 person.getName=function(){ alert('person1 name'); } student.getAge=person.getAge; student.getName(); person.getName(); } window.onload=init; </script>
它的结果:
通过这个例子,我们就能理解上面的内容了。
对象成员对象=关联数组=属性包=存储体
在javascript里只有对象访问操作
原型/对象 属性包
原型只存在于function中,它实质就是一个对象被创建后引挚默认创建一个空的prototype对象,既然对象是一个属性包,那么原型也就是一个属性包。
原型中读的时候,从原型链上读,写的时候往自己里写。
请看如下例子:
<script type="text/javascript"> function object2(){}; function object3(){}; object3.prototype=new object2(); Object.prototype.foo=function(){ alert('object.prototype.foo'); }; aObj=new object3(); aObj.foo(); object2.prototype.foo=function(){ alert('object2.prototype.foo'); }; aObj.foo(); </script>
运行结果:第一次:object.prototype.foo 第二次:object2.prototype.foo
下图可以帮助理解:
window对象 覆盖作用域链
看如下例子:
<script type="text/javascript"> function override() { var alert=function(message){ window.alert('override'+message); }; alert('alert'); window.alert('window.alert'); } override(); window.alert('window.alert from outside'); </script>