node

node

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
javascript/jQuery

javascript/jQuery

一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。
MongoDB

MongoDB

MongoDB 是一个基于分布式文件存储的数据库
openstack

openstack

OpenStack是一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。
VUE

VUE

一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。
bootstrap

bootstrap

Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.
HTML

HTML

超文本标记语言,标准通用标记语言下的一个应用。
CSS/SASS/SCSS/Less

CSS/SASS/SCSS/Less

层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。
PHP

PHP

PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域。PHP 独特的语法混合了C、Java、Perl以及PHP自创的语法。它可以比CGI或者Perl更快速地执行动态网页。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML(标准通用标记语言下的一个应用)文档中去执行,执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执
每天进步一点点

每天进步一点点

乌法把门的各累笑寂静
求职招聘

求职招聘

猎头招聘专用栏目
Python

Python

一种解释型、面向对象、动态数据类型的高级程序设计语言。

lockr.js 本地储存 localStorage操作js库

javascript/jQuerylopo1983 发表了文章 • 0 个评论 • 4480 次浏览 • 2017-05-24 23:51 • 来自相关话题

一个本地储存操作js库,他真的很小,压缩版的甚至<2kb,你可以用类似api的方式来对本地存储进行操作。

1.如何安装lockrbower install lockrcnpm i lockr --save你还可以点击在那遥远的地方直接下载使用<script src="/path/lockr.js" type="text/javascript"></script>
2.API 介绍
Lockr.prefix?- String
?
设置一个字符串用于标记相关的值Lockr.prefix = 'lockr';
Lockr.set('username', 'Coyote');
localStorage.getItem('username');
localStorage.getItem('lockr_username');




Lockr.set?- :?[ key, value ]?{String, Number, Array or Object}
给本地储存写入值Lockr.set('username', 'Coyote'); // String
Lockr.set('user_id', 12345); // number
Lockr.set('users', [{name: 'John Doe', age: 18}, {name: 'Jane Doe', age: 19}]);




Lockr.get?- :?[ key ?/ ?hash_key , 默认值 ]
读取本地储存的值,如果获取到的数值为null/undefined ?则返回设置的默认值Lockr.get('username');
> "Coyote"

Lockr.get('user_id');
> 12345

Lockr.get('users');
> [{name: 'John Doe', age: 18}, {name: 'Jane Doe', age: 19}]

Lockr.get('score', 0):
> 0
//不存在返回设置的默认值0
Lockr.set('score', 3):
Lockr.get('score', 0):
> 3




Lockr.rm?- arguments:?[ key ]?{String}
从本地储存中移除相关数据Lockr.set('username', 'Coyote');
Lockr.get('username');
> "Coyote"
Lockr.rm('username');
Lockr.get('username');
> undefined




Lockr.sadd?- arguments?[ key, value ]{String, Number, Array or Object}
给hash key添加指定值(持续添加类似push 但具备set 自动过滤重复)Lockr.sadd("wat", 1); // [1]
Lockr.sadd("wat", 2); // [1, 2]
Lockr.sadd("wat", 1); // [1, 2]




Lockr.sismember?- arguments?[ key, value ]
判断某hash key 是否包含某个值 ?返回Boolean true falseLockr.sadd("wat", 1);
Lockr.sismember("wat", 1); // true
Lockr.sismember("wat", 2); // false




Lockr.smembers?- arguments?[ key ]
返回hash key下的值Lockr.sadd("wat", 42);
Lockr.sadd("wat", 1337);
Lockr.smembers("wat"); // [42, 1337]




Lockr.srem?- arguments?[ key, value ]
移除hash key下的指定数值Lockr.sadd("wat", 1);
Lockr.sadd("wat", 2);
Lockr.srem("wat", 1);
Lockr.smembers("wat"); // [2]




Lockr.getAll?- arguments:?null
获取所有数据生成多维数组Lockr.getAll();
> ["Coyote", 12345, [{name: 'John Doe', age: 18}, {name: 'Jane Doe', age: 19}]]获取所有数据生成json数据Lockr.getAll(true);
> [{"username": "Coyote"}, {"user_id": 12345}, {"users": [{name: 'John Doe', age: 18}, {name: 'Jane Doe', age: 19}]}]




Lockr.flush()?- arguments:?null
清空本地储存所有数据localStorage.length;
> 3
Lockr.flush();
localStorage.length;
> 0 查看全部
lockr.png

一个本地储存操作js库,他真的很小,压缩版的甚至<2kb,你可以用类似api的方式来对本地存储进行操作。

1.如何安装lockr
bower install lockr
cnpm i lockr --save
你还可以点击在那遥远的地方直接下载使用
<script src="/path/lockr.js" type="text/javascript"></script>

2.API 介绍

Lockr.prefix?- String


?
设置一个字符串用于标记相关的值
Lockr.prefix = 'lockr';
Lockr.set('username', 'Coyote');
localStorage.getItem('username');
localStorage.getItem('lockr_username');

line.jpg

Lockr.set?- :?[ key, value ]?{String, Number, Array or Object}


给本地储存写入值
Lockr.set('username', 'Coyote'); // String
Lockr.set('user_id', 12345); // number
Lockr.set('users', [{name: 'John Doe', age: 18}, {name: 'Jane Doe', age: 19}]);

line.jpg

Lockr.get?- :?[ key ?/ ?hash_key , 默认值 ]


读取本地储存的值,如果获取到的数值为null/undefined ?则返回设置的默认值
Lockr.get('username');
> "Coyote"

Lockr.get('user_id');
> 12345

Lockr.get('users');
> [{name: 'John Doe', age: 18}, {name: 'Jane Doe', age: 19}]

Lockr.get('score', 0):
> 0
//不存在返回设置的默认值0
Lockr.set('score', 3):
Lockr.get('score', 0):
> 3

line.jpg

Lockr.rm?- arguments:?[ key ]?{String}


从本地储存中移除相关数据
Lockr.set('username', 'Coyote');
Lockr.get('username');
> "Coyote"
Lockr.rm('username');
Lockr.get('username');
> undefined

line.jpg

Lockr.sadd?- arguments?[ key, value ]{String, Number, Array or Object}


给hash key添加指定值(持续添加类似push 但具备set 自动过滤重复)
Lockr.sadd("wat", 1); // [1]
Lockr.sadd("wat", 2); // [1, 2]
Lockr.sadd("wat", 1); // [1, 2]

line.jpg

Lockr.sismember?- arguments?[ key, value ]


判断某hash key 是否包含某个值 ?返回Boolean true false
Lockr.sadd("wat", 1);
Lockr.sismember("wat", 1); // true
Lockr.sismember("wat", 2); // false

line.jpg

Lockr.smembers?- arguments?[ key ]


返回hash key下的值
Lockr.sadd("wat", 42);
Lockr.sadd("wat", 1337);
Lockr.smembers("wat"); // [42, 1337]

line.jpg

Lockr.srem?- arguments?[ key, value ]


移除hash key下的指定数值
Lockr.sadd("wat", 1);
Lockr.sadd("wat", 2);
Lockr.srem("wat", 1);
Lockr.smembers("wat"); // [2]

line.jpg

Lockr.getAll?- arguments:?null


获取所有数据生成多维数组
Lockr.getAll();
> ["Coyote", 12345, [{name: 'John Doe', age: 18}, {name: 'Jane Doe', age: 19}]]
获取所有数据生成json数据
Lockr.getAll(true);
> [{"username": "Coyote"}, {"user_id": 12345}, {"users": [{name: 'John Doe', age: 18}, {name: 'Jane Doe', age: 19}]}]

line.jpg

Lockr.flush()?- arguments:?null


清空本地储存所有数据
localStorage.length;
> 3
Lockr.flush();
localStorage.length;
> 0

vue前后端分离解决

VUEyangyulu 发表了文章 • 0 个评论 • 2541 次浏览 • 2017-05-19 16:12 • 来自相关话题

看了很多vue的项目,基本都是用mock来做模拟数据,实际开发中,对于与实际接口的交互,就成了很大的阻碍。本demo以实际的后端接口做交互。前端用vue-cli脚手架加上elementUI组件,后端用基于Java的springmvc+mybatis+mysql+shiro的一个权限管理的demo。 查看全部
看了很多vue的项目,基本都是用mock来做模拟数据,实际开发中,对于与实际接口的交互,就成了很大的阻碍。本demo以实际的后端接口做交互。前端用vue-cli脚手架加上elementUI组件,后端用基于Java的springmvc+mybatis+mysql+shiro的一个权限管理的demo。

移动端页面开发总结(三)

HTMLboloog 发表了文章 • 0 个评论 • 1715 次浏览 • 2017-05-09 15:37 • 来自相关话题

CSS reset
@charset "utf-8";
html{
-webkit-text-size-adjust:none;
-webkit-user-select:none;
-webkit-touch-callout: none;
font-family: Microsoft YaHei,'宋体' , Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif;
font-size:24px;
}
body,h1,h2,h3,h4,h5,h6,p,dl,dd,ul,ol,pre,form,input,textarea,th,td,select{
margin:0;
padding:0;
font-weight: normal;
}
a,button,input,textarea,select{
background: none;
-webkit-tap-highlight-color:rgba(255,0,0,0);
outline:none;
-webkit-appearance:none;
}
ol,ul{
list-style:none;
}
a{
text-decoration:none;
}
img{
border:none;
text-decoration: none;
}
table{
border-collapse:collapse;
border-spacing: 0;
}
textarea{
resize:none;
overflow:auto;
}
清除浮动
.clearfix{
zoom:1;
}
.clearfix:after {
clear:both;
display:block;
height:0;
content:"";
visibility:hidden;
}
禁止换行 超出文本用省略号代替
.no-wrap-ellipsis{
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
使文本文字两端对齐
.text-justify{
text-align:justify;
text-justify:inter-ideograph;
}
CSS判断横屏竖屏
@media screen and (orientation: portrait) {
/*竖屏 css*/
}
@media screen and (orientation: landscape) {
/*横屏 css*/
}
?取消长按复制 获取长按复制
.text-nocopy {
-webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.text-copy{
-webkit-touch-callout:text;
-webkit-user-select:text;
-moz-user-select:text;
-ms-user-select:text;
user-select:text;
}
?
?
?
? 查看全部
CSS reset
@charset "utf-8";
html{
-webkit-text-size-adjust:none;
-webkit-user-select:none;
-webkit-touch-callout: none;
font-family: Microsoft YaHei,'宋体' , Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif;
font-size:24px;
}
body,h1,h2,h3,h4,h5,h6,p,dl,dd,ul,ol,pre,form,input,textarea,th,td,select{
margin:0;
padding:0;
font-weight: normal;
}
a,button,input,textarea,select{
background: none;
-webkit-tap-highlight-color:rgba(255,0,0,0);
outline:none;
-webkit-appearance:none;
}
ol,ul{
list-style:none;
}
a{
text-decoration:none;
}
img{
border:none;
text-decoration: none;
}
table{
border-collapse:collapse;
border-spacing: 0;
}
textarea{
resize:none;
overflow:auto;
}

清除浮动
.clearfix{ 
zoom:1;
}
.clearfix:after {
clear:both;
display:block;
height:0;
content:"";
visibility:hidden;
}

禁止换行 超出文本用省略号代替
.no-wrap-ellipsis{ 
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}

使文本文字两端对齐
.text-justify{ 
text-align:justify;
text-justify:inter-ideograph;
}

CSS判断横屏竖屏
@media screen and (orientation: portrait) {
/*竖屏 css*/
}
@media screen and (orientation: landscape) {
/*横屏 css*/
}

?取消长按复制 获取长按复制
.text-nocopy {
-webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.text-copy{
-webkit-touch-callout:text;
-webkit-user-select:text;
-moz-user-select:text;
-ms-user-select:text;
user-select:text;
}

?
?
?
?

移动端页面开发总结(二)

HTMLboloog 发表了文章 • 0 个评论 • 1783 次浏览 • 2017-05-09 14:55 • 来自相关话题

CSS的样式技巧?
?
1、禁止ios和android用户选中文字
html{-webkit-user-select:none;}
2、禁止ios长按时触发系统的菜单,禁止ios&android长按时下载图片
html{-webkit-touch-callout: none;}
3、webkit去除表单元素的默认样式
input{-webkit-appearance:none;}
4、修改webkit表单输入框placeholder的样式
input::-webkit-input-placeholder{color:#123456;}
input:focus::-webkit-input-placeholder{color:#654321;}
5、去除android设备下面的 a/button/input标签被点击时产生的边框 & 去除ios a标签被点击时产生的半透明灰色背景
a,button,input{-webkit-tap-highlight-color:rgba(255,0,0,0);}
6、ios使用-webkit-text-size-adjust禁止调整字体大小
body{-webkit-text-size-adjust: 100%!important;}
7、android 上去掉语音输入按钮
input::-webkit-input-speech-button {display: none;}
8、定义字体
font-family:'\5FAE\8F6F\96C5\9ED1',tahoma,'\5b8b\4f53',"Helvetica Neue",Helvetica,Arial,sans-serif;
? 查看全部
CSS的样式技巧?
?
1、禁止ios和android用户选中文字
html{-webkit-user-select:none;}

2、禁止ios长按时触发系统的菜单,禁止ios&android长按时下载图片
html{-webkit-touch-callout: none;}

3、webkit去除表单元素的默认样式
input{-webkit-appearance:none;}

4、修改webkit表单输入框placeholder的样式
input::-webkit-input-placeholder{color:#123456;}
input:focus::-webkit-input-placeholder{color:#654321;}

5、去除android设备下面的 a/button/input标签被点击时产生的边框 & 去除ios a标签被点击时产生的半透明灰色背景
a,button,input{-webkit-tap-highlight-color:rgba(255,0,0,0);}

6、ios使用-webkit-text-size-adjust禁止调整字体大小
body{-webkit-text-size-adjust: 100%!important;}

7、android 上去掉语音输入按钮
input::-webkit-input-speech-button {display: none;}

8、定义字体
font-family:'\5FAE\8F6F\96C5\9ED1',tahoma,'\5b8b\4f53',"Helvetica Neue",Helvetica,Arial,sans-serif;

?

移动端页面开发总结(一)

HTMLboloog 发表了文章 • 0 个评论 • 1801 次浏览 • 2017-05-09 14:39 • 来自相关话题

meta标签的相关知识
?1、移动端页面设置视口宽度等于设备宽度,并禁止缩放。
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
?2、移动端页面设置视口宽度等于定宽(如750px),并禁止缩放,常用于微信浏览器页面。
<meta name="viewport" content="width=750, user-scalable=no, target-densitydpi=device-dpi">
3、禁止将页面中的数字识别为电话号码
<meta name="format-detection" content="telephone=no" />
4、忽略Android平台中对邮箱地址的识别
<meta name="format-detection" content="email=no" />
5、当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari
<meta name="apple-mobile-web-app-capable" content="yes" />
6、将网站添加到主屏幕快速启动方式,仅针对ios的safari顶端状态条的样式
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
html5 viewport模板
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>Document</title>
</head>
<body>
content...
</body>
</html>
?
?
?
?
? 查看全部
meta标签的相关知识
?1、移动端页面设置视口宽度等于设备宽度,并禁止缩放。
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />

?2、移动端页面设置视口宽度等于定宽(如750px),并禁止缩放,常用于微信浏览器页面。
<meta name="viewport" content="width=750, user-scalable=no, target-densitydpi=device-dpi">

3、禁止将页面中的数字识别为电话号码
<meta name="format-detection" content="telephone=no" />

4、忽略Android平台中对邮箱地址的识别
<meta name="format-detection" content="email=no" />

5、当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari
<meta name="apple-mobile-web-app-capable" content="yes" />

6、将网站添加到主屏幕快速启动方式,仅针对ios的safari顶端状态条的样式
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

html5 viewport模板
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>Document</title>
</head>
<body>
content...
</body>
</html>

?
?
?
?
?

Bootstrap+Masonry+imagesLoaded 快速实现瀑布流

bootstrap3.xlopo1983 发表了文章 • 0 个评论 • 2355 次浏览 • 2017-05-04 16:53 • 来自相关话题

html
<div id="masonry" class="container-fluid">

<div class="thumbnail">
<div class="imgs">
<img src="" />
</div>
<div class="caption">
<div class="title"></div>
<div class="content">

</div>
</div>
</div>

</div>css
<script>
$(function() {

var masonryNode = $('#masonry');
masonryNode.imagesLoaded(function(){
masonryNode.masonry({
itemSelector: '.thumbnail',
isFitWidth: true
});
});


});
</script>// 首先将新元素添加到页面容器中

masonryNode.append(newItems);
// 等待新元素中的图片加载完毕
newItems.imagesLoaded(function(){

// 调用瀑布流布局的appended方法
masonryNode.masonry('appended', newItems);
});$(window).scroll(function() {

if($(document).height() - $(window).height() - $(document).scrollTop() < 10) {

if(!imagesLoading) {
appendToMasonry();
}

}

});masonry官网 查看全部
html
<div id="masonry" class="container-fluid">

<div class="thumbnail">
<div class="imgs">
<img src="" />
</div>
<div class="caption">
<div class="title"></div>
<div class="content">

</div>
</div>
</div>

</div>
css
<script>
$(function() {

var masonryNode = $('#masonry');
masonryNode.imagesLoaded(function(){
masonryNode.masonry({
itemSelector: '.thumbnail',
isFitWidth: true
});
});


});
</script>
// 首先将新元素添加到页面容器中

masonryNode.append(newItems);
// 等待新元素中的图片加载完毕
newItems.imagesLoaded(function(){

// 调用瀑布流布局的appended方法
masonryNode.masonry('appended', newItems);
});
$(window).scroll(function() {

if($(document).height() - $(window).height() - $(document).scrollTop() < 10) {

if(!imagesLoading) {
appendToMasonry();
}

}

});
masonry官网

jQuery 瀑布流可以这样写

javascript/jQueryboloog 发表了文章 • 0 个评论 • 1812 次浏览 • 2017-05-04 09:56 • 来自相关话题

瀑布流实现原理
?
固定每一个item的宽度根据父级绝对定位js计算每一行可以排列几个 (父级总宽度 / item)= 排列个数写一个空数组 循环保存每一行的下标高度循环所有item获取当前行最小的高度和索引,改变当前的left和top会用到left的值就是当前索引*item的宽度top的值就是当前索引的高度计算完以后重置当前索引的高度elHeight[minIndex]+= 当前的高度,依次循环就可以了浏览器缩放时添加一个resize再从第三部重新计算宽度,然后循环数据,调整样式
?
实例代码
?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Waterfall flow</title>
<style>
*{
margin: 0;
padding: 0;
}
body {
font-family: "Droid Serif","Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
}
.clearfix:after{
content: "";
display: block;
clear: both;
}
input,button,select,textarea{
outline:none;border: none;
}
a{
text-decoration: none;
}
ul,li{
list-style: none;
}
img{
border: none;
}
.wrap {
position: relative;
min-width: 440px;
width: 90%;
margin: 0 auto;
}
.item {
width: 200px;
margin: 10px;
position: absolute;
transition: all .6s ease-out;
font-size: 50px;
color: #fff;
text-align: center;
}
</style>
</head>
<body>
<div class="wrap"></div>
<script src="https://cdn.bootcss.com/jquery ... gt%3B
<script>
var WaterFall = {
init: function(){
// 添加 item 盒子
this.addItem();
// 添加好盒子就开始布局
this.layout();
// 改变窗口时执行
this.resize();
},
addItem: function(){
var wrap = $('.wrap');
// 生成30个div 随机高度 和 颜色
var item = '';
for (var i = 0; i < 30; i++) {
item +='<div class="item" style="height:'+parseInt(Math.random() * 100 + 230)+'px;background-color:'+this.getRandColor()+'">'+i+'</div>';
}
wrap.append(item);
},
layout: function(){
var elHeight = [];
// 计算每一行可以存放几个 item 总宽 / item宽度
var countWidth = Math.floor( $('.wrap').width() / $('.item').width());
// 初始化添加 第一行高度的下标
for (var i = 0; i < countWidth; i++) {
elHeight[i] = 0;
}
// 循环 所有item
$('.item').each(function(index, el) {
// apply 传入数组 取得最小的高度
var minValue = Math.min.apply(null, elHeight);
console.log(minValue)
// 然后获取当前高度的索引
var minIndex = elHeight.indexOf(minValue)
// 修改当前的top 和 left
$(this).css({
top: elHeight[minIndex], // 获取当前索引对应的高度
left: $(this).outerWidth(true) * minIndex // 当前的left值为 索引 * 宽度(位于第几个)
})
// 当前索引的高度 += 当前 item 的高度 (比如计算第二排高度时, 就等于上一个的 top + 当前的高度)elHeight[0] += 90 下一次高度就为90
elHeight[minIndex] += $(this).outerHeight(true);
});
},
resize: function(){
$(window).resize(function() {
WaterFall.layout();
});
},
getRandColor: function(){
var str = '1234567890abcdef';
var colorStr = '#';
for(var i =0; i < 6; i++){
colorStr += str[ Math.floor(Math.random() * str.length) ];
}
return colorStr;
}
}
WaterFall.init(); // 执行
</script>
</body>
</html>
在线查看
?
总结

瀑布流布局实现了,在数据多的情况下没有做分页加载数据,后续会补充。
?
? 查看全部
瀑布流实现原理
?
  • 固定每一个item的宽度
  • 根据父级绝对定位
  • js计算每一行可以排列几个 (父级总宽度 / item)= 排列个数
  • 写一个空数组 循环保存每一行的下标高度
  • 循环所有item获取当前行最小的高度和索引,改变当前的left和top会用到
  • left的值就是当前索引*item的宽度
  • top的值就是当前索引的高度
  • 计算完以后重置当前索引的高度elHeight[minIndex]+= 当前的高度,依次循环就可以了
  • 浏览器缩放时添加一个resize再从第三部重新计算宽度,然后循环数据,调整样式

?
实例代码
?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Waterfall flow</title>
<style>
*{
margin: 0;
padding: 0;
}
body {
font-family: "Droid Serif","Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
}
.clearfix:after{
content: "";
display: block;
clear: both;
}
input,button,select,textarea{
outline:none;border: none;
}
a{
text-decoration: none;
}
ul,li{
list-style: none;
}
img{
border: none;
}
.wrap {
position: relative;
min-width: 440px;
width: 90%;
margin: 0 auto;
}
.item {
width: 200px;
margin: 10px;
position: absolute;
transition: all .6s ease-out;
font-size: 50px;
color: #fff;
text-align: center;
}
</style>
</head>
<body>
<div class="wrap"></div>
<script src="https://cdn.bootcss.com/jquery ... gt%3B
<script>
var WaterFall = {
init: function(){
// 添加 item 盒子
this.addItem();
// 添加好盒子就开始布局
this.layout();
// 改变窗口时执行
this.resize();
},
addItem: function(){
var wrap = $('.wrap');
// 生成30个div 随机高度 和 颜色
var item = '';
for (var i = 0; i < 30; i++) {
item +='<div class="item" style="height:'+parseInt(Math.random() * 100 + 230)+'px;background-color:'+this.getRandColor()+'">'+i+'</div>';
}
wrap.append(item);
},
layout: function(){
var elHeight = [];
// 计算每一行可以存放几个 item 总宽 / item宽度
var countWidth = Math.floor( $('.wrap').width() / $('.item').width());
// 初始化添加 第一行高度的下标
for (var i = 0; i < countWidth; i++) {
elHeight[i] = 0;
}
// 循环 所有item
$('.item').each(function(index, el) {
// apply 传入数组 取得最小的高度
var minValue = Math.min.apply(null, elHeight);
console.log(minValue)
// 然后获取当前高度的索引
var minIndex = elHeight.indexOf(minValue)
// 修改当前的top 和 left
$(this).css({
top: elHeight[minIndex], // 获取当前索引对应的高度
left: $(this).outerWidth(true) * minIndex // 当前的left值为 索引 * 宽度(位于第几个)
})
// 当前索引的高度 += 当前 item 的高度 (比如计算第二排高度时, 就等于上一个的 top + 当前的高度)elHeight[0] += 90 下一次高度就为90
elHeight[minIndex] += $(this).outerHeight(true);
});
},
resize: function(){
$(window).resize(function() {
WaterFall.layout();
});
},
getRandColor: function(){
var str = '1234567890abcdef';
var colorStr = '#';
for(var i =0; i < 6; i++){
colorStr += str[ Math.floor(Math.random() * str.length) ];
}
return colorStr;
}
}
WaterFall.init(); // 执行
</script>
</body>
</html>

在线查看
?
总结

瀑布流布局实现了,在数据多的情况下没有做分页加载数据,后续会补充。
?
?

vue-cli+pug+less+vuex+vue-form+axios+lodash webpack.json

VUElopo1983 发表了文章 • 1 个评论 • 2484 次浏览 • 2017-05-03 16:31 • 来自相关话题

{
? "name": "qdcenter",
? "version": "1.0.0",
? "description": "qiduo new user center",
? "author": "lopo <lopo1983@foxmail.com>",
? "private": true,
? "scripts": {
? ? "dev": "node build/dev-server.js",
? ? "start": "node build/dev-server.js",
? ? "build": "node build/build.js"
? },
? "dependencies": {
? ? "vue": "^2.2.6",
? ? "vue-router": "^2.3.1"
? },
? "devDependencies": {
? ? "animate.css": "^3.5.2",
? ? "autoprefixer": "^6.7.2",
? ? "available": "^2.0.3",
? ? "axios": "^0.15.3",
? ? "babel-core": "^6.22.1",
? ? "babel-loader": "^6.2.10",
? ? "babel-plugin-transform-runtime": "^6.22.0",
? ? "babel-polyfill": "^6.23.0",
? ? "babel-preset-env": "^1.2.1",
? ? "babel-preset-stage-2": "^6.22.0",
? ? "babel-register": "^6.22.0",
? ? "bce-sdk-js": "^0.2.7",
? ? "bootstrap": "^3.3.7",
? ? "chalk": "^1.1.3",
? ? "connect-history-api-fallback": "^1.3.0",
? ? "copy-webpack-plugin": "^4.0.1",
? ? "css-loader": "^0.26.1",
? ? "echarts": "^3.6.1",
? ? "eventsource-polyfill": "^0.9.6",
? ? "express": "^4.14.1",
? ? "extract-text-webpack-plugin": "^2.0.0",
? ? "file-loader": "^0.10.1",
? ? "friendly-errors-webpack-plugin": "^1.1.3",
? ? "function-bind": "^1.1.0",
? ? "html-webpack-plugin": "^2.28.0",
? ? "http-proxy-middleware": "^0.17.3",
? ? "less": "^2.7.2",
? ? "less-loader": "^3.0.0",
? ? "lodash": "^4.17.4",
? ? "opn": "^4.0.2",
? ? "optimize-css-assets-webpack-plugin": "^1.3.0",
? ? "ora": "^1.1.0",
? ? "pug": "^2.0.0-beta.12",
? ? "pug-filters": "^2.1.2",
? ? "pug-loader": "^2.3.0",
? ? "rimraf": "^2.6.0",
? ? "semver": "^5.3.0",
? ? "style-loader": "^0.14.1",
? ? "url-loader": "^0.5.7",
? ? "vue": "^2.3.3",
? ? "vue-event-calendar": "^1.3.0",
? ? "vue-form": "^4.1.1",
? ? "vue-loader": "^11.1.4",
? ? "vue-router": "^2.5.3",
? ? "vue-style-loader": "^2.0.0",
? ? "vue-template-compiler": "^2.2.4",
? ? "vuex": "^2.2.1",
? ? "webpack": "^2.3.3",
? ? "webpack-dev-middleware": "^1.10.0",
? ? "webpack-hot-middleware": "^2.18.0",
? ? "webpack-merge": "^4.1.0"
? },
? "engines": {
? ? "node": ">= 4.0.0",
? ? "npm": ">= 3.0.0"
? },
? "browserslist": [
? ? "> 1%",
? ? "last 2 versions",
? ? "not ie <= 8"
? ]
}
[size=13]
[/size] 查看全部
{
? "name": "qdcenter",
? "version": "1.0.0",
? "description": "qiduo new user center",
? "author": "lopo <lopo1983@foxmail.com>",
? "private": true,
? "scripts": {
? ? "dev": "node build/dev-server.js",
? ? "start": "node build/dev-server.js",
? ? "build": "node build/build.js"
? },
? "dependencies": {
? ? "vue": "^2.2.6",
? ? "vue-router": "^2.3.1"
? },
? "devDependencies": {
? ? "animate.css": "^3.5.2",
? ? "autoprefixer": "^6.7.2",
? ? "available": "^2.0.3",
? ? "axios": "^0.15.3",
? ? "babel-core": "^6.22.1",
? ? "babel-loader": "^6.2.10",
? ? "babel-plugin-transform-runtime": "^6.22.0",
? ? "babel-polyfill": "^6.23.0",
? ? "babel-preset-env": "^1.2.1",
? ? "babel-preset-stage-2": "^6.22.0",
? ? "babel-register": "^6.22.0",
? ? "bce-sdk-js": "^0.2.7",
? ? "bootstrap": "^3.3.7",
? ? "chalk": "^1.1.3",
? ? "connect-history-api-fallback": "^1.3.0",
? ? "copy-webpack-plugin": "^4.0.1",
? ? "css-loader": "^0.26.1",
? ? "echarts": "^3.6.1",
? ? "eventsource-polyfill": "^0.9.6",
? ? "express": "^4.14.1",
? ? "extract-text-webpack-plugin": "^2.0.0",
? ? "file-loader": "^0.10.1",
? ? "friendly-errors-webpack-plugin": "^1.1.3",
? ? "function-bind": "^1.1.0",
? ? "html-webpack-plugin": "^2.28.0",
? ? "http-proxy-middleware": "^0.17.3",
? ? "less": "^2.7.2",
? ? "less-loader": "^3.0.0",
? ? "lodash": "^4.17.4",
? ? "opn": "^4.0.2",
? ? "optimize-css-assets-webpack-plugin": "^1.3.0",
? ? "ora": "^1.1.0",
? ? "pug": "^2.0.0-beta.12",
? ? "pug-filters": "^2.1.2",
? ? "pug-loader": "^2.3.0",
? ? "rimraf": "^2.6.0",
? ? "semver": "^5.3.0",
? ? "style-loader": "^0.14.1",
? ? "url-loader": "^0.5.7",
? ? "vue": "^2.3.3",
? ? "vue-event-calendar": "^1.3.0",
? ? "vue-form": "^4.1.1",
? ? "vue-loader": "^11.1.4",
? ? "vue-router": "^2.5.3",
? ? "vue-style-loader": "^2.0.0",
? ? "vue-template-compiler": "^2.2.4",
? ? "vuex": "^2.2.1",
? ? "webpack": "^2.3.3",
? ? "webpack-dev-middleware": "^1.10.0",
? ? "webpack-hot-middleware": "^2.18.0",
? ? "webpack-merge": "^4.1.0"
? },
? "engines": {
? ? "node": ">= 4.0.0",
? ? "npm": ">= 3.0.0"
? },
? "browserslist": [
? ? "> 1%",
? ? "last 2 versions",
? ? "not ie <= 8"
? ]
}
[size=13]
[/size]

jQuery 幻灯片的实现原理

javascript/jQueryboloog 发表了文章 • 0 个评论 • 2014 次浏览 • 2017-05-03 09:47 • 来自相关话题

淡入淡出的轮播
?
slide-ul 是幻灯片的盒子 包括了所有的img position: relative;img position: absolute; 全部隐藏,默认显示第一张图片pageIndex 分页索引对应 img 的索引在点击分页索引时 给对应的 img 显示,其它的 img 隐藏设置一个定时器函数每三秒执行一次,每次都传入 pageIndex 实现定时切换 默认是 0 判断 (pageIndex++ >= img.length) 0 : pageIndex++鼠标移入图片清除定时器 鼠标移出时重启定时器

实例代码<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery-slide-fadeIn</title>
<style>
*{
margin: 0;
padding: 0;
}
body {
font-family: "Droid Serif","Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
}
.clearfix:after{
content: "";
display: block;
clear: both;
}
input,button,select,textarea{
outline:none;border: none;
}
a{
text-decoration: none;
color: #fff;
}
ul,li{
list-style: none;
}
img{
border: none;
}
.wrap{
width: 790px;
margin: 20px auto;
}
.slide-box{
height: 340px;
overflow: hidden;
position: relative;
}
.slide-left{
width: 100%;
position: relative;
}
.slide-left li{
position: absolute;
display: none;
}
.slide-left li a{
display: block;
}
.slide-left li a img{
width: 100%;
}

.slider-indicator{
position: absolute;
z-index: 1;
left: 50%;
transform: translateX(-50%);
bottom: 20px;
font-size: 0;
padding: 4px 8px;
border-radius: 12px;
background-color: rgba(255, 255, 255, 0.3);
}
.slider-indicator i{
display: inline-block;
margin-right: 10px;
width: 12px;
height: 12px;
border-radius: 100%;
background-color: #fff;
cursor: pointer;
}
.slider-indicator i.page-active{
background-color: #2196F3;
}
.slide-btn{
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 1;
display: block;
width: 40px;
height: 50px;
line-height: 45px;
background-color: rgba(0,0,0,.2);
font-size: 20px;
text-align: center;
display: none;
}
.slider-prev{
left: 0;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
.slider-next{
right: 0;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
</style>
</head>
<body>
<div class="wrap">
<div class="slide-box clearfix">
<ul class="slide-left"></ul>
<div class="slider-indicator"></div>
<a href="javascript:void(0)" class="slide-btn slider-prev"><</a>
<a href="javascript:void(0)" class="slide-btn slider-next">></a>
</div>
</div>
<script src="https://cdn.bootcss.com/jquery ... gt%3B
<script>
$(function(){
var data = [{
url: '#1',
img: '//img11.360buyimg.com/da/jfs/t4657/90/3561484677/83893/f05ac312/59004d0dNc66933b4.png'
},
{
url: '#2',
img: '//img1.360buyimg.com/da/jfs/t5122/78/482212244/90225/c4ccd3b7/59001933Nb4a11a00.jpg'
},
{
url: '#3',
img: '//img12.360buyimg.com/da/jfs/t3172/29/7532815266/78514/96c6e177/58ba3348N479cafe1.jpg'
},
{
url: '#4',
img: '//img20.360buyimg.com/da/jfs/t4249/102/1331521120/224199/40dcb547/58c0b221N5acfd3c6.jpg'
},
{
url: '#5',
img: '//img13.360buyimg.com/da/jfs/t5518/250/560655744/102051/9f4965b2/5901d835N6c3481c7.jpg'
}];

var slide = $('.slide-box');
var prev = $('.slider-prev');
var next = $('.slider-next');
var slideLeftData = $('.slide-left');
var slideIndicator = $('.slider-indicator');
var index = 0,slideAuto=null,isAnimate=false;

var slideData = ''; // 数据
var pageIndicator = ''; // page的小点
$.each(data, function(index, val) {
slideData += "<li data-id="+index+"><a href="+val.url+">![](+val.img+)</a></li>";
pageIndicator += "<i></i>";
});
slideLeftData.append(slideData); // 给左边盒子添加图片信息

slideIndicator.append(pageIndicator).find('i').eq(0).addClass('page-active'); // 给第一个小点添加样式
$('.slide-left li').eq(0).show();

prev.on('click', prevPage); // 点击上一页
next.on('click', nextPage); // 点击下一页
// 自动运行函数
var autoRun = function(){
slideAuto = setInterval(function(){
nextPage(index);
}, 3000)
}
autoRun();
// 上一页
function prevPage(){
if(isAnimate){ return;}
isAnimate = true;
index--;
if(index < 0){
index = data.length -1;
}
slideLeftData.find('li').eq(index).fadeIn().siblings().fadeOut();
slidePage(index);
isAnimate = false;
}

// 下一页
function nextPage(){
if(isAnimate){ return;}
isAnimate = true;
index++;
if(index >= data.length){
index = 0;
}
slideLeftData.find('li').eq(index).fadeIn().siblings().fadeOut();
slidePage(index);
isAnimate = false;
}
// page
slideIndicator.on('mouseenter', 'i', function(){
var pageIndex = $(this).index();
index = pageIndex;
$(this).addClass('page-active').siblings().removeClass('page-active');
slideLeftData.find('li').eq(pageIndex).fadeIn().siblings().fadeOut();
});
// 获取当前page 并添加样式
function slidePage(){
slideIndicator.find('i').eq(index).addClass('page-active').siblings().removeClass('page-active')
}
// 鼠标移入时
slide.on('mouseenter', function(){
$('.slide-btn').show(); // 显示左右的按钮
clearInterval(slideAuto); // 清除定时器
});
// 鼠标移出时
slide.on('mouseleave', function(){
$('.slide-btn').hide(); // 隐藏左右的按钮
autoRun(); // 继续运行定时器
});
});
</script>
</body>
</html>
?轮播1在线查看

左右无缝切换的轮播
?
slide-box 是包括幻灯片的盒子,设置overflow: hidden;slide-ul 是幻灯片的盒子(宽度为img的宽度*img的length) 包括了所有的img(浮动在一行)分别给 幻灯片的盒子 最前面克隆 img 的最后一个,最后面克隆 img 的第一个 4,0,1,2,3,4,0此时克隆了两个,重新给图片盒子宽度添加总长度, 给第0个写一个 left -img (一个宽度)就显示真正的第一个图片每点击下一页时 (pageIndex++ > imgLength -1) 0 : pageIndex++; 根据对应的pageIndex操作 left每点击上一页时 (pageIndex-- < 0) imgLength-1 : pageIndex--; 在对应的pageIndex操作 left点击到最后一个和最前面一个图片时,在动画效果结果后操作css让元素left值变成对应克隆的对象left,造成一个无限切换的错觉

实例代码<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery-slide-无缝滚动</title>
<style>
*{
margin: 0;
padding: 0;
}
body {
font-family: "Droid Serif","Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
}
.clearfix:after{
content: "";
display: block;
clear: both;
}
input,button,select,textarea{
outline:none;border: none;
}
a{
text-decoration: none;
color: #fff;
}
ul,li{
list-style: none;
}
img{
border: none;
}
.wrap{
width: 790px;
margin: 20px auto;
}
.slide-box{
height: 340px;
overflow: hidden;
position: relative;
}
.slide-ul{
width: 100%;
position: relative;
}
.slide-ul li{
width: 790px;
float: left;
}
.slide-ul li a{
display: block;
}
.slide-ul li a img{
width: 100%;
}

.slider-indicator{
position: absolute;
z-index: 1;
left: 50%;
transform: translateX(-50%);
bottom: 20px;
font-size: 0;
padding: 4px 8px;
border-radius: 12px;
background-color: rgba(255, 255, 255, 0.3);
}
.slider-indicator i{
display: inline-block;
margin-right: 10px;
width: 12px;
height: 12px;
border-radius: 100%;
background-color: #fff;
cursor: pointer;
}
.slider-indicator i.page-active{
background-color: #2196F3;
}
.slide-btn{
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 1;
display: block;
width: 40px;
height: 50px;
line-height: 45px;
background-color: rgba(0,0,0,.2);
font-size: 20px;
text-align: center;
display: none;
}
.slider-prev{
left: 0;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
.slider-next{
right: 0;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
</style>
</head>
<body>
<div class="wrap">
<div class="slide-box clearfix">
<ul class="slide-ul"></ul>
<div class="slider-indicator"></div>
<a href="javascript:void(0)" class="slide-btn slider-prev"><</a>
<a href="javascript:void(0)" class="slide-btn slider-next">></a>
</div>
</div>
<script src="https://cdn.bootcss.com/jquery ... gt%3B
<script>
$(function(){
var data = [{
url: '#1',
img: '//img11.360buyimg.com/da/jfs/t4657/90/3561484677/83893/f05ac312/59004d0dNc66933b4.png'
},
{
url: '#2',
img: '//img1.360buyimg.com/da/jfs/t5122/78/482212244/90225/c4ccd3b7/59001933Nb4a11a00.jpg'
},
{
url: '#3',
img: '//img12.360buyimg.com/da/jfs/t3172/29/7532815266/78514/96c6e177/58ba3348N479cafe1.jpg'
},
{
url: '#4',
img: '//img20.360buyimg.com/da/jfs/t4249/102/1331521120/224199/40dcb547/58c0b221N5acfd3c6.jpg'
},
{
url: '#5',
img: '//img13.360buyimg.com/da/jfs/t5518/250/560655744/102051/9f4965b2/5901d835N6c3481c7.jpg'
}];

var slide = $('.slide-box'), // 幻灯片盒子
prev = $('.slider-prev'), // 上一页按钮
next = $('.slider-next'), // 下一页按钮
slideUl = $('.slide-ul'), // 图片盒子
slideIndicator = $('.slider-indicator'), // 中部page盒子
pageIndex = 0, // page索引
slideAuto=null, // 自动滚动方法
isAnimate=false, // 事件锁
slideData = '', // img数据变量
pageIndicator = ''; // page的小点变量

// 循环添加img数据和page小点的个数
$.each(data, function(index, val) {
slideData += "<li data-id="+index+"><a href="+val.url+">![](+val.img+)</a></li>";
pageIndicator += "<i></i>";
});
// 给盒子添加图片信息
slideUl.append(slideData);
// 给page盒子添加小点并给第一个添加 page-active 样式
slideIndicator.append(pageIndicator).find('i').eq(0).addClass('page-active');
// 默认给第一个li添加显示
$('.slide-ul li').eq(0).show();
// 获取图片盒子里面的 li 个数
var imgLength = slideUl.children().length;
// 分别给 图片盒子 最前面克隆 li 最后一个,最后面克隆 li 第一个 [4,0,1,2,3,4,0]
var lastLi = slideUl.find('li').last();
var firstLi = slideUl.find('li').first();
slideUl.prepend(lastLi.clone())
slideUl.append(firstLi.clone());

// 获取克隆后图片盒子里面的 li 个数
var countLength = slideUl.children().length;
// 单独一个li的盒子宽度
var slideLiWidth = slideUl.find('li').width();
// 重新计算出 图片盒子 的宽度 让 li 浮动在一行
var boxWidth = countLength * slideLiWidth;
// 给图片盒子宽度添加总长度 然后第一个看到的是克隆的那个,所以给个 - 一个li宽度 就显示真正的第一个
slideUl.css({'left': -slide.width(), width: boxWidth});

// 点击上一页
prev.on('click', function(){
prevPage(1)
});
// 点击下一页
next.on('click', function(){
nextPage(1);
});

// 自动运行函数
var autoRun = function(){
slideAuto = setInterval(function(){
nextPage(1);
}, 3000)
}
autoRun();
// 上一页
function prevPage(len){
if(isAnimate){ return;}
isAnimate = true;
pageIndex -=len;
// '-='+slideLiWidth 0 -790px -1580px -2370px -3160px -3950px
slideUl.animate({left: '+='+len*slideLiWidth },function(){
if( pageIndex < 0){
pageIndex = imgLength-1; // 获取最后一个
slideUl.css({left: -slideLiWidth*imgLength}); // 默认回到 -3950px 也就是第后一个
}
isAnimate = false;
slidePage(pageIndex); // 获取当前的 小点 状态
});

}
// 下一页
function nextPage(len){
if(isAnimate){ return;}
isAnimate = true;
pageIndex += len;
console.log( pageIndex )
// '-='+slideLiWidth -790px -1580px -2370px -3160px -3950px
slideUl.animate({left: '-='+len*slideLiWidth },function(){
// 判断当前索引是否等于img图片的长度(没克隆前的长度)
if(pageIndex > imgLength -1 ){
pageIndex = 0; // 给索引值设置为0 也就是当前一个
slideUl.css({left: -slideLiWidth}); // 默认回到 -790px 也就是第0个
}
isAnimate = false;
slidePage(pageIndex); // 获取当前的 小点 状态
});
}
// 点击切换
slideIndicator.on('click', 'i', function(){
var index = $(this).index();
$(this).addClass('page-active').siblings().removeClass('page-active');
if(pageIndex > index){ // 当前page 大于 当前索引
prevPage(pageIndex - index); // 向后移动
}else{
nextPage(index - pageIndex); // 向前移动
}
});
// 获取当前page 并添加样式
function slidePage(){
slideIndicator.find('i').removeClass('page-active').eq(pageIndex).addClass('page-active')
}
// 鼠标移入时
slide.on('mouseenter', function(){
$('.slide-btn').show(); // 显示左右的按钮
clearInterval(slideAuto); // 清除定时器
});
// 鼠标移出时
slide.on('mouseleave', function(){
$('.slide-btn').hide(); // 隐藏左右的按钮
autoRun(); // 继续运行定时器
});
});
</script>
</body>
</html>
轮播2在线查看

制作简书首页的幻灯片
?
功能结合了淡入淡出和无缝滚动
轮播3在线查看 查看全部
淡入淡出的轮播
?
  • slide-ul 是幻灯片的盒子 包括了所有的img position: relative;
  • img position: absolute; 全部隐藏,默认显示第一张图片
  • pageIndex 分页索引对应 img 的索引
  • 在点击分页索引时 给对应的 img 显示,其它的 img 隐藏
  • 设置一个定时器函数每三秒执行一次,每次都传入 pageIndex 实现定时切换 默认是 0 判断 (pageIndex++ >= img.length) 0 : pageIndex++
  • 鼠标移入图片清除定时器 鼠标移出时重启定时器


实例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery-slide-fadeIn</title>
<style>
*{
margin: 0;
padding: 0;
}
body {
font-family: "Droid Serif","Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
}
.clearfix:after{
content: "";
display: block;
clear: both;
}
input,button,select,textarea{
outline:none;border: none;
}
a{
text-decoration: none;
color: #fff;
}
ul,li{
list-style: none;
}
img{
border: none;
}
.wrap{
width: 790px;
margin: 20px auto;
}
.slide-box{
height: 340px;
overflow: hidden;
position: relative;
}
.slide-left{
width: 100%;
position: relative;
}
.slide-left li{
position: absolute;
display: none;
}
.slide-left li a{
display: block;
}
.slide-left li a img{
width: 100%;
}

.slider-indicator{
position: absolute;
z-index: 1;
left: 50%;
transform: translateX(-50%);
bottom: 20px;
font-size: 0;
padding: 4px 8px;
border-radius: 12px;
background-color: rgba(255, 255, 255, 0.3);
}
.slider-indicator i{
display: inline-block;
margin-right: 10px;
width: 12px;
height: 12px;
border-radius: 100%;
background-color: #fff;
cursor: pointer;
}
.slider-indicator i.page-active{
background-color: #2196F3;
}
.slide-btn{
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 1;
display: block;
width: 40px;
height: 50px;
line-height: 45px;
background-color: rgba(0,0,0,.2);
font-size: 20px;
text-align: center;
display: none;
}
.slider-prev{
left: 0;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
.slider-next{
right: 0;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
</style>
</head>
<body>
<div class="wrap">
<div class="slide-box clearfix">
<ul class="slide-left"></ul>
<div class="slider-indicator"></div>
<a href="javascript:void(0)" class="slide-btn slider-prev"><</a>
<a href="javascript:void(0)" class="slide-btn slider-next">></a>
</div>
</div>
<script src="https://cdn.bootcss.com/jquery ... gt%3B
<script>
$(function(){
var data = [{
url: '#1',
img: '//img11.360buyimg.com/da/jfs/t4657/90/3561484677/83893/f05ac312/59004d0dNc66933b4.png'
},
{
url: '#2',
img: '//img1.360buyimg.com/da/jfs/t5122/78/482212244/90225/c4ccd3b7/59001933Nb4a11a00.jpg'
},
{
url: '#3',
img: '//img12.360buyimg.com/da/jfs/t3172/29/7532815266/78514/96c6e177/58ba3348N479cafe1.jpg'
},
{
url: '#4',
img: '//img20.360buyimg.com/da/jfs/t4249/102/1331521120/224199/40dcb547/58c0b221N5acfd3c6.jpg'
},
{
url: '#5',
img: '//img13.360buyimg.com/da/jfs/t5518/250/560655744/102051/9f4965b2/5901d835N6c3481c7.jpg'
}];

var slide = $('.slide-box');
var prev = $('.slider-prev');
var next = $('.slider-next');
var slideLeftData = $('.slide-left');
var slideIndicator = $('.slider-indicator');
var index = 0,slideAuto=null,isAnimate=false;

var slideData = ''; // 数据
var pageIndicator = ''; // page的小点
$.each(data, function(index, val) {
slideData += "<li data-id="+index+"><a href="+val.url+">![](+val.img+)</a></li>";
pageIndicator += "<i></i>";
});
slideLeftData.append(slideData); // 给左边盒子添加图片信息

slideIndicator.append(pageIndicator).find('i').eq(0).addClass('page-active'); // 给第一个小点添加样式
$('.slide-left li').eq(0).show();

prev.on('click', prevPage); // 点击上一页
next.on('click', nextPage); // 点击下一页
// 自动运行函数
var autoRun = function(){
slideAuto = setInterval(function(){
nextPage(index);
}, 3000)
}
autoRun();
// 上一页
function prevPage(){
if(isAnimate){ return;}
isAnimate = true;
index--;
if(index < 0){
index = data.length -1;
}
slideLeftData.find('li').eq(index).fadeIn().siblings().fadeOut();
slidePage(index);
isAnimate = false;
}

// 下一页
function nextPage(){
if(isAnimate){ return;}
isAnimate = true;
index++;
if(index >= data.length){
index = 0;
}
slideLeftData.find('li').eq(index).fadeIn().siblings().fadeOut();
slidePage(index);
isAnimate = false;
}
// page
slideIndicator.on('mouseenter', 'i', function(){
var pageIndex = $(this).index();
index = pageIndex;
$(this).addClass('page-active').siblings().removeClass('page-active');
slideLeftData.find('li').eq(pageIndex).fadeIn().siblings().fadeOut();
});
// 获取当前page 并添加样式
function slidePage(){
slideIndicator.find('i').eq(index).addClass('page-active').siblings().removeClass('page-active')
}
// 鼠标移入时
slide.on('mouseenter', function(){
$('.slide-btn').show(); // 显示左右的按钮
clearInterval(slideAuto); // 清除定时器
});
// 鼠标移出时
slide.on('mouseleave', function(){
$('.slide-btn').hide(); // 隐藏左右的按钮
autoRun(); // 继续运行定时器
});
});
</script>
</body>
</html>

?轮播1在线查看

左右无缝切换的轮播
?
  • slide-box 是包括幻灯片的盒子,设置overflow: hidden;
  • slide-ul 是幻灯片的盒子(宽度为img的宽度*img的length) 包括了所有的img(浮动在一行)
  • 分别给 幻灯片的盒子 最前面克隆 img 的最后一个,最后面克隆 img 的第一个 4,0,1,2,3,4,0
  • 此时克隆了两个,重新给图片盒子宽度添加总长度, 给第0个写一个 left -img (一个宽度)就显示真正的第一个图片
  • 每点击下一页时 (pageIndex++ > imgLength -1) 0 : pageIndex++; 根据对应的pageIndex操作 left
  • 每点击上一页时 (pageIndex-- < 0) imgLength-1 : pageIndex--; 在对应的pageIndex操作 left
  • 点击到最后一个和最前面一个图片时,在动画效果结果后操作css让元素left值变成对应克隆的对象left,造成一个无限切换的错觉


实例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery-slide-无缝滚动</title>
<style>
*{
margin: 0;
padding: 0;
}
body {
font-family: "Droid Serif","Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
}
.clearfix:after{
content: "";
display: block;
clear: both;
}
input,button,select,textarea{
outline:none;border: none;
}
a{
text-decoration: none;
color: #fff;
}
ul,li{
list-style: none;
}
img{
border: none;
}
.wrap{
width: 790px;
margin: 20px auto;
}
.slide-box{
height: 340px;
overflow: hidden;
position: relative;
}
.slide-ul{
width: 100%;
position: relative;
}
.slide-ul li{
width: 790px;
float: left;
}
.slide-ul li a{
display: block;
}
.slide-ul li a img{
width: 100%;
}

.slider-indicator{
position: absolute;
z-index: 1;
left: 50%;
transform: translateX(-50%);
bottom: 20px;
font-size: 0;
padding: 4px 8px;
border-radius: 12px;
background-color: rgba(255, 255, 255, 0.3);
}
.slider-indicator i{
display: inline-block;
margin-right: 10px;
width: 12px;
height: 12px;
border-radius: 100%;
background-color: #fff;
cursor: pointer;
}
.slider-indicator i.page-active{
background-color: #2196F3;
}
.slide-btn{
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 1;
display: block;
width: 40px;
height: 50px;
line-height: 45px;
background-color: rgba(0,0,0,.2);
font-size: 20px;
text-align: center;
display: none;
}
.slider-prev{
left: 0;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
.slider-next{
right: 0;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
</style>
</head>
<body>
<div class="wrap">
<div class="slide-box clearfix">
<ul class="slide-ul"></ul>
<div class="slider-indicator"></div>
<a href="javascript:void(0)" class="slide-btn slider-prev"><</a>
<a href="javascript:void(0)" class="slide-btn slider-next">></a>
</div>
</div>
<script src="https://cdn.bootcss.com/jquery ... gt%3B
<script>
$(function(){
var data = [{
url: '#1',
img: '//img11.360buyimg.com/da/jfs/t4657/90/3561484677/83893/f05ac312/59004d0dNc66933b4.png'
},
{
url: '#2',
img: '//img1.360buyimg.com/da/jfs/t5122/78/482212244/90225/c4ccd3b7/59001933Nb4a11a00.jpg'
},
{
url: '#3',
img: '//img12.360buyimg.com/da/jfs/t3172/29/7532815266/78514/96c6e177/58ba3348N479cafe1.jpg'
},
{
url: '#4',
img: '//img20.360buyimg.com/da/jfs/t4249/102/1331521120/224199/40dcb547/58c0b221N5acfd3c6.jpg'
},
{
url: '#5',
img: '//img13.360buyimg.com/da/jfs/t5518/250/560655744/102051/9f4965b2/5901d835N6c3481c7.jpg'
}];

var slide = $('.slide-box'), // 幻灯片盒子
prev = $('.slider-prev'), // 上一页按钮
next = $('.slider-next'), // 下一页按钮
slideUl = $('.slide-ul'), // 图片盒子
slideIndicator = $('.slider-indicator'), // 中部page盒子
pageIndex = 0, // page索引
slideAuto=null, // 自动滚动方法
isAnimate=false, // 事件锁
slideData = '', // img数据变量
pageIndicator = ''; // page的小点变量

// 循环添加img数据和page小点的个数
$.each(data, function(index, val) {
slideData += "<li data-id="+index+"><a href="+val.url+">![](+val.img+)</a></li>";
pageIndicator += "<i></i>";
});
// 给盒子添加图片信息
slideUl.append(slideData);
// 给page盒子添加小点并给第一个添加 page-active 样式
slideIndicator.append(pageIndicator).find('i').eq(0).addClass('page-active');
// 默认给第一个li添加显示
$('.slide-ul li').eq(0).show();
// 获取图片盒子里面的 li 个数
var imgLength = slideUl.children().length;
// 分别给 图片盒子 最前面克隆 li 最后一个,最后面克隆 li 第一个 [4,0,1,2,3,4,0]
var lastLi = slideUl.find('li').last();
var firstLi = slideUl.find('li').first();
slideUl.prepend(lastLi.clone())
slideUl.append(firstLi.clone());

// 获取克隆后图片盒子里面的 li 个数
var countLength = slideUl.children().length;
// 单独一个li的盒子宽度
var slideLiWidth = slideUl.find('li').width();
// 重新计算出 图片盒子 的宽度 让 li 浮动在一行
var boxWidth = countLength * slideLiWidth;
// 给图片盒子宽度添加总长度 然后第一个看到的是克隆的那个,所以给个 - 一个li宽度 就显示真正的第一个
slideUl.css({'left': -slide.width(), width: boxWidth});

// 点击上一页
prev.on('click', function(){
prevPage(1)
});
// 点击下一页
next.on('click', function(){
nextPage(1);
});

// 自动运行函数
var autoRun = function(){
slideAuto = setInterval(function(){
nextPage(1);
}, 3000)
}
autoRun();
// 上一页
function prevPage(len){
if(isAnimate){ return;}
isAnimate = true;
pageIndex -=len;
// '-='+slideLiWidth 0 -790px -1580px -2370px -3160px -3950px
slideUl.animate({left: '+='+len*slideLiWidth },function(){
if( pageIndex < 0){
pageIndex = imgLength-1; // 获取最后一个
slideUl.css({left: -slideLiWidth*imgLength}); // 默认回到 -3950px 也就是第后一个
}
isAnimate = false;
slidePage(pageIndex); // 获取当前的 小点 状态
});

}
// 下一页
function nextPage(len){
if(isAnimate){ return;}
isAnimate = true;
pageIndex += len;
console.log( pageIndex )
// '-='+slideLiWidth -790px -1580px -2370px -3160px -3950px
slideUl.animate({left: '-='+len*slideLiWidth },function(){
// 判断当前索引是否等于img图片的长度(没克隆前的长度)
if(pageIndex > imgLength -1 ){
pageIndex = 0; // 给索引值设置为0 也就是当前一个
slideUl.css({left: -slideLiWidth}); // 默认回到 -790px 也就是第0个
}
isAnimate = false;
slidePage(pageIndex); // 获取当前的 小点 状态
});
}
// 点击切换
slideIndicator.on('click', 'i', function(){
var index = $(this).index();
$(this).addClass('page-active').siblings().removeClass('page-active');
if(pageIndex > index){ // 当前page 大于 当前索引
prevPage(pageIndex - index); // 向后移动
}else{
nextPage(index - pageIndex); // 向前移动
}
});
// 获取当前page 并添加样式
function slidePage(){
slideIndicator.find('i').removeClass('page-active').eq(pageIndex).addClass('page-active')
}
// 鼠标移入时
slide.on('mouseenter', function(){
$('.slide-btn').show(); // 显示左右的按钮
clearInterval(slideAuto); // 清除定时器
});
// 鼠标移出时
slide.on('mouseleave', function(){
$('.slide-btn').hide(); // 隐藏左右的按钮
autoRun(); // 继续运行定时器
});
});
</script>
</body>
</html>

轮播2在线查看

制作简书首页的幻灯片
?
  • 功能结合了淡入淡出和无缝滚动

轮播3在线查看

JavaScript正则表达式基本语法

javascript/jQueryboloog 发表了文章 • 0 个评论 • 1831 次浏览 • 2017-04-28 20:08 • 来自相关话题

1.?\d,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{3},^,$,分别是什么?
\d 匹配 [0-9] 数字字符
\w 匹配 [a-zA-Z_0-9] 单词字符,字母、数字下划线
\s 匹配 [\t\n\x0B\f\r] 空白符
[a-zA-Z0-9] 匹配范围类 小写字母a-z 大写字母 A-Z 和数字 0-9
\b 匹配单词边界
var str ='hello world';
/llo\b/.test(str); // true 匹配边界是llo
/wor\b/.test(str); // false 匹配边界是wor
. 匹配 [^\r\n] 除了回车符和换行符之外的所有字符
* 匹配 出现零次或多次(任意次)
+ 匹配 出现一次或多次(至少出现一次)
? 匹配 出现零次或一次(最多出现一次)
x{3} 匹配 x出现3次
^ 匹配 以xxx开头
$ 匹配 以xxx结束
2.?去除字符串两边的空白字符
?
var str = ' hello bsfans ';
function trim(str){
return str.replace(/^\s+|\s+$/g,'');
}
trim(str);
?3.?判断用户输入的是不是邮箱
?
var str = 'bsfans@admin.com';
function isEmail(str){
return /^\w+@\w+\.(com|cn|com\.cn)$/.test( str );
}
isEmail(str);
?4.?判断用户输入的是不是手机号
?
function isPhoneNum(str){
return /^1[3|5|6|7|8]\d{9}$/.test( str )
}
isPhoneNum('13600007663');
?5.?判断用户输入的是不是合法的用户名(长度6-20个字符,只能包括字母、数字、下划线)
?
function isValidUsername(str){
return /^\w{6,20}$/.test( str )
}
isValidUsername('a_3EDdfd');
?6.?判断用户输入的是不是合法密码(长度6-20个字符,只包括大写字母、小写字母、数字、下划线,且至少至少包括两种)
?
function isValidPassword(str){
if(str.length < 6 || str.length > 20){
return false;
}
var num = 0;
if(/[A-Z]/.test(str)){
num++;
}
if(/[a-z]/.test(str)){
num++;
}
if(/[0-9]/.test(str)){
num++;
}
if(/_/.test(str)){
num++;
}
return num >= 2;
}
isValidPassword('qweqeqew'); // false
isValidPassword('qweqe111'); // true
?
?
?
?
?
?
?
?
?
?
?
?
?
?
? 查看全部
1.?\d,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{3},^,$,分别是什么?
\d 匹配 [0-9] 数字字符
\w 匹配 [a-zA-Z_0-9] 单词字符,字母、数字下划线
\s 匹配 [\t\n\x0B\f\r] 空白符
[a-zA-Z0-9] 匹配范围类 小写字母a-z 大写字母 A-Z 和数字 0-9
\b 匹配单词边界
var str ='hello world';
/llo\b/.test(str); // true 匹配边界是llo
/wor\b/.test(str); // false 匹配边界是wor
. 匹配 [^\r\n] 除了回车符和换行符之外的所有字符
* 匹配 出现零次或多次(任意次)
+ 匹配 出现一次或多次(至少出现一次)
? 匹配 出现零次或一次(最多出现一次)
x{3} 匹配 x出现3次
^ 匹配 以xxx开头
$ 匹配 以xxx结束

2.?去除字符串两边的空白字符
?
var str = '  hello bsfans ';
function trim(str){
return str.replace(/^\s+|\s+$/g,'');
}
trim(str);

?3.?判断用户输入的是不是邮箱
?
var str = 'bsfans@admin.com';
function isEmail(str){
return /^\w+@\w+\.(com|cn|com\.cn)$/.test( str );
}
isEmail(str);

?4.?判断用户输入的是不是手机号
?
function isPhoneNum(str){
return /^1[3|5|6|7|8]\d{9}$/.test( str )
}
isPhoneNum('13600007663');

?5.?判断用户输入的是不是合法的用户名(长度6-20个字符,只能包括字母、数字、下划线)
?
function isValidUsername(str){
return /^\w{6,20}$/.test( str )
}
isValidUsername('a_3EDdfd');

?6.?判断用户输入的是不是合法密码(长度6-20个字符,只包括大写字母、小写字母、数字、下划线,且至少至少包括两种)
?
function isValidPassword(str){
if(str.length < 6 || str.length > 20){
return false;
}
var num = 0;
if(/[A-Z]/.test(str)){
num++;
}
if(/[a-z]/.test(str)){
num++;
}
if(/[0-9]/.test(str)){
num++;
}
if(/_/.test(str)){
num++;
}
return num >= 2;
}
isValidPassword('qweqeqew'); // false
isValidPassword('qweqe111'); // true

?
?
?
?
?
?
?
?
?
?
?
?
?
?
?