跳到主要内容

· 阅读需 2 分钟

接上一篇文章,图片在谷歌浏览器上使用的时候没有问题,但是在手机上测试的时候就卡在那不动了,然后我测试了安卓我们的app和手机自带浏览器都不行,又测试了苹果我们的app不行,微信和safari是可以的。

然后我就和我们的安卓小哥说让他帮我看看log,结果发现canvas.toBlob is undefined。

原因: blog方法兼容性不是很好,所以需要兼容一下 解决办法: 发现了这个网址解决了问题 https://github.com/blueimp/JavaScript-Canvas-to-Blob; 使用方法很简单,只需要把canvas-to-blob.js或者canvas-to-blob.min.js在之前引入就好了。然后下面原来的方法该怎么用就怎么用,就没有问题了。

var canvas = document.createElement('canvas');
if (canvas.toBlob) {
canvas.toBlob(function (blob) {
//do something
},
'image/jpeg'
);
}

· 阅读需 4 分钟

单图片做完之后发现手机拍照照片都很大,基本都在4、5M,上传速度有些慢,然后就寻找方法,开始想使用图片转base64给后台,但是发现后台不支持base64,然后寻求他路,发现给以把图片转换成canvas进行压缩。

代码如下(还是需要依赖jq)

html

<div class="imgUpload">
<input type="file" accept="image/*" capture="camera" class="imgUploadIpt">
<img src="1.png" alt="">
</div>

css

.imgUpload {
width: 88px;
height: 88px;
position: relative;
}
.imgUpload input[type='file'] {
width: 100%;
height: 100%;
opacity: 0;
position: absolute;
z-index: 2;
}
.imgUpload img {
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
}

js

function ImgUpload(ele, files, options ) {
this.ele = ele;//点击的input元素
this.files = files;//图片file
this.compression = options.compression || false;//是否开启压缩默认否
this.maxWidth = options.maxWidth || 800;//压缩最大宽度
this.maxHeight = options.maxHeight || 800;//压缩最大高度
this.callback = options.callback;//回调
this.init();
}
ImgUpload.prototype = {
init: function () {
this.onChangeUploadFile();
},
onChangeUploadFile: function () {
var _this = this;
//判断文件是否添加进来
if (this.files.length == 0) {
return false;
}
var file = this.files[0];
//判断上传的是不是图片
if (file.type.indexOf('image') === -1) {
alert("您上传的不是图片!");
return false;
}
//上传图片进行最大限制
var filesize = Math.floor((file.size) / 1024);
if (filesize > 1024 * 20) {
alert("上传大小不能超过20M.");
return false;
}
this.ele.parent().find("img").attr("src", window.URL.createObjectURL(file));
if( !this.compression ) {
if (this.callback) {
this.callback( file );
}
}else {
// 压缩图片需要的一些元素和对象
var reader = new FileReader(), img = new Image();
//result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容
reader.readAsDataURL(file);
// 文件base64化,以便获知图片原始尺寸
reader.onload = function(e) {
img.src = e.target.result;
};
// 缩放图片需要的canvas
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
img.onload = function () {
// 图片原始尺寸
var originWidth = this.width;
var originHeight = this.height;
// 最大尺寸限制
var maxWidth = _this.maxWidth, maxHeight = _this.maxHeight;
// 目标尺寸
var targetWidth = originWidth, targetHeight = originHeight;
// 图片尺寸超过限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
} else {
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
}
}
// canvas对图片进行缩放
canvas.width = targetWidth;
canvas.height = targetHeight;
// 清除画布
context.clearRect(0, 0, targetWidth, targetHeight);
// 图片压缩
context.drawImage(img, 0, 0, targetWidth, targetHeight);
// canvas转为blob返回
canvas.toBlob(function (blob) {
if (_this.callback) {
_this.callback( blob );
}
}, file.type || 'image/png');
};
}
}
}

$('.imgUploadIpt').on('change', function (event) {
new ImgUpload($(this), event.target.files, {
compression: true, //开启压缩默认不压缩
maxWidth: 600, //开启压缩图片最大宽度
maxHeight: 600, //开启压缩图片最大高度
callback:function (file) {//回调函数
console.log(file);
}
})
})
具体效果点击这里

参考地址 https://www.zhangxinxu.com/wordpress/2017/07/html5-canvas-image-compress-upload/;

· 阅读需 3 分钟

原来判断一个元素是否在页面显示区域中,需要使用scroll事件进行监听判断,现在有了IntersectionObserver就方便了很多。

用法为

var io = new IntersectionObserver(callback, option);

IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:callback是可见性变化时的回调函数,option是配置对象(该参数可选)。

// 开始观察

io.observe(document.getElementById('example'));

// 停止观察

io.unobserve(element);

// 关闭观察器

io.disconnect();
var io = new IntersectionObserver(
entries => {
entries.forEach(i => {
console.log('Time: ' + i.time);
console.log('Target: ' + i.target);
console.log('IntersectionRatio: ' + i.intersectionRatio);
console.log('rootBounds: ' + i.rootBounds);
console.log(i.boundingClientRect);
console.log(i.intersectionRect);
console.log('================');
});
},
{
/* Using default options. Details below */
}
);
// Start observing an element
// 多次调用
io.observe(document.querySelector('#a'));
io.observe(document.querySelector('#b'));

返回的属性如下

time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
target:被观察的目标元素,是一个 DOM 节点对象
rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
boundingClientRect:目标元素的矩形区域的信息
intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0

这里面返回的值里面有位置信息,就可以搞事情了。

看一下兼容性

虽然兼容还不是很好,要是这个方法主流兼容了就很好了。以后一定是一个好方法。

想要学习更多的请借一步前往阮大大这里看

http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html

· 阅读需 1 分钟

刚开始学些flutter,安装配置的时候遇到了点小问题,配置流程我就不发了,网上很多,我的学习地址是这个,可以参考。技术胖的这篇教程; 我只要是记录我在使用Android Studio运行flutter的时候出现的问题。

出现问题如下图

我是没搞懂这是什么问题,然后就请教了一下我们公司做Android的大神,他来我这一看,就找到了问题。

看着两个图,文件配置的版本号为27,虚拟机的版本号为28 两个版本号没有对上,然后我把27改成28,在debug一下就跑起来了。

闻道有先后,术业有专攻。

还是要多多学习。

· 阅读需 2 分钟

业务需求,移动端app需要一个单图片上传的功能,并且只允许照相,不允许从本地选取,本来想使用webUploader来做,配置好了,发现一个问题只能上传一次,在次上传,缩略图不替换(也有可能这个插件我没配置使用好,此处不做过多纠结),然后就参考写了一个。

代码如下(需要依赖jq)

html

<div id="imgUpload">
<img src="upload.png" alt=""><!--upload.png为初始显示背景图-->
</div>

css

#imgUpload {
width: 88px;
height: 88px;
}
#imgUpload img {
width: 100%;
height: 100%;
}

js

//图片上传
function ImgUpload(id, options) {
this.me = $(id);
this.callback = options.callback;
this.init();
}
ImgUpload.prototype = {
init: function () {
this.eventClickInit();
},
eventClickInit:function () {
var self = this;
this.me.unbind().click(function() {
self.createImageUploadDialog();
})
},
onChangeUploadFile: function() {
var fileInput = this.fileInput;
var files = fileInput.files;
if (files.length == 0) {
return false;
}
var file = files[0];
if (file.type.indexOf('image') === -1) {
alert("您上传的不是图片!");
return false;
}
var img = window.URL.createObjectURL(file);
var filename = file.name;
var filesize = Math.floor((file.size) / 1024);
if (filesize > 1024 * 20) {
alert("上传大小不能超过20M.");
return false;
}
this.me.find("img").attr("src", img);
this.me.find("img").attr("title", filename);
if (this.callback) {
this.callback(files);
}
},
createImageUploadDialog: function() {
var fileInput = this.fileInput;
if (!fileInput) {
fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.name = 'ime-images';
fileInput.accept = 'image/*';
fileInput.capture = 'camera';//只允许照相
fileInput.multiple = false;//不允许多选
fileInput.onchange = this.onChangeUploadFile.bind(this);
this.fileInput = fileInput;
}
fileInput.click();
}
}

//调用方法
var dragImgUpload = new ImgUpload("#imgUpload",{
callback:function (files) {
var imgFile = files[0];
console.log(imgFile);
//do something 调取接口进行上传等操作。
}
});

具体效果点击这里

· 阅读需 2 分钟

默认的radio、checkbox的样式比较单一,往往达不到我们想要的效果,所以需要自定义我们需要的样子。

先来看一下最终效果图吧。

基础布局如下

<div class="radioBox">
<label>
<input class="radioInput" type="radio" name="single" value="5">
<span class="radioSpan"></span>5
</label>
<label>
<input class="radioInput" type="radio" name="single" value="4">
<span class="radioSpan"></span>4
</label>
<label>
<input class="radioInput" type="radio" name="single" value="3">
<span class="radioSpan"></span>3
</label>
<label>
<input class="radioInput" type="radio" name="single" value="2">
<span class="radioSpan"></span>2
</label>
<label>
<input class="radioInput" type="radio" name="single" value="1">
<span class="radioSpan"></span>1
</label>
</div>
<div class="checkBox">
<label>
<input class="checkInput" type="checkbox">
<span class="checkSpan"></span>喜欢
</label>
<label>
<input class="checkInput" type="checkbox">
<span class="checkSpan"></span>好看
</label>
<label>
<input class="checkInput" type="checkbox">
<span class="checkSpan"></span>耐用
</label>
</div>

样式是这样的

然后我们把我们想要的样式赋予我们添加的span标签,添加css样式。

.radioSpan {
background-color:transparent;
border: 1px solid #B5B5B5;
border-radius:100%;
display:inline-block;
width:13px;
height:13px;
vertical-align:middle;
line-height:0;
margin-right: 5px;
}
.radioInput:checked + .radioSpan {
border: 1px solid #16A096;
}
.radioInput:checked + .radioSpan:after {
background-color:#16A096;
border-radius:100%;
content:"";
display:inline-block;
height:9px;
margin:2px;
width:9px;
}

.checkSpan {
background-color:transparent;
border: 1px solid #B5B5B5;
display:inline-block;
width:13px;
height:13px;
vertical-align:middle;
line-height:0;
margin-right: 5px;
}

.checkInput:checked + .checkSpan {
width: 15px;
height: 15px;
background: url('checkedSelect.png') no-repeat center center;
background-size: 15px 15px;
border: none;
}

然后在看一下样式

然后我们在把原来的input标签隐藏就好了

.radioInput {
display: none;
}
.checkInput {
display: none;
}

这样就可以看到开始的效果了。

这里样式全部是分开写的,方便理解。。

· 阅读需 9 分钟

空闲时间看到俩CSS,var()、mask 没遇到过,比较好奇,学习一下。

CSS变量var()语法

上来先看看是怎么写的,我就是被这惊奇的写法吸引到了。

See the Pen var() by 周艳伟 (@zywkuo) on CodePen.

var 哇 css怎么用到了var,什么鬼。

原来这是css原生的变量,CSS中原生的变量定义语法是:--,变量使用语法是:var(--),其中*表示我们的变量名称。关于命名这个东西,各种语言都有些显示,例如CSS选择器不能是数字开头,JS中的变量是不能直接数值的,但是,在CSS变量中,这些限制通通没有

但是,不能包含$,[,^,(,%等字符,普通字符局限在只要是“数字[0-9]”“字母[a-zA-Z]”“下划线_”和“短横线-”这些组合,但是可以是中文,日文或者韩文。

看一下兼容性

我们广大的猿友们,努努力吧IE干掉吧。

有想了解更多的,请来张鑫旭,张大大空间,看看他的这篇文章https://www.zhangxinxu.com/wordpress/2016/11/css-css3-variables-var/

声明一下,上面和下面一点关系都没有,只是同时看到了,就一起学习一下。

mask

遮罩mask的功能就是使用透明的图片或渐变遮罩元素的背景. 我用我的大白话理解一下,就是把图片的透明处变为不透明,不透明的地方变成透明。(如有错误,欢迎指正。)所以jpg的还是就算了吧,放了也是全透明,没什么效果,开始我放了jpg的,找了半天原因。

遮罩mask是一个复合属性

  • mask-image
  • mask-mode
  • mask-repeat
  • mask-position
  • mask-clip
  • mask-origin
  • mask-size
  • mask-type
  • mask-composite

mask-image

默认值为none,值为透明图片,或透明渐变 mask-image遮罩所支持的图片类型非常的广泛,可以是url()静态图片资源,格式包括JPG,PNG以及SVG等都是支持的;也可以是动态生成的图片,例如使用各种CSS3渐变绘制的图片。语法上支持CSS3各类渐变,以及url()功能符,image()功能符,甚至element()功能符。同时还支持多背景,因此理论上,使用mask-image我们可以遮罩出任意我们想要的图形,非常强大。

html

<img src="1.jpg" alt="" class="mask">

1.jpg图片是这个

放上这段css

.mask {
width: 600px;
-webkit-mask-image: url(3.svg);
mask-image: url(3.svg);
}

3.svg长这样

运行结果这样

mask-repeat

mask-repeat属性的默认值是repeat,行为类似于background-repeat属性。

属性

mask-repeat: repeat-x;      //水平x平铺
mask-repeat: repeat-y; //垂直y平铺。
mask-repeat: repeat; //默认值,水平和垂直平铺。
mask-repeat: no-repeat; //不平铺
mask-repeat: space; //表示遮罩图片尽可能的平铺同时不发生任何剪裁。
mask-repeat: round; //表示遮罩图片尽可能靠在一起没有任何间隙,同时不发生任何剪裁。

mask-position

mask-position和background-position支持的属性值和表现基本上都是一模一样的。 例如,mask-position默认计算值是0% 0%,也就是相对左上角定位。

支持单个关键字(缺省关键字的解析为center):

mask-position: top;
mask-position: bottom;
mask-position: left;
mask-position: right;
mask-position: center;

支持垂直和水平方向两个关键字:

mask-position: right top;

支持各类数值:

mask-position: 30% 50%;<
mask-position: 10px 5rem;

由于mask-image支持多遮罩图片,因此,mask-position也支持多属性值,例如:

mask-position: 0 0, center;

这个我就不具体上图片了,想必大家都懂了。 想看的请跳到张大大这里看一下吧,https://www.zhangxinxu.com/study/201711/mask-position-png.html

mask-clip

mask-clip属性性质上和background-clip类似,但是mask-clip支持的属性值要多一点,主要是多了个SVG元素的mask-clip支持。

属性值

mask-clip: content-box;
mask-clip: padding-box;
mask-clip: border-box;
mask-clip: fill-box;
mask-clip: stroke-box;
mask-clip: view-box;
mask-clip: no-clip;

其中默认值是border-box和background-clip类似。同样也支持多属性值:

mask-clip: content-box, border-box;

谷歌测试了一下,全员out!!!!!!晕 火狐也全员out,什么鬼,难道和笔记本有关(我的是mac)..这个还有待测试。

mask-origin

属性值

mask-origin: content-box;
mask-origin: padding-box;
mask-origin: border-box;
mask-origin: fill-box;
mask-origin: stroke-box;
mask-origin: view-box;

其中默认值是border-box和background-origin类似。同样也支持多属性值:

mask-origin: content-box, border-box;

测试结果依旧全员out!!!!!!

mask-size

mask-size属性性质上和background-size类似,支持的属性值也类似,作用是控制遮罩图片尺寸。

默认值是auto.

属性值

mask-size: cover;
mask-size: contain;

支持各类数值(缺省高度会自动计算为auto):

mask-size: 50%;
mask-size: 3em;
mask-size: 12px;

mask-size: 50% auto;
mask-size: 3em 25%;
mask-size: auto 6px;

同样支持多属性值:

mask-size: 50%, 25%, 25%;
mask-size: 6px, auto, contain;

mask-type

mask-type属性功能上和mask-mode类似,都是设置不同的遮罩模式。但还是有个很大的区别,那就是mask-type只能作用在SVG元素上,本质上是由SVG属性演变而来,因此,Chrome等浏览器都是支持的。但是mask-mode是一个针对所有元素的CSS3属性,Chrome等浏览器并不支持,目前仅Firefox浏览器支持。

由于只能作用在SVG元素上,因此默认值表现为SVG元素默认遮罩模式,也就是默认值是luminance,亮度遮罩模式。如果需要支持透明度遮罩模式,可以这么设置:

mask-type: alpha;

mask-composite

mask-composite表示当同时使用多个图片进行遮罩时候的混合方式

属性值

mask-composite: add;            //遮罩累加。
mask-composite: subtract; //遮罩相减。也就是遮罩图片重合的地方不显示。意味着遮罩图片越多,遮罩区域越小。
mask-composite: intersect; //遮罩相交。也就是遮罩图片重合的地方才显示遮罩。
mask-composite: exclude; //遮罩排除。也就是后面遮罩图片重合的地方排除,当作透明处理。

这个属性浏览器支持也不是很好。。。

mask-mode

默认值为match-source,意思是根据资源的类型自动采用合适的遮罩模式。

mask-mode支持下面3个属性值:

.mask {
mask-mode: alpha;
mask-mode: luminance;
mask-mode: match-source;
}

因为mask-image支持多图片,因此mask-mode也支持多属性值,例如:

mask-mode: alpha, match-source;

这个属性浏览器支持效果还不是很好。

看一下浏览器兼容性吧。

虽然支持还不是很好,但是好东西不怕晚,欢迎指正。

学习的是张鑫旭,张大大的这篇文章https://www.zhangxinxu.com/wordpress/2016/11/css-css3-variables-var/

· 阅读需 32 分钟

CSS 网格布局(Grid Layout) 是CSS中最强大的布局系统。 这是一个二维系统,这意味着它可以同时处理列和行,不像 flexbox 那样主要是一维系统。 你可以通过将CSS规则应用于父元素(成为网格容器)和该元素的子元素(网格元素),来使用网格布局。

引言

CSS网格布局(又名“网格”)是一个二维的基于网格的布局系统,其目的只在于完全改变我们设计基于网格的用户界面的方式。 CSS一直用来布局网页,但一直都不完美。 一开始我们使用table 做布局,然后转向浮动、定位以及inline-block,但所有这些方法本质上都是 Hack 的方式,并且遗漏了很多重要的功能(例如垂直居中)。 Flexbox的出现在一定程度上解决了这个问题,但是它的目的是为了更简单的一维布局,而不是复杂的二维布局(Flexbox和Grid实际上一起工作得很好)。 只要我们一直在制作网站,我们就一直在为解决布局问题不断探索, 而Grid是第一个专门为解决布局问题而生的CSS模块。

有两个东西,启发我写这篇指南。 第一个是雷切尔·安德鲁(Rachel Andrew)的书为CSS Grid布局准备。 这本书对网格布局做了彻底、清晰的介绍,也是是整篇文章的基础,我强烈建议你购买并阅读他的书。 我的另一个重要灵感是Chris Coyier的Flexbox完全指南,当需要查阅 flexbox 的一切资料时我就会找这篇文章。 这篇文章帮助了很多人学习 Flex 布局,也是 Google 上搜索“flexbox”关键字排名第一的文章。你会发现他的文章和我的很多相似之处,有最好的范例在那放着为什么咱不偷师学着写呢?

本指南的目的是介绍网格概念,因为它们存在于最新版本的规范中。 因此我不会覆盖过时的IE语法,而且随着规范的成熟,我会尽最大努力保存更新本指南。

基础知识以及浏览器支持情况

一开始你需要使用display:grid把容器元素定义为一个网格,使用grid-template-columns和grid-template-rows设置列和行大小,然后使用grid-column 和 grid-row把它的子元素放入网格。 与flexbox类似,网格子元素的原始顺序不重要。 你的可以在 CSS 里以任意顺序放置它们,这使得使用媒体查询重新排列网格变得非常容易。 想象一下,我们需要定义整个页面的布局,然后为了适应不同的屏幕宽度完全重新排列,我们只需要几行CSS就能实现这个需求。 网格是有史以来最强大的CSS模块之一。

截至2017年3月,许多浏览器都提供了原生的、不加前缀的对CSS Grid的支持,比如 Chrome(包括Android),Firefox,Safari(包括iOS)和Opera。 另一方面,Internet Explorer 10和11支持它,但需要使用过时的语法。 Edge浏览器已经宣布将支持标准的Grid语法,但暂未支持。

浏览器支持的详细数据可在Caniuse查看。其中里面的数字表示该版本以上的浏览器支持Grid。

桌面浏览器

Chrome      Opera       Firefox     IE      Edge    Safari
57 44 52 11* 16 10.1

移动端 / 平板

iOS Safari      Opera Mobile    Opera Mini  Android     Android Chrome      Android Firefox
10.3 No No 62 62 57

除了微软之外,浏览器制造商在 Grid 规范完全落地以前似乎并没有放手让 Gird 野生也长的打算。 这是一件好事,这意味着我们不需要再去学习各种浏览器兼容版本的旧语法。

在生产环境中使用Grid只是时间问题,但现在是我们该学习的时候了。

重要术语

在深入了解网格的概念之前,理解术语是很重要的。 由于这里所涉及的术语在概念上都是相似的,如果不先记住它们在网格规范中定义的含义,则很容易将它们彼此混淆。 但是不用太担心,这些术语并不多。

Grid Container

设置了 display: gird 的元素。 这是所有 grid item 的直接父项。 在下面的例子中,.container 就是是 grid container。

<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>

Grid Item

Grid 容器的孩子(直接子元素)。下面的 .item 元素就是 grid item,但 .sub-item不是。

<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>

Grid Line

这个分界线组成网格结构。 它们既可以是垂直的(“column grid lines”),也可以是水平的(“row grid lines”),并位于行或列的任一侧。 下面例中的黄线就是一个列网格线。

Grid Track

两个相邻网格线之间的空间。 你可以把它们想象成网格的列或行。 下面是第二行和第三行网格线之间的网格轨道。

Grid Cell

两个相邻的行和两个相邻的列网格线之间的空间。它是网格的一个“单元”。 下面是行网格线1和2之间以及列网格线2和3的网格单元。

Grid Area

四个网格线包围的总空间。 网格区域可以由任意数量的网格单元组成。 下面是行网格线1和3以及列网格线1和3之间的网格区域。

Grid 属性列表

Grid Container 的全部属性

  • display
  • grid-template-columns
  • grid-template-rows
  • grid-template-areas
  • grid-template
  • grid-column-gap
  • grid-row-gap
  • grid-gap
  • justify-items
  • align-items
  • justify-content
  • align-content
  • grid-auto-columns
  • grid-auto-rows
  • grid-auto-flow
  • grid

Grid Items 的全部属性

  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end
  • grid-column
  • grid-row
  • grid-area
  • justify-self
  • align-self

父容器(Grid Container)的属性

display

将元素定义为 grid contaienr,并为其内容建立新的网格格式化上下文(grid formatting context)。

值: grid – 生成一个块级(block-level)网格(主要的还是使用这个属性,想要使用grid,就要先设置这个值) inline-grid – 生成一个行级(inline-level)网格 subgrid – 如果你的 grid container 本身就是一个 grid item(即,嵌套网格),你可以使用这个属性来表示你想从它的父节点获取它的行/列的大小,而不是指定它自己的大小。

.container {
display: grid | inline-grid | subgrid;
}

注意:column, float, clear, 以及 vertical-align 对一个 grid container 没有影响

grid-template-columns / grid-template-rows

使用以空格分隔的多个值来定义网格的列和行。这些值表示轨道大小(track size),它们之间的空格代表表格线(grid line)。

.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}

例子: (如果未显示的给网格线命名),轨道值之间仅仅有空格时,网格线会被自动分配数字名称:

.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}

但你可以给网格线指定确切的命名。 注意中括号里的网格线命名语法:

.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}

需要注意的是,一个网格线可以有不止一个名字。例如,这里第2条网格线有两个名字:row1-end 和 row2-start:

.container {
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}

如果你的定义中包含重复的部分,则可以使用repeat() 符号来简化写法:

.container {
grid-template-columns: repeat(3, 20px [col-start]) 5%;
}

上面的写法和下面等价:

.container {
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}

“fr”单位允许您将轨道大小设置为网格容器自由空间的一部分。 例如,下面的代码会将每个 grid item 为 grid container 宽度的三分之一:

.container {
grid-template-columns: 1fr 1fr 1fr;
}

自由空间是在排除所有不可伸缩的 grid item 之后计算得到的。 在下面的示例中,fr单位可用的自由空间总量不包括50px:

.container {
grid-template-columns: 1fr 50px 1fr 1fr;
}

grid-template-areas

通过引用 grid-area属性指定的网格区域的名称来定义网格模板。 重复网格区域的名称导致内容扩展到这些单元格。 点号表示一个空单元格。 语法本身提供了网格结构的可视化。

值:

<grid-area-name> – 使用 grid-area 属性设置的网格区域的名称 . – 点号代表一个空网格单元 none – 没有定义网格区域 举例:

.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}

.container {
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}

这将创建一个四列宽三行高的网格。 整个第一行将由 header 区域组成。 中间一行将由两个 main 区域、一个空单元格和一个 sidebar 区域组成。 最后一行是footer区域组成。 你的声明中的每一行都需要有相同数量的单元格。

您可以使用任意数量的相邻的.来声明单个空单元格。 只要这些点号之间没有空格,他们就代表了一个单一的单元格。

需要注意的是你不是在用这个语法命名网格线,而是在命名区域。 当你使用这种语法时,区域两端的网格线实际上是自动命名的。 比如,如果网格区域的名称是foo,那么区域的起始的行网格线和列网格线名称是 foo-start,并且区域终点的行网格线和列网格线名称是 foo-end。 这意味着某些网格线可能有多个名称,比如上面的例子中最左边的一条网格线有三个名字:header-start,main-start 和 footer-start。

grid-template

在单个声明中定义 grid-template-rows、grid-template-columns、grid-template-areas 的简写。

值:

none – 将三个属性都设置为其初始值 subgrid – 把 grid-template-rows 和 grid-template-columns 设置为 subgrid, 并且 grid-template-areas 设置为初始值 grid-template-rows / <grid-template-columns – 把 grid-template-columns 和 grid-template-rows 设置为指定值, 与此同时, 设置 grid-template-areas 为 none

.container {
grid-template: none | subgrid | <grid-template-rows> / <grid-template-columns>;
}

它也可以使用一个更复杂但相当方便的语法来指定这三个值。 一个例子:

.container {
grid-template:
[row1-start] "header header header" 25px [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}

以上等价于:

.container {
grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
grid-template-areas:
"header header header"
"footer footer footer";
}

由于 grid-template 不会重置隐式网格属性(grid-auto-columns,grid-auto-rows和grid-auto-flow),而这可能是大多数情况下你想要做的。因此建议使用grid属性来代替grid-template。

grid-column-gap / grid-row-gap

指定网格线的大小,你可以把它想象为设置列/行之间的间距的宽度。

值:

line-size – 一个长度值

.container {
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}

举例:

.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px;
grid-row-gap: 15px;
}

只能在列/行之间创建缝隙,而不是在外部边缘创建。

grid-gap

grid-row-gap 和 grid-column-gap 的缩写

.container {
grid-gap: <grid-row-gap> <grid-column-gap>;
}

Example:

.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-gap: 10px 15px;
}

如果没有指定 grid-row-gap,则会被设置为与 grid-column-gap 相同的值。

justify-items

沿着行轴对齐网格内的内容(与之对应的是 align-items, 即沿着列轴对齐),该值适用于容器内的所有的 grid items。

值:

start: 内容与网格区域的左端对齐 end: 内容与网格区域的右端对齐 center: 内容位于网格区域的中间位置 stretch: 内容宽度占据整个网格区域空间(这是默认值)

.container {
justify-items: start | end | center | stretch;
}

举例:

.container {
justify-items: start;
}

.container{
justify-items: end;
}

.container {
justify-items: center;
}

.container {
justify-items: stretch;
}

也可以通过给单个 grid item 设置justify-self属性来达到上述效果。

align-items

沿着列轴对齐grid item 里的内容(与之对应的是使用 justify-items 设置沿着行轴对齐),该值适用于容器内的所有 grid items。

值:

start: 内容与网格区域的顶端对齐 end: 内容与网格区域的底部对齐 center: 内容位于网格区域的垂直中心位置 stretch: 内容高度占据整个网格区域空间(这是默认值)

.container {
align-items: start | end | center | stretch;
}

举例:

.container {
align-items: start;
}

.container {
align-items: end;
}

.container {
align-items: center;
}

.container {
align-items: stretch;
}

也可以通过给单个 grid item 设置align-self属性来达到上述效果。

justify-content

有时,网格的总大小可能小于其网格容器的大小。如果你的所有 grid items 都使用像px这样的非弹性单位来设置大小,则可能发生这种情况。此时,你可以设置网格容器内的网格的对齐方式。 此属性沿着行轴对齐网格(与之对应的是 align-content, 沿着列轴对齐)。

值:

start – 网格与网格容器的左边对齐 end – 网格与网格容器的右边对齐 center – 网格与网格容器的中间对齐 stretch – 调整g rid item 的大小,让宽度填充整个网格容器 space-around – 在 grid item 之间设置均等宽度的空白间隙,其外边缘间隙大小为中间空白间隙宽度的一半 space-between – 在 grid item 之间设置均等宽度空白间隙,其外边缘无间隙 space-evenly – 在每个 grid item 之间设置均等宽度的空白间隙,包括外边缘

.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}

举例:

.container {
justify-content: start;
}

.container {
justify-content: end;
}

.container {
justify-content: center;
}

.container {
justify-content: stretch;
}

.container {
justify-content: space-around;
}

.container {
justify-content: space-between;
}

.container {
justify-content: space-evenly;
}

align-content

有时,网格的总大小可能小于其网格容器的大小。如果你的所有 grid items 都使用像px这样的非弹性单位来设置大小,则可能发生这种情况。此时,你可以设置网格容器内的网格的对齐方式。 此属性沿着列轴对齐网格(与之对应的是 justify-content, 即沿着行轴对齐)。

值:

start – 网格与网格容器的顶部对齐 end – 网格与网格容器的底部对齐 center – 网格与网格容器的中间对齐 stretch – 调整 grid item 的大小,让高度填充整个网格容器 space-around – 在 grid item 之间设置均等宽度的空白间隙,其外边缘间隙大小为中间空白间隙宽度的一半 space-between – 在 grid item 之间设置均等宽度空白间隙,其外边缘无间隙 space-evenly – 在每个 grid item 之间设置均等宽度的空白间隙,包括外边缘

.container {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}

举例:

.container {
align-content: start;
}

.container {
align-content: end;
}

.container {
align-content: center;
}

.container {
align-content: stretch;
}

.container {
align-content: space-around;
}

.container {
align-content: space-between;
}

.container {
align-content: space-evenly;
}

grid-auto-columns / grid-auto-rows

指定自动生成的网格轨道(又名隐式网格轨道)的大小。 隐式网格轨道在你显式的定位超出指定网格范围的行或列(使用 grid-template-rows/grid-template-columns)时被创建。

值:

<track-size> – 可以是一个长度值,一个百分比值,或者一个自由空间的一部分(使用 fr 单位)

.container {
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;
}

为了说明如何创建隐式网格轨道,思考如下代码:

.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px
}

这里创建了一个 2×2的网格。

但是,现在想象一下,使用 grid-column 和 grid-row 来定位你的网格项目,如下所示:

.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}

这里我们指定 .item-b开始于列网格线 5 并结束于在列网格线 6,但我们并未定义列网格线 5 或 6。因为我们引用不存在的网格线,宽度为0的隐式轨道的就会被创建用与填补间隙。我们可以使用 grid-auto-columns 和 grid-auto-rows属性来指定这些隐式轨道的宽度:

.container {
grid-auto-columns: 60px;
}

grid-auto-flow

如果你存在没有显示指明放置在网格上的 grid item,则自动放置算法会自动放置这些项目。 而该属性则用于控制自动布局算法的工作方式。

值:

row – 告诉自动布局算法依次填充每行,根据需要添加新行 column – 告诉自动布局算法依次填充每列,根据需要添加新列 dense – 告诉自动布局算法,如果后面出现较小的 grid item,则尝试在网格中填充空洞

.container {
grid-auto-flow: row | column | row dense | column dense
}

需要注意的是,dense 可能导致您的 grid item 乱序。

举例, 考虑如下 HTML:

<section class="container">
<div class="item-a">item-a</div>
<div class="item-b">item-b</div>
<div class="item-c">item-c</div>
<div class="item-d">item-d</div>
<div class="item-e">item-e</div>
</section>

你定义一个有5列和2行的网格,并将 grid-auto-flow 设置为 row(这也是默认值):

.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}

当把 grid item 放在网格上时,你只把其中两个设置了固定的位置:

.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}

因为我们将 grid-auto-flow 设置为row,所以我们的grid就像这样。 注意观察我们没有做设置的三个项目(item-b,item-c和item-d)是如何在剩余的行水平摆放位置的:

如果我们将 grid-auto-flow 设置为 column,则 item-b,item-c 和 item-d 以列的顺序上下摆放:

.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: column;
}

grid

在单个属性中设置所有以下属性的简写:grid-template-rows,grid-template-columns,grid-template-areas,grid-auto-rows,grid-auto-columns和grid-auto-flow。 它同时也将 sets grid-column-gap 和 grid-row-gap 设置为它们的初始值,即使它们不能被此属性显示设置。

值:

none – 将所有子属性设置为其初始值

<grid-template-rows> / <grid-template-columns> – 将 grid-template-rows 和 grid-template-columns 分别设置为指定值,将所有其他子属性设置为其初始值
<grid-auto-flow> [<grid-auto-rows> [ / <grid-auto-columns>] ] – 接受所有与grid-auto-flow,grid-auto-rows和grid-auto-columns相同的值。 如果省略grid-auto-columns,则将其设置为为grid-auto-rows指定的值。

如果两者都被省略,则它们被设置为它们的初始值

.container {
grid: none | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [/ <grid-auto-columns>]];
}

举例:

以下代码写法等价

.container {
grid: 200px auto / 1fr auto 1fr;
}
.container {
grid-template-rows: 200px auto;
grid-template-columns: 1fr auto 1fr;
grid-template-areas: none;
}

以下代码写法等价

.container {
grid: column 1fr / auto;
}
.container {
grid-auto-flow: column;
grid-auto-rows: 1fr;
grid-auto-columns: auto;
}

它也可用使用一个更复杂但相当方便的语法来一次设置所有内容。 你可以指定 grid-template-areas、grid-template-rows 以及 grid-template-columns,并将所有其他子属性设置为其初始值。 你现在所做的是在其网格区域内,指定网格线名称和内联轨道大小。 可以看下面的例子:

.container {
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}

上述代码等价于

.container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
}

孩子(Grid Items)的属性

grid-column-start / grid-column-end / grid-row-start /grid-row-end

使用特定的网格线确定 grid item 在网格内的位置。grid-column-start/grid-row-start 属性表示grid item的网格线的起始位置,grid-column-end/grid-row-end属性表示网格项的网格线的终止位置。

值:

<line>: 可以是一个数字来指代相应编号的网格线,也可使用名称指代相应命名的网格线
span <number>: 网格项将跨越指定数量的网格轨道
span <name>: 网格项将跨越一些轨道,直到碰到指定命名的网格线
auto: 自动布局, 或者自动跨越, 或者跨越一个默认的轨道
.item {
grid-column-start: <number> | <name> | span <number> | span <name> | auto
grid-column-end: <number> | <name> | span <number> | span <name> | auto
grid-row-start: <number> | <name> | span <number> | span <name> | auto
grid-row-end: <number> | <name> | span <number> | span <name> | auto
}

举例:

.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start
grid-row-end: 3
}

.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2
grid-row-end: span 2
}

如果没有声明 grid-column-end / grid-row-end,默认情况下,该网格项将跨越1个轨道。

网格项可以相互重叠。 您可以使用z-index来控制它们的堆叠顺序。

grid-column / grid-row

grid-column-start + grid-column-end, 和 grid-row-start + grid-row-end 的简写形式。

值:

<start-line> / <end-line> – 每个值的用法都和属性分开写时的用法一样
.item {
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}

举例:

.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}

如果没有指定结束行值,则该网格项默认跨越1个轨道。

grid-area 给 grid item 进行命名以便于使用 grid-template-areas 属性创建模板时来进行引用。另外也可以做为 grid-row-start + grid-column-start + grid-row-end + grid-column-end 的简写形式。

值:

<name> – 你的命名
<row-start> / <column-start> / <row-end> / <column-end> – 可以是数字,也可以是网格线的名字
.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}

举例:

给一个网格项命名

.item-d {
grid-area: header
}

作为 grid-row-start + grid-column-start + grid-row-end + grid-column-end 的简写:

.item-d {
grid-area: 1 / col4-start / last-line / 6
}

justify-self

沿着行轴对齐grid item 里的内容(与之对应的是 align-self, 即沿列轴对齐)。 此属性对单个网格项内的内容生效。

值:

start – 将内容对齐到网格区域的左端 end – 将内容对齐到网格区域的右端 center – 将内容对齐到网格区域的中间 stretch – 填充网格区域的宽度 (这是默认值) 举例:

.item-a {
justify-self: start;
}

.item-a {
justify-self: end;
}

.item-a {
justify-self: center;
}

.item-a {
justify-self: stretch;
}

要为网格中的所有grid items 设置对齐方式,也可以通过 justify-items 属性在网格容器上设置此行为。

align-self 沿着列轴对齐grid item 里的内容(与之对应的是 justify-self, 即沿行轴对齐)。 此属性对单个网格项内的内容生效。

值:

start – 将内容对齐到网格区域的顶部 end – 将内容对齐到网格区域的底部 center – 将内容对齐到网格区域的中间 stretch – 填充网格区域的高度 (这是默认值)

.item {
align-self: start | end | center | stretch;
}

举例:

.item-a {
align-self: start;
}

.item-a {
align-self: end;
}

.item-a {
align-self: center;
}

.item-a {
align-self: stretch;
}

要为网格中的所有grid items 统一设置对齐方式,也可以通过 align-items 属性在网格容器上设置此行为。

终于COPY完了,以上部分来自饥人谷

fr 单位(等分)

fr 是为网格布局定义的一个新单位。它可以帮助你摆脱计算百分比,并将可用空间等分。

例如,如果在网格容器中设置这个规则:grid-template-rows: 2fr 3fr,那么你的网格容器将首先被分成 2 行。然后将数字部分加在一起,这里总和为 5, 即 5 等分。

就是说,我们将有 2 行:第一排占据垂直空间的 2/5 。 第二排占垂直空间的 3/5 。

用fr来个有3行3列的布局怎么实现?

.container {
display: grid;
grid-template-rows: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
}

这里特别需要注意的是: fr 单位是等分可用空间,或者说剩余空间。看个例子

.container {
grid-gap:2px;
display: grid;
width:300px;
height:200px;
grid-template-rows: 100px 1fr 1fr;
grid-template-columns: 1fr 50px 1fr;
}

你会看到 fr 单位是将 总的尺寸 减去 单元格明确尺寸后,在等分剩余空间。 grid-gap 是间隔。

repeat() 函数

在某些情况下,我们可能有很多的列和行。在 grid-template 属性中指定每一个值可能会很乏味。幸运的是,有一个 repeat 函数,就像任何一个循环重复多少次输出某个给定值。它有两个参数。第一个是迭代次数,第二个是要重复的值。我们用 repeat 函数重写上面的例子。

.container {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
}

等价于:

.container {
display: grid;
grid-template-rows: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
}

参考学习网址

http://www.css88.com/archives/8675

· 阅读需 2 分钟

做了一份关于跨域的ppt,主要讲解了,使用vue-cli、nginx、node.js进行跨域处理。欢迎下载观看。

PPT请点击这里下载

下面附上几张照片,node.js跨域源码在下面。

proxy.js

var PORT = 3000;
var http = require('http');
var url=require('url');
var fs=require('fs');
var mine=require('./mime').types;
var path=require('path');
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({
target: 'http://192.168.2.18:8080/', //接口地址
// 下面的设置用于https
// ssl: {
// key: fs.readFileSync('server_decrypt.key', 'utf8'),
// cert: fs.readFileSync('server.crt', 'utf8')
// },
// secure: false
});
proxy.on('error', function(err, req, res){
res.writeHead(500, {
'content-type': 'text/plain'
});
console.log(err);
res.end('Something went wrong. And we are reporting a custom error message.');
});
var server = http.createServer(function (request, response) {
var pathname = url.parse(request.url).pathname;
//var realPath = path.join("main-pages", pathname); // 指定根目录
var realPath = path.join("./", pathname);
console.log(pathname);
console.log(realPath);
var ext = path.extname(realPath);
ext = ext ? ext.slice(1) : 'unknown';
//判断如果是接口访问,则通过proxy转发
if(pathname.indexOf("meis") > 0){
proxy.web(request, response);
return;
}
fs.exists(realPath, function (exists) {
if (!exists) {
response.writeHead(404, {
'Content-Type': 'text/plain'
});

response.write("This request URL " + pathname + " was not found on this server.");
response.end();
} else {
fs.readFile(realPath, "binary", function (err, file) {
if (err) {
response.writeHead(500, {
'Content-Type': 'text/plain'
});
response.end(err);
} else {
var contentType = mine[ext] || "text/plain";
response.writeHead(200, {
'Content-Type': contentType
});
response.write(file, "binary");
response.end();
}
});
}
});
});
server.listen(PORT);
console.log("Server runing at port: " + PORT + ".");

mime.js

exports.types = {
"css": "text/css",
"gif": "image/gif",
"html": "text/html",
"ico": "image/x-icon",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"js": "text/javascript",
"json": "application/json",
"pdf": "application/pdf",
"png": "image/png",
"svg": "image/svg+xml",
"swf": "application/x-shockwave-flash",
"tiff": "image/tiff",
"txt": "text/plain",
"wav": "audio/x-wav",
"wma": "audio/x-ms-wma",
"wmv": "video/x-ms-wmv",
"xml": "text/xml",
"woff": "application/x-woff",
"woff2": "application/x-woff2",
"tff": "application/x-font-truetype",
"otf": "application/x-font-opentype",
"eot": "application/vnd.ms-fontobject"
};

· 阅读需 1 分钟

使用vue-cli3脚手架搭配ElementUI做了一个简单的PC后台管理系统

连接地址账号密码随便输,不写也行。 [github源码在这里](https://github.com/zywkuo/vue-cli-demo-pc) 下载在下来后安装依赖,启动项目应该就可以看了。

我也在学习中,持续更新。。。。。。