display:inline-block;
简单来说就是将对象呈现为inline对象,但是对象的内容作为block对象呈现。之后的内联对象会被排列在同一行内。比如我们可以给一个link(a元素)inline-block属性值,使其既具有block的宽度高度特性又具有inline的同行特性。
但其并不兼容IE6、7,解决办法:
1、首先设置inline-block触发块元素,具有了layout的特性,然后设置display:inline使块元素呈现内联元素,此时layout的特性不会消失。
2、直接设置display:inline,使用zoom:1触发layout。
兼容所有浏览器的方法是:
display:inline-block;
*display:inline;
*zoom:1;
应用:可解决轮播图中下标 li 的水平居中问题
animation: name keeping-time animate-function delay times iteration final;
第一个参数:name (animation-name):
动画的名字,即设定动画过程的名字,CSS3采用“关键帧 keyframes”来定义动画
前缀-webkit-表示webkit内核浏览器(Chrome、Safari和变心的opera),以上代码定义了一个动画,名叫name,效果是使透明度从0变化到1,0%~100%为整个过程,当然也可以定义多段如:0%~20~50%~100%。
第二个参数:keeping-time (animation-duration):
整个动画的持续时间,必须带上时间单位,s或者ms均可;
第三个参数:animate-function (animation-timing-function):
运动方式(动画方式)的贝赛尔曲线,可取值为:ease、ease-in、ease-out、linear、ease-in-out、cubic-bezier(num1,num2,num3,num4)。
第四个参数:delay (animation-delay):
动画延迟执行的时间,单位也是s或者ms,值得注意的是,即使延迟时间为0,也必须加上时间单位,如果写成直接写成0,在Chrome和Safari(webkit)下是没问题的,但是在FF(gecko)下无效。
第五个参数:times (animation-iteration-count):
动画循环执行的次数,无单位,infinite为无限循环。
第六个参数:iteration (animation-direction):
如果动画循环,循环的方式是:alternate(偶数次向前播放,奇数次向后播放)、normal(每次都向前播放)。
第七个参数:final (animation-fill-mode):
动画的最后(达到100%)时的状态,取值有:backward(回到初始状态)、forwards(停在最终状态)、none、both。
每个参数也可以单独写,最后用的时候记得加浏览器前缀
transform的属性包括:rotate() / skew() / scale() / translate(,)
transform-origin: x-axis y-axis z-axis;
@keyframes animationname {keyframes-selector {css-styles;}}
less:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/* 变量声明 */ //var color = '#f00'; @color: #ff0; a{ font-size: 14px; color:@color; &:hover { text-decoration: underline; } } /* 变量的运算 */ @font-size: 12px; body{ font-size: @font-size; } .content { font-size: @font-size * 2; } .header{ height: 40px; background: #000; } .footer { &:extend(.header); font-size: 40px; } .fn-border-radius(@radius: 5px){ border-radius: @radius; } .box1 { .fn-border-radius(); } .box2 { .fn-border-radius(10px); } /* 外部导入 */ @import "01-demo-bak";
gulp教程:gulp-less
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//3、配置gulpfile.js //3.1、基本使用 var gulp = require('gulp'), less = require('gulp-less'); gulp.task('testLess', function () { gulp.src('src/less/index.less') .pipe(less()) .pipe(gulp.dest('src/css')); }); //3.2、编译多个less文件 var gulp = require('gulp'), less = require('gulp-less'); gulp.task('testLess', function () { gulp.src(['src/less/index.less','src/less/detail.less']) //多个文件以数组形式传入 .pipe(less()) .pipe(gulp.dest('src/css')); //将会在src/css下生成index.css以及detail.css }); //3.3、匹配符“!”,“*”,“**”,“{}” var gulp = require('gulp'), less = require('gulp-less'); gulp.task('testLess', function () { //编译src目录下的所有less文件 //除了reset.less和test.less(**匹配src/less的0个或多个子文件夹) gulp.src(['src/less/*.less', '!src/less/**/{reset,test}.less']) .pipe(less()) .pipe(gulp.dest('src/css')); }); //3.4、调用多模块(编译less后压缩css) var gulp = require('gulp'), less = require('gulp-less'), //确保本地已安装gulp-minify-css [cnpm install gulp-minify-css --save-dev] cssmin = require('gulp-minify-css'); gulp.task('testLess', function () { gulp.src('src/less/index.less') .pipe(less()) .pipe(cssmin()) //兼容IE7及以下需设置compatibility属性 .pipe(cssmin({compatibility: 'ie7'})) .pipe(gulp.dest('src/css')); }); //3.5、当less有各种引入关系时,编译后不容易找到对应less文件,所以需要生成sourcemap文件,方便修改 var gulp = require('gulp'), less = require('gulp-less'), //确保本地已安装gulp-sourcemaps [cnpm install gulp-sourcemaps --save-dev] sourcemaps = require('gulp-sourcemaps'); gulp.task('testLess', function () { gulp.src('src/less/**/*.less') .pipe(sourcemaps.init()) .pipe(less()) .pipe(sourcemaps.write()) .pipe(gulp.dest('src/css')); }); //4、执行任务 //4.1、命令提示符执行:gulp testLess //5、监听事件(自动编译less) //5.1、若每修改一次less,就要手动执行任务,显然是不合理的,所以当有less文件发生改变时使其自动编译 var gulp = require('gulp'), less = require('gulp-less'); gulp.task('testLess', function () { gulp.src(['src/less/*.less','!src/less/extend/{reset,test}.less']) .pipe(less()) .pipe(gulp.dest('src/css')); }); gulp.task('testWatch', function () { gulp.watch('src/**/*.less', ['testLess']); //当所有less文件发生改变时,调用testLess任务 }); //5.2、启动监听事件:命令提示符执行 gulp testWatch //5.3、注意:该命令提示符执行需处于打开状态,关闭后监听事件结束(Ctrl + C 或右上)
gulp-livereload:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//3、配置gulpfile.js //3.1、基本使用(当less发生变化的时候,自动更新页面) var gulp = require('gulp'), less = require('gulp-less'), livereload = require('gulp-livereload'); gulp.task('less', function() { gulp.src('src/less/*.less') .pipe(less()) .pipe(gulp.dest('src/css')) .pipe(livereload()); }); //特别注意:若编译less的时候,同时执行其他操作,有可能引起页面刷新,而不是将样式植入页面 //例如下面任务同时生成sourcemap: //var sourcemaps = require('gulp-sourcemaps'); //gulp.task('less', function () { // gulp.src(['src/less/*.less']) // .pipe(sourcemaps.init()) // .pipe(less()) // .pipe(sourcemaps.write('./')) // .pipe(gulp.dest('src/css')) // .pipe(livereload()); //}); gulp.task('watch', function() { livereload.listen(); gulp.watch('src/less/**/*.less', ['less']); }); <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="css/style.css"/> </head> <body> </body> </html> /* 4、谷歌浏览器或火狐安装livereload插件 4.1、说明:谷歌浏览器安装插件需要翻墙,我已经下载了最新版本2.1.0到本地,点击下载(谷歌为.crx文件,火狐为.xpi文件) 4.2、安装方法:谷歌浏览器安装crx插件方法、火狐浏览器直接将xpi文件拖进浏览器即可安装/ 5、执行监听任务 5.1、命令提示符执行:gulp watch 6、打开页面并启动livereload浏览器插件 6.1、以服务器的方式打开页面,例如http://localhost:4444,而不是file:///F:/phpStudy/project/src/index.html,否则无法启动livereload浏览器插件 6.2、点击livereload浏览器插件即可启动 */
socket.io
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//Server (app.js) var app = require('express')(); var server = require('http').Server(app); var io = require('socket.io')(server); server.listen(80); app.get('/', function (req, res) { res.sendfile(__dirname + '/index.html'); }); io.on('connection', function (socket) { socket.emit('news', { hello: 'world' }); socket.on('my other event', function (data) { console.log(data); }); }); //Client (index.html) <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://localhost'); socket.on('news', function (data) { console.log(data); socket.emit('my other event', { my: 'data' }); }); </script>
服务端添加了两个行为:
1.某客户端登入后向其他客户端发送登陆消息。该功能通过socket.broadcast.emit函数实现。broadcast.emit 是向除该socket自己外的所有客户端发送登陆消息。
2.scoket监听chat message事件,并向包括自己在内的所有人发送聊天信息。
vue.js 表单控件
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>PlayAround2 Have Fun</title> <script src="https://cdn.jsdelivr.net/vue/1.0.26/vue.min.js"></script> </head> <body> <div id="app"> <h2>checkBox</h2> <input type="checkbox" v-model="checked"> <label>{{checked}}</label> <h2>multi checkbox</h2> <input type="checkbox" id="Kobe" value="Kobe" v-model="names"> <label for="Kobe">Kobe</label> <input type="checkbox" id="Curry" value="Curry" v-model="names"> <label for="Curry">Curry</label> <input type="checkbox" id="Aaron" value="Aaron" v-model="names"> <label for="Aaron">Aaron</label> <br> <span>Checked names: {{names | json}}</span> <h2>Radio</h2> <input type="radio" id="one" value="one" v-model="picked"> <label for="one">one</label> <br> <input type="radio" id="two" value="two" v-model="picked"> <label for="two">two</label> <br> <span>Picked: {{picked}}</span> <h2>Select</h2> <select v-model="selected"> <option selected>Kobe</option> <option>Curry</option> <option>Aaron</option> </select> <span>Selected: {{selected}}</span> <h2>Multi Select</h2> <select multiple v-model="multiSelected"> <option>Kobe</option> <option>Curry</option> <option>Aaron</option> </select> <span>Selected: {{multiSelected}}</span> <h2>Select with for</h2> <select v-model="selectedPlayer"> <option v-for="option in options" :value="option.value">{{option.text}}</option> </select> <span>Selected: {{selectedPlayer}}</span> <h2>Lazy-改变更新的事件从input->change</h2> <input v-model="msg" lazy> <span>Msg:{{msg}}</span> <h2>Number</h2> <input v-model="age" number> <span>age:{{age}}</span> <h2>debounce-延迟更新view</h2> <p>Edit me<input v-model="delayMsg" debounce="500"></p> <span>delayMsg:{{delayMsg}}</span> </div> <script> var vm = new Vue({ el:"#app", data:{ checked:false, names:[], picked:"", selected:"", multiSelected:"", options:[ {text:"Kobe",value:"Bryant"}, {text:"Stephen",value:"Curry"}, {text:"Aaron",value:"Kong"} ], selectedPlayer:"", msg:"", age:"", delayMsg:"" } }) </script> </body> </html>
angular.js ng-model, ng-repeat, ng-if
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ng-repeat</title> <script type="text/javascript" src="../js/angular.min.js"></script> </head> <body ng-app="myApp"> <!-- ng-repeat 循环数据 <li ng-repeat="i in list">{{i.name}}--{{i.age}}</li> i表示每一项 名字随意 list表示数据 名字必须和scope上面绑定的一致 <li ng-repeat="(key,item) in list">{{key}}--{{item.name}}--{{item.age}}</li> (key,item) key索引值 item表示每一项 ng-if true的话显示 --> <div ng-controller="firstController"> <!-- 数组循环 --> <ul> <li ng-repeat="val in list1"> {{val}} </li> </ul> <hr> <!-- 对象循环 --> <ul> <li ng-repeat="(key, val) in list2">{{key}}--{{val}}</li> </ul> <hr> <!-- 数组对象循环 --> <ul> <li ng-repeat="(key, item) in list3">{{key}}--{{item.name}}--{{item.age}}</li> </ul> <hr> <ul> <li ng-repeat="(key, item) in list3" ng-if="key > 0"> {{key}}--{{item.name}}--{{item.age}} </li> </ul> <hr/> <!--$index 也是索引值--> <ul> <li ng-repeat="(key, item) in list3"> {{$index}}----{{key}}--{{item.name}}--{{item.age}} </li> </ul> <hr> <ul> <li ng-repeat="item in list3"> {{$first}}----{{$index}}----{{item.name}}--{{item.age}} </li> </ul> </div> </body> </html> <script> var app=angular.module('myApp',[]); app.controller('firstController',function($scope){ $scope.list1 = ['张三','李四', '王五']; $scope.list2 = {'name':'王五',age:'20',sex:'男'}; $scope.list3 = [ {'name':'张三',age:'20'}, {'name':'李四',age:'20'}, {'name':'王五',age:'22'} ]; }) </script>
$filter:
filter的两种使用方法 1. 在模板中使用filter 我们可以直接在{{}}中使用filter,跟在表达式后面用 | 分割,语法如下: {{ expression | filter }} 也可以多个filter连用,上一个filter的输出将作为下一个filter的输入(怪不得这货长的跟管道一个样。。) {{ expression | filter1 | filter2 | ... }} filter可以接收参数,参数用 : 进行分割,如下: {{ expression | filter:argument1:argument2:... }} 除了对{{}}中的数据进行格式化,我们还可以在指令中使用filter,例如先对数组array进行过滤处理,然后再循环输出: <span ng-repeat="a in array | filter "> 2. 在controller和service中使用filter 我们的js代码中也可以使用过滤器,方式就是我们熟悉的依赖注入,例如我要在controller中使用currency过滤器,只需将它注入到该controller中即可,代码如下: app.controller('testC',function($scope,currencyFilter){ $scope.num = currencyFilter(123534); } 在模板中使用{{num}}就可以直接输出 $123,534.00了!在服务中使用filter也是同样的道理。 此时你可能会有疑惑,如果我要在controller中使用多个filter,难道要一个一个注入吗,这岂不太费劲了?小兄弟莫着急~ng提供了一个$filter服务可以来调用所需的filter,你只需注入一个$filter就够了,使用方法如下: app.controller('testC',function($scope,$filter){ $scope.num = $filter('currency')(123534); $scope.date = $filter('date')(new Date()); } 可以达到同样的效果。好处是你可以方便使用不同的filter了。 ng的内置过滤器 ng内置了九种过滤器,使用方法都非常简单,看文档即懂。不过为了以后不去翻它的文档,我在这里还是做一个详细的记录。 1. currency (货币处理) 使用currency可以将数字格式化为货币,默认是美元符号,你可以自己传入所需的符号,例如我传入人民币: {{num | currency : '¥'}} 2. date (日期格式化) 原生的js对日期的格式化能力有限,ng提供的date过滤器基本可以满足一般的格式化要求。用法如下: {{date | date : 'yyyy-MM-dd hh:mm:ss EEEE'}} 参数用来指定所要的格式,y M d h m s E 分别表示 年 月 日 时 分 秒 星期,你可以自由组合它们。也可以使用不同的个数来限制格式化的位数。另外参数也可以使用特定的描述性字符串,例如“shortTime”将会把时间格式为 12:05 pm这样的。ng提供了八种描述性的字符串,个人觉得这些有点多余,我完全可以根据自己的意愿组合出想要的格式,不愿意去记这么多单词~ 3. filter(匹配子串) 这个名叫filter的filter(不得不说这名字起的,真让人容易混淆——!)用来处理一个数组,然后可以过滤出含有某个子串的元素,作为一个子数组来返回。可以是字符串数组,也可以是对象数组。如果是对象数组,可以匹配属性的值。它接收一个参数,用来定义子串的匹配规则。下面举个例子说明一下参数的用法,我用现在特别火的几个孩子定义了一个数组: $scope.childrenArray = [ {name:'kimi',age:3}, {name:'cindy',age:4}, {name:'anglar',age:4}, {name:'shitou',age:6}, {name:'tiantian',age:5} ]; $scope.func = function(e){return e.age>4;} {{ childrenArray | filter : 'a' }} //匹配属性值中含有a的 {{ childrenArray | filter : 4 }} //匹配属性值中含有4的 {{ childrenArray | filter : {name : 'i'} }} //参数是对象,匹配name属性中含有i的 {{childrenArray | filter : func }} //参数是函数,指定返回age>4的 4. json(格式化json对象) json过滤器可以把一个js对象格式化为json字符串,没有参数。这东西有什么用呢,我一般也不会在页面上输出一个json串啊,官网说它可以用来进行调试,嗯,是个不错的选择。或者,也可以用在js中使用,作用就和我们熟悉的JSON.stringify()一样。用法超级简单: {{ jsonTest | json}} 5. limitTo(限制数组长度或字符串长度) limitTo过滤器用来截取数组或字符串,接收一个参数用来指定截取的长度。个人觉得这个filter有点鸡肋,首先只能从数组或字符串的开头进行截取,其次,js原生的函数就可以代替它了,看看怎么用吧: {{ childrenArray | limitTo : 2 }} //将会显示数组中的前两项 6. lowercase(小写) 把数据转化为全部小写。太简单了,不多解释。同样是很鸡肋的一个filter,没有参数,只能把整个字符串变为小写,不能指定字母。怎么用我都懒得写了。 7. uppercase(大写) 8. number(格式化数字) number过滤器可以为一个数字加上千位分割,像这样,123,456,789。同时接收一个参数,可以指定小float类型保留几位小数: {{ num | number : 2 }} 9. orderBy(排序) orderBy过滤器可以将一个数组中的元素进行排序,接收一个参数来指定排序规则,参数可以是一个字符串,表示以该属性名称进行排序。可以是一个函数,定义排序属性。还可以是一个数组,表示依次按数组中的属性值进行排序(若按第一项比较的值相等,再按第二项比较),还是拿上面的孩子数组举例: <div>{{ childrenArray | orderBy : 'age' }}</div> //按age属性值进行排序 <div>{{ childrenArray | orderBy : orderFunc }}</div> //按照函数的返回值进行排序 <div>{{ childrenArray | orderBy : ['age','name'] }}</div> //如果age相同,按照name进行排序 内置的过滤器介绍完了,写的我都快睡着了。。。正如你所看到的,ng内置的过滤器也并不是万能的,事实上好多都比较鸡肋。更个性化的需求就需要我们来定义自己的过滤器了,下面来看看如何自定义过滤器。 自定义过滤器 filter的自定义方式也很简单,使用module的filter方法,返回一个函数,该函数接收输入值,并返回处理后的结果。话不多说,我们来写一个看看。比如我需要一个过滤器,它可以返回一个数组中下标为奇数的元素,代码如下: app.filter('odditems',function(){ return function(inputArray){ var array = []; for(var i=0;i<inputArray.length;i++){ if(i%2!==0){ array.push(inputArray[i]); } } return array; } }); 格式就是这样,你的处理逻辑就写在内部的那个闭包函数中。你也可以让自己的过滤器接收参数,参数就定义在return的那个函数中,作为第二个参数,或者更多个参数也可以。
$http.get(url).success(function (data) {});
app.controller('firstController',function($scope, $filter){
$scope.text='Hello Angularjs';
$scope.Retext = $filter('replace')($scope.text);
});
app.filter('replace',function(){
return function(data){
return data.replace('Hello','你好');
}
});
css文字扫光
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>css文字扫光</title> <style> .sample{ background-color: #0E1326; padding-top:30px; overflow: hidden; } .blank_text{ position: relative; width:200px; margin:20px auto; color: #fff; line-height: 1; font-size: 50px; font-size: 0.74074rem; text-align: center; overflow: hidden; font-family: "icomoon"; } .blank_text:after{ width: 300%; height: 100%; content: ""; position: absolute; top: 0; left: 0; background: -webkit-gradient(linear, left top, right top, color-stop(0, rgba(15,20,40, 0.7)), color-stop(0.4, rgba(15,20,40, 0.7)), color-stop(0.5, rgba(15,20,40, 0)), color-stop(0.6, rgba(15,20,40, 0.7)), color-stop(1, rgba(15,20,40, 0.7))); -webkit-animation: slide ease-in-out 2s infinite; } @-webkit-keyframes slide{ 0%{-webkit-transform:translateX(-66.666%);} 100%{-webkit-transform:translateX(0);} } </style> </head> <body> <div class="sample"> <div class="blank_text">天行健,君子以自强不息</div> </div> </body> </html> <!-- <div class="bg"> <p class="slideShine">Welcome to xinpureZhu Blog</p> </div> .bg { background: #000; width: 1000px; height: 300px; margin: 0 auto; padding-top: 100px; } .slideShine { width: 1000px; font-family: "Microsoft YaHei"; font-size: 60px; text-align: center; background: #111 -webkit-linear-gradient(left, #111, #fff) 0 0 no-repeat; -webkit-background-size: 80px; -webkit-background-clip: text; -webkit-text-fill-color: rgba(255, 255, 255, 0.3); -webkit-animation: slideShine 3s infinite; } @-webkit-keyframes slideShine { 0% { background-position: 0 0; } 100% { background-position: 100% 100%; } } -->