本相关的属性一般具有继承性,即给祖先设置的样式,同样被后代标签所继承。
通常具有继承性样式
在实践过程中,通常我们会 设置一些通用的全局属性,比如背景色、字号等, 设置在 HTML的body标签上,这样默认的所有body下的子标签都具有了此样式。
在继承的情况下,选择器权重失效(了解选择器权重)从而遵循 就近原则, 标签会选择距离自己最近的样式。
今年国庆假期终于可以憋在家里了不用出门了,不用出去看后脑了,真的是一种享受。这么好的光阴怎么浪费,睡觉、吃饭、打豆豆这怎么可能(耍多了也烦),完全不符合我们程序员的作风,赶紧起来把文章写完。
这篇文章比较基础,在国庆期间的业余时间写的,这几天又完善了下,力求把更多的前端所涉及到的关于文件上传的各种场景和应用都涵盖了,若有疏漏和问题还请留言斧正和补充。
以下是本文所涉及到的知识点,break or continue ?
原理很简单,就是根据 http 协议的规范和定义,完成请求消息体的封装和消息体的解析,然后将二进制内容保存到文件。
我们都知道如果要上传一个文件,需要把 form 标签的enctype设置为multipart/form-data,同时method必须为post方法。
那么multipart/form-data表示什么呢?
multipart互联网上的混合资源,就是资源由多种元素组成,form-data表示可以使用HTML Forms 和 POST 方法上传文件,具体的定义可以参考RFC 7578。
multipart/form-data 结构
看下 http 请求的消息体
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDCntfiXcSkPhS4PN 表示本次请求要上传文件,其中boundary表示分隔符,如果要上传多个表单项,就要使用boundary分割,每个表单项由———XXX开始,以———XXX结尾。
每一个表单项又由Content-Type和Content-Disposition组成。
Content-Disposition: form-data 为固定值,表示一个表单元素,name 表示表单元素的 名称,回车换行后面就是name的值,如果是上传文件就是文件的二进制内容。
Content-Type:表示当前的内容的 MIME 类型,是图片还是文本还是二进制数据。
解析
客户端发送请求到服务器后,服务器会收到请求的消息体,然后对消息体进行解析,解析出哪是普通表单哪些是附件。
可能大家马上能想到通过正则或者字符串处理分割出内容,不过这样是行不通的,二进制buffer转化为string,对字符串进行截取后,其索引和字符串是不一致的,所以结果就不会正确,除非上传的就是字符串。
不过一般情况下不需要自行解析,目前已经有很成熟的三方库可以使用。
至于如何解析,这个也会占用很大篇幅,后面的文章在详细说。
使用 form 表单上传文件
在 ie时代,如果实现一个无刷新的文件上传那可是费老劲了,大部分都是用 iframe 来实现局部刷新或者使用 flash 插件来搞定,在那个时代 ie 就是最好用的浏览器(别无选择)。
DEMO
这种方式上传文件,不需要 js ,而且没有兼容问题,所有浏览器都支持,就是体验很差,导致页面刷新,页面其他数据丢失。
HTML
<form method="post" action="http://localhost:8100" enctype="multipart/form-data">
选择文件:
<input type="file" name="f1"/> input 必须设置 name 属性,否则数据无法发送<br/>
<br/>
标题:<input type="text" name="title"/><br/><br/><br/>
<button type="submit" id="btn-0">上 传</button>
</form>
复制代码
服务端文件的保存基于现有的库koa-body结合 koa2实现服务端文件的保存和数据的返回。
在项目开发中,文件上传本身和业务无关,代码基本上都可通用。
在这里我们使用koa-body库来实现解析和文件的保存。
koa-body 会自动保存文件到系统临时目录下,也可以指定保存的文件路径。
然后在后续中间件内得到已保存的文件的信息,再做二次处理。
NODE
/**
* 服务入口
*/
var http=require('http');
var koaStatic=require('koa-static');
var path=require('path');
var koaBody=require('koa-body');//文件保存库
var fs=require('fs');
var Koa=require('koa2');
var app=new Koa();
var port=process.env.PORT || '8100';
var uploadHost=`http://localhost:${port}/uploads/`;
app.use(koaBody({
formidable: {
//设置文件的默认保存目录,不设置则保存在系统临时目录下 os
uploadDir: path.resolve(__dirname, '../static/uploads')
},
multipart: true // 开启文件上传,默认是关闭
}));
//开启静态文件访问
app.use(koaStatic(
path.resolve(__dirname, '../static')
));
//文件二次处理,修改名称
app.use((ctx)=> {
var file=ctx.request.files.f1;//得道文件对象
var path=file.path;
var fname=file.name;//原文件名称
var nextPath=path+fname;
if(file.size>0 && path){
//得到扩展名
var extArr=fname.split('.');
var ext=extArr[extArr.length-1];
var nextPath=path+'.'+ext;
//重命名文件
fs.renameSync(path, nextPath);
}
//以 json 形式输出上传文件地址
ctx.body=`{
"fileUrl":"${uploadHost}${nextPath.slice(nextPath.lastIndexOf('/')+1)}"
}`;
});
/**
* http server
*/
var server=http.createServer(app.callback());
server.listen(port);
console.log('demo1 server start ...... ');
复制代码
CODE
https://github.com/Bigerfe/fe-learn-code/
者:张鑫旭(@张鑫旭)
网址:http://www.zhangxinxu.com/wordpress/2016/03/know-about-css3-all/
一、兼容性
一些CSS文章,或者CSS文档,兼容性什么的都是放在最后。
又不是什么见不得人的事情,来,直接开篇就亮刺刀。
兼容性还行, 除了IE不支持,其他浏览器基本上都绿油油,目前自娱自乐,内网项目什么的都是可以用用的。
二、all是干嘛用的
all属性实际上是所有CSS属性的缩写,表示,所有的CSS属性都怎样怎样,但是,不包括unicode-bidi和direction这两个CSS属性。
为什么会有这个CSS属性呢?
我们可能知道,有些CSS属性值基本上所有CSS属性都有,比方说继承inherit!
我们CSS reset输入框的时候,是不是有类似这样的代码(实际可能是具体值,作用类似):
input, textarea {
color: inherit;
font-size: inherit;
font-family: inherit;
}
因为这类输入控件自身有内置的大小和字体,需要重置。
此时,大家就会发现,这些属性值都是inherit, 要是可以合并就好了!
哟哟哟,说到点子上了,CSS all属性就是用来合并的。
input, textarea {
all: inherit;
}
喔噢,三合一,顿时一阵春风拂面之感。但是,这里仅仅是展示作用,实际上是不会这么用的,因为,all:inherit会让背景色什么的,都继承父级,相信这不是你希望看到的。
三、语法和区别
语法如下:
all: initial;
all: inherit;
all: unset;
/* CSS4特性,无视之 */
all: revert;
支持三个CSS通用属性值,initial, inherit, unset. 这三个属性值分别表示什么意思呢?
您可以狠狠地点击这里:CSS3 all属性演示demo(http://www.zhangxinxu.com/study/201603/css3-all.html)
默认的HTML和CSS是这样的,一个传统的标签内容,有标题有列表:
<article>
<h6>标题</h6>
<p>p变文字</p>
<ol>
<li>有序列表1</li>
<li>有序列表2</li>
<li>有序列表3</li>
</ol>
<textarea>文本域</textarea>
</article>
article {
background-color: #f0f3f9;
color: green;
}
article > textarea {
border: 1px solid #34538b;
background-color: #ffffe0;
color: red;
}
这盛世,如你所见:
颜色啊,间距啊,以及文本域状态都是我们认为的样子显示。
现在,点击demo的下拉,选择对应的all属性值,实现下面CSS效果:
.initial > * {
all: initial;
}
.inherit > * {
all: inherit;
}
.unset > * {
all: unset;
}
结果:
initial
initial是初始值的意思,也就是,article元素下面所有的第一级子元素都除了unicode-bidi和direction以外的CSS都使用初始值。
例如,<h6>, <p>元素浏览器内置的display:block直接拜拜了,都变成了inline元素,因此在一行显示:
font-size也使用了浏览器软件本身设置的大小16px,color颜色也变成了浏览器软件本身的黑色。例如,在浏览器设置中改变字号,从中变成大:
会看到显示的文字内容也变大了:
由于我们只是对相邻层级子元素进行了initial设置,因此,<li>元素不受影响,但是,由于在父元素不明的情况下,<li>元素的默认是打点,因此,这里从数字变成了点,list-style-type和list-style-position都变化了。
inherit
inherit是继承的意思,也就是,article元素下面所有的相邻子元素都除了unicode-bidi和direction以外的CSS都继承了<article>元素的CSS。
因此,<h6>, <p>元素还是块状的,background-color都是<article>元素的背景色,color颜色也跟<article>一样,是绿色(文本域的红色被干掉了)。
不仅上面这些CSS,padding/margin也都继承了,只是默认是0, 看不出来,我们稍微修改下,例如给<article>元素来个margin值:
结果,那些子元素都开花了:
unset
unset是取消设置的意思,也就是,article元素下面所有的相邻子元素除了unicode-bidi和direction以外的CSS都干掉都不要,不要了那用什么呢?unset值的特性如下,当前元素浏览器或用户设置的CSS忽略,然后如果是具有继承特性的CSS,如color, 则使用继承值;如果是没有继承特性的CSS属性,如background-color, 则使用初始值。
因此,<h6>, <p>元素的display属性值使用了initial初始值,因此变成了inline元素,两个同一行显示了;而这些元素的color颜色使用了inherit继承值,因此都是绿色,<textarea>的背景色background-color不具有继承特性,因此使用的是initial初始值,也就是transparent透明,因此,就是截图所示效果。
三、结语
动手写文章之前,还以为这个CSS属性会有意想不到的妙用,最后结果是,表现确实意想不到,至于妙用,我只能科科一下。
all所牵扯的CSS实在是太多了,我目前还是想不出有什么场景,就是要用这个CSS属性。或者说什么时候,希望特殊的元素一下子变成普通元素,例如,input输入框外面一个div,来个input{all:inherit;},貌似还真有这样的场景,输入框不需要border不需要background不需要padding不需要margin, 恩,不错,不枉写此文了!
更多精彩内容在微信公众平台:网页设计自学平台
干货!免费领取Adobe高级讲师前端教程
点我领取
*请认真填写需求信息,我们会在24小时内与您取得联系。