bootstrap 3.x +vue 2.x 饿了么pc端导航模拟
bootstrap3.x • lopo1983 发表了文章 • 0 个评论 • 2065 次浏览 • 2016-12-08 22:48
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
<style>
.nav>li>a {
border-radius: 0;
cursor: pointer;
color: #101010;
}
#pmenu a {
cursor: pointer;
}
#pmenu .active a {
background-color: lightgrey;
color: #080808;
border-radius: 0;
}
#cmenu {
background-color: lightgrey;
}
#cmenu li {
padding: 10px 5px;
}
#cmenu .active a {}
</style>
</head>
<body>
<div id="app">
<topnav></topnav>
</div>
<!--template-->
<template id="topnav-comp">
<div>
<ul class="nav nav-pills nav-justified" id="pmenu">
<li v-for="(nav,index) in navlist" :class="{active:iscurP==index}" @click="iscurP=index">
<a @click="getChild(index)">{{nav.name}}</a>
</li>
</ul>
<ul class="nav nav-pills" id="cmenu">
<li v-for="(navc,index) in navchild" :class="{active:iscurC==index}" @click="iscurC=index">
<a>{{navc.name}}</a>
</li>
</ul>
</div>
</template>
<script type="text/javascript" src="js/jquery-2.1.0.js"></script>
<script type="text/javascript" src="js/vue.js"></script>
<script>
Vue.component('topnav', {
template: '#topnav-comp',
data: function() {
return {
iscurP: 0,
iscurC: 0,
navlist: [],
navchild: []
}
},
methods: {
getNavlist: function() {
var self = this
$.ajax({
url: 'data/navlist.json',
type: 'get',
async: false,
dataType: "json",
success: function(data) {
self.navlist = data;
},
error: function() {
console.log('%c 数据加载失败,请检查数据是否存在', 'background: #222; color: #bada55')
}
});
},
getChild: function(index) {
this.navchild = this.navlist[index].sub_categories;
this.iscurC = 0
}
},
mounted: function() {},
created: function() {
this.getNavlist();
}
});
vm = new Vue({
el: "#app"
})
</script>
</body>
</htm 查看全部
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
<style>
.nav>li>a {
border-radius: 0;
cursor: pointer;
color: #101010;
}
#pmenu a {
cursor: pointer;
}
#pmenu .active a {
background-color: lightgrey;
color: #080808;
border-radius: 0;
}
#cmenu {
background-color: lightgrey;
}
#cmenu li {
padding: 10px 5px;
}
#cmenu .active a {}
</style>
</head>
<body>
<div id="app">
<topnav></topnav>
</div>
<!--template-->
<template id="topnav-comp">
<div>
<ul class="nav nav-pills nav-justified" id="pmenu">
<li v-for="(nav,index) in navlist" :class="{active:iscurP==index}" @click="iscurP=index">
<a @click="getChild(index)">{{nav.name}}</a>
</li>
</ul>
<ul class="nav nav-pills" id="cmenu">
<li v-for="(navc,index) in navchild" :class="{active:iscurC==index}" @click="iscurC=index">
<a>{{navc.name}}</a>
</li>
</ul>
</div>
</template>
<script type="text/javascript" src="js/jquery-2.1.0.js"></script>
<script type="text/javascript" src="js/vue.js"></script>
<script>
Vue.component('topnav', {
template: '#topnav-comp',
data: function() {
return {
iscurP: 0,
iscurC: 0,
navlist: [],
navchild: []
}
},
methods: {
getNavlist: function() {
var self = this
$.ajax({
url: 'data/navlist.json',
type: 'get',
async: false,
dataType: "json",
success: function(data) {
self.navlist = data;
},
error: function() {
console.log('%c 数据加载失败,请检查数据是否存在', 'background: #222; color: #bada55')
}
});
},
getChild: function(index) {
this.navchild = this.navlist[index].sub_categories;
this.iscurC = 0
}
},
mounted: function() {},
created: function() {
this.getNavlist();
}
});
vm = new Vue({
el: "#app"
})
</script>
</body>
</htm
bootstrap 基础css 问题集锦
bootstrap3.x • lopo1983 发表了文章 • 0 个评论 • 1877 次浏览 • 2016-11-24 10:02
A: 设置该元素css属性
line-height:normal
A: 设置该元素css属性
line-height:normal
Flex 布局教程:语法篇
CSS/SASS/SCSS/LESS • lopo1983 发表了文章 • 0 个评论 • 1687 次浏览 • 2016-09-02 12:19
布局的传统解决方案,基于盒状模型,依赖?display属性 +?position属性 +?float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。
2009年,W3C提出了一种新的方案----Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。
Flex布局将成为未来布局的首选方案。本文介绍它的语法,下一篇文章给出常见布局的Flex写法。
以下内容主要参考了下面两篇文章:A Complete Guide to Flexbox?和?A Visual Guide to CSS3 Flexbox Properties。
一、Flex布局是什么?
Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为Flex布局。
.box{ display: flex; }
行内元素也可以使用Flex布局。
.box{ display: inline-flex; }
Webkit内核的浏览器,必须加上-webkit前缀。
.box{ display: -webkit-flex; /* Safari */ display: flex; }
注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。
二、基本概念
采用Flex布局的元素,称为Flex容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称"项目"。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
三、容器的属性
以下6个属性设置在容器上。
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
3.1 flex-direction属性
flex-direction属性决定主轴的方向(即项目的排列方向)。
.box { flex-direction: row | row-reverse | column | column-reverse; }
它可能有4个值。
row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
3.2 flex-wrap属性
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
.box{ flex-wrap: nowrap | wrap | wrap-reverse; }
它可能取三个值。
(1)nowrap(默认):不换行。
(2)wrap:换行,第一行在上方。
(3)wrap-reverse:换行,第一行在下方。
3.3 flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.box { flex-flow: <flex-direction> || <flex-wrap>; }
3.4 justify-content属性
justify-content属性定义了项目在主轴上的对齐方式。
.box { justify-content: flex-start | flex-end | center | space-between | space-around; }
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。
flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
3.5 align-items属性
align-items属性定义项目在交叉轴上如何对齐。
.box { align-items: flex-start | flex-end | center | baseline | stretch; }
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
3.6 align-content属性
align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }
该属性可能取6个值。
flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。
四、项目的属性
以下6个属性设置在项目上。
order
flex-grow
flex-shrink
flex-basis
flex
align-self
4.1 order属性
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
.item { order: <integer>; }
4.2 flex-grow属性
flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
.item { flex-grow: <number>; /* default 0 */ }
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
4.3 flex-shrink属性
flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item { flex-shrink: <number>; /* default 1 */ }
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
负值对该属性无效。
4.4 flex-basis属性
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
.item { flex-basis: <length> | auto; /* default auto */ }
它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。
4.5 flex属性
flex属性是flex-grow,?flex-shrink?和?flex-basis的简写,默认值为0 1 auto。后两个属性可选。
.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] }
该属性有两个快捷值:auto?(1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
4.6 align-self属性
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。 查看全部
布局的传统解决方案,基于盒状模型,依赖?display属性 +?position属性 +?float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。
2009年,W3C提出了一种新的方案----Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。
Flex布局将成为未来布局的首选方案。本文介绍它的语法,下一篇文章给出常见布局的Flex写法。
以下内容主要参考了下面两篇文章:A Complete Guide to Flexbox?和?A Visual Guide to CSS3 Flexbox Properties。
一、Flex布局是什么?
Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为Flex布局。
.box{ display: flex; }
行内元素也可以使用Flex布局。
.box{ display: inline-flex; }
Webkit内核的浏览器,必须加上-webkit前缀。
.box{ display: -webkit-flex; /* Safari */ display: flex; }
注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。
二、基本概念
采用Flex布局的元素,称为Flex容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称"项目"。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
三、容器的属性
以下6个属性设置在容器上。
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
3.1 flex-direction属性
flex-direction属性决定主轴的方向(即项目的排列方向)。
.box { flex-direction: row | row-reverse | column | column-reverse; }
它可能有4个值。
row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
3.2 flex-wrap属性
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
.box{ flex-wrap: nowrap | wrap | wrap-reverse; }
它可能取三个值。
(1)nowrap(默认):不换行。
(2)wrap:换行,第一行在上方。
(3)wrap-reverse:换行,第一行在下方。
3.3 flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.box { flex-flow: <flex-direction> || <flex-wrap>; }
3.4 justify-content属性
justify-content属性定义了项目在主轴上的对齐方式。
.box { justify-content: flex-start | flex-end | center | space-between | space-around; }
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。
flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
3.5 align-items属性
align-items属性定义项目在交叉轴上如何对齐。
.box { align-items: flex-start | flex-end | center | baseline | stretch; }
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
3.6 align-content属性
align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }
该属性可能取6个值。
flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。
四、项目的属性
以下6个属性设置在项目上。
order
flex-grow
flex-shrink
flex-basis
flex
align-self
4.1 order属性
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
.item { order: <integer>; }
4.2 flex-grow属性
flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
.item { flex-grow: <number>; /* default 0 */ }
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
4.3 flex-shrink属性
flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item { flex-shrink: <number>; /* default 1 */ }
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
负值对该属性无效。
4.4 flex-basis属性
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
.item { flex-basis: <length> | auto; /* default auto */ }
它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。
4.5 flex属性
flex属性是flex-grow,?flex-shrink?和?flex-basis的简写,默认值为0 1 auto。后两个属性可选。
.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] }
该属性有两个快捷值:auto?(1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
4.6 align-self属性
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
HTML5 实现手机拍照上传
HTML • lopo1983 发表了文章 • 0 个评论 • 2412 次浏览 • 2016-08-30 11:11
PS:该属性存在浏览器兼容性问题,不是所有的浏览器都支持。
<input type="file" accept="image/*" capture="camera" >因为原生file样式不满足要求,需要进行相应的处理,此时使用定位,在input上面放置我们想要的页面效果。然后当点击上面的元素,就可以触发我们的input进行图片上传。此时的问题是:当点击input上面的元素,需要事件穿透,即相当于点击input。则借助于css3新属性pointer-events。
button{
cursor:pointer;
pointer-events:none;
}----此时图片上传的样式已经处理好了
----代码片段:
<style >
*{
padding: 0;
margin: 0;
}
.wrapper{
width: 320px;
height: 50px;
margin: 20px auto;
position: relative;
border: 1px solid #f0f0f0;
}
input{
width: 100px;
height: 30px;
}
button{
position: absolute;
cursor: pointer;
pointer-events: none;
width: 100px;
height: 30px;
left: 0;
top: 0;
}
a{
pointer-events: none;
}
.img{
border: 1px solid #ccc;
padding: 10px;
}
</style >
<div class = "wrapper">
<input type = "file" accept= "image/*" capture= "camera" id= "img" />
<button >上传照片 </button >
</div >
?
图片压缩处理:
因为要做的是手机拍照上传,现在的手机拍照片都很大,比如小米4S,大小在3M以上,如果原图上传,太消耗用户流量,于是要解决图片压缩的问题。
通过change事件,监听图片上传,通过readerAsDataURL获取上传的图片。
document.getElementById( 'img').addEventListener( 'change', function () {
var reader = new FileReader();
reader.onload = function (e) {
//调用图片压缩方法:compress();
};
reader.readAsDataURL(this.files[0]);
console.log(this.files[0]);
var fileSize = Math.round( this.files[0].size/1024/1024) ; //以M为单位
//this.files[0] 该信息包含:图片的大小,以byte计算 获取size的方法如下:this.files[0].size;
}, false);对上传的图片进行压缩,需要借助于canvas API,调用其中canvas.toDataURL(type,?encoderOptions);?将图片按照一定的压缩比进行压缩,得到base64编码。重点来了:压缩策略:先设置图片的最大宽度 or 最大高度,一般设置其中一个就可以了,因为所有的手机宽高比差别不是很大。然后设置图片的最大size,allowMaxSize,根据图片的实际大小和最大允许大小,设置相应的压缩比率。
//最终实现思路:
1、设置压缩后的最大宽度 or 高度;
2、设置压缩比例,根据图片的不同size大小,设置不同的压缩比。
function compress(res,fileSize) { //res代表上传的图片,fileSize大小图片的大小
var img = new Image(),
maxW = 640; //设置最大宽度
img.onload = function () {
var cvs = document.createElement( 'canvas'),
ctx = cvs.getContext( '2d');
if(img.width > maxW) {
img.height *= maxW / img.width;
img.width = maxW;
}
cvs.width = img.width;
cvs.height = img.height;
ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.drawImage(img, 0, 0, img.width, img.height);
var compressRate = getCompressRate(1,fileSize);
var dataUrl = cvs.toDataURL( 'image/jpeg', compressRate);
document.body.appendChild(cvs);
console.log(dataUrl);
}
img.src = res;
}
function getCompressRate(allowMaxSize,fileSize){ //计算压缩比率,size单位为MB
var compressRate = 1;
if(fileSize/allowMaxSize > 4){
compressRate = 0.5;
} else if(fileSize/allowMaxSize >3){
compressRate = 0.6;
} else if(fileSize/allowMaxSize >2){
compressRate = 0.7;
} else if(fileSize > allowMaxSize){
compressRate = 0.8;
} else{
compressRate = 0.9;
}
return compressRate;
}
?
图片上传给服务器:图片已经压缩完成了,但是压缩后的图片不是File,而是一个base64编码,于是乎两个选择:1、以String的形式将base64编码上传给服务器,服务器转存base64为img图片;2、前端将base64转为File图片类型,上传给服务器。
方法一:压缩之后直接上传base64给后台,实现简单。
方法二:前端自己转存base64位File图片,这个对于前端 压力比较大。
原因:html5 canvas属于客户端API,没有权限去保存图片到硬盘,只有canvas.toDataURL()这一接口可导出画布的base64编码,以提供给服务器进行处理保存。所以如果要将base64编码转成图片需要借助于nodeJs。因为nodeJS有相关文件处理的API。
//使用nodeJS将base64转化成图片
var express = require('express');
var fs = require("fs");
var app = module.exports = express();
function dataToImage(dataUrl){
var base64Data = dataUrl.replace(/^data:image\/\w+;base64,/,'');
var dataBuffer = new Buffer(base64Data,'base64');
fs.writeFile('out.jpg',dataBuffer,function(err){
if(err){
console.log(err);
}else{
console.log('Success...');
}
});
}
dataToImage('data:image/jpeg;base64,/9...'); //图片完整base64过长,所以省略...
if(!module.parent){
app.listen(8000);
console.log('Express started on port 8000');
}Summary:如果使用nodeJS,需要单独部署nodeJS代码到服务器,整个逻辑会比较麻烦。综合比较两种方法,推荐使用第一种方法,直接传base64给服务器,后台处理相应的转化! 查看全部
PS:该属性存在浏览器兼容性问题,不是所有的浏览器都支持。
<input type="file" accept="image/*" capture="camera" >因为原生file样式不满足要求,需要进行相应的处理,此时使用定位,在input上面放置我们想要的页面效果。然后当点击上面的元素,就可以触发我们的input进行图片上传。此时的问题是:当点击input上面的元素,需要事件穿透,即相当于点击input。则借助于css3新属性pointer-events。
button{----此时图片上传的样式已经处理好了
cursor:pointer;
pointer-events:none;
}
----代码片段:
<style >
*{
padding: 0;
margin: 0;
}
.wrapper{
width: 320px;
height: 50px;
margin: 20px auto;
position: relative;
border: 1px solid #f0f0f0;
}
input{
width: 100px;
height: 30px;
}
button{
position: absolute;
cursor: pointer;
pointer-events: none;
width: 100px;
height: 30px;
left: 0;
top: 0;
}
a{
pointer-events: none;
}
.img{
border: 1px solid #ccc;
padding: 10px;
}
</style >
<div class = "wrapper">
<input type = "file" accept= "image/*" capture= "camera" id= "img" />
<button >上传照片 </button >
</div >
?
图片压缩处理:
因为要做的是手机拍照上传,现在的手机拍照片都很大,比如小米4S,大小在3M以上,如果原图上传,太消耗用户流量,于是要解决图片压缩的问题。
通过change事件,监听图片上传,通过readerAsDataURL获取上传的图片。
document.getElementById( 'img').addEventListener( 'change', function () {对上传的图片进行压缩,需要借助于canvas API,调用其中canvas.toDataURL(type,?encoderOptions);?将图片按照一定的压缩比进行压缩,得到base64编码。重点来了:压缩策略:先设置图片的最大宽度 or 最大高度,一般设置其中一个就可以了,因为所有的手机宽高比差别不是很大。然后设置图片的最大size,allowMaxSize,根据图片的实际大小和最大允许大小,设置相应的压缩比率。
var reader = new FileReader();
reader.onload = function (e) {
//调用图片压缩方法:compress();
};
reader.readAsDataURL(this.files[0]);
console.log(this.files[0]);
var fileSize = Math.round( this.files[0].size/1024/1024) ; //以M为单位
//this.files[0] 该信息包含:图片的大小,以byte计算 获取size的方法如下:this.files[0].size;
}, false);
//最终实现思路:
1、设置压缩后的最大宽度 or 高度;
2、设置压缩比例,根据图片的不同size大小,设置不同的压缩比。
function compress(res,fileSize) { //res代表上传的图片,fileSize大小图片的大小
var img = new Image(),
maxW = 640; //设置最大宽度
img.onload = function () {
var cvs = document.createElement( 'canvas'),
ctx = cvs.getContext( '2d');
if(img.width > maxW) {
img.height *= maxW / img.width;
img.width = maxW;
}
cvs.width = img.width;
cvs.height = img.height;
ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.drawImage(img, 0, 0, img.width, img.height);
var compressRate = getCompressRate(1,fileSize);
var dataUrl = cvs.toDataURL( 'image/jpeg', compressRate);
document.body.appendChild(cvs);
console.log(dataUrl);
}
img.src = res;
}
function getCompressRate(allowMaxSize,fileSize){ //计算压缩比率,size单位为MB
var compressRate = 1;
if(fileSize/allowMaxSize > 4){
compressRate = 0.5;
} else if(fileSize/allowMaxSize >3){
compressRate = 0.6;
} else if(fileSize/allowMaxSize >2){
compressRate = 0.7;
} else if(fileSize > allowMaxSize){
compressRate = 0.8;
} else{
compressRate = 0.9;
}
return compressRate;
}
?
图片上传给服务器:图片已经压缩完成了,但是压缩后的图片不是File,而是一个base64编码,于是乎两个选择:1、以String的形式将base64编码上传给服务器,服务器转存base64为img图片;2、前端将base64转为File图片类型,上传给服务器。
方法一:压缩之后直接上传base64给后台,实现简单。
方法二:前端自己转存base64位File图片,这个对于前端 压力比较大。
原因:html5 canvas属于客户端API,没有权限去保存图片到硬盘,只有canvas.toDataURL()这一接口可导出画布的base64编码,以提供给服务器进行处理保存。所以如果要将base64编码转成图片需要借助于nodeJs。因为nodeJS有相关文件处理的API。
//使用nodeJS将base64转化成图片Summary:如果使用nodeJS,需要单独部署nodeJS代码到服务器,整个逻辑会比较麻烦。综合比较两种方法,推荐使用第一种方法,直接传base64给服务器,后台处理相应的转化!
var express = require('express');
var fs = require("fs");
var app = module.exports = express();
function dataToImage(dataUrl){
var base64Data = dataUrl.replace(/^data:image\/\w+;base64,/,'');
var dataBuffer = new Buffer(base64Data,'base64');
fs.writeFile('out.jpg',dataBuffer,function(err){
if(err){
console.log(err);
}else{
console.log('Success...');
}
});
}
dataToImage('data:image/jpeg;base64,/9...'); //图片完整base64过长,所以省略...
if(!module.parent){
app.listen(8000);
console.log('Express started on port 8000');
}
前端装逼指南
扯蛋 • lopo1983 发表了文章 • 0 个评论 • 1686 次浏览 • 2016-08-22 13:56
Macbook Pro 是标配,美其名曰“提高开发体验”
什么?你还在用 Spotlight?赶紧给我换 Alfred!
编辑器,Sublime / Atom / VS Code 三选一
虽然很想用IDE,但一定要忍住,并且与人解释道:
“启动速度慢,消耗资源多,不适合我这种完美主义者
如果不是为了美观,我宁愿使用 Vim / Emacs”
命令行 iTerm2 + Oh-my-zsh
二逼青年用 bash,普通青年用 zsh
我们也只是想做一名普通人罢了
查资料虽然都是百度
但一定要称都是用 Google
且要说英文而不是中文的“谷歌”
使用美式发音,当自己是湾区老司机
尽管四级飘过,六级没过
在 Stack Overflow 上点数也低
但也要说每天都与各国程序员谈笑风生
§ 语言
这年头如果还不用 Babel + ES6
都不好意思说自己是 JSer
当然还有 TypeScript / CoffeeScript / Dart …
没学过没关系
对外人说自己“略懂”即可
反正最后都是编译为 ES5,你懂的
为了避免对方深入问
此时你应该继续发表高见:
“JS 是基于原型的函数式弱类语言
引入类与强类真的是不伦不类”
说到此,顿一下,表现出百感交集
随后继续徐徐道:
“可大势所趋,吾等小辈惟随波逐流”
说罢,即可挥挥衣袖转身离去
在这里不得不提一下,虽然使用 Babel 转码可以尽情装逼
但其对某些新特性的转换相当二逼(详情请看这篇文章)
一句话:Babel 虽好,但别贪杯哦(推荐Babel 在线实时编译)
§ 代码风格
摒 弃JSLint / JSHint / JSCS,拥抱 ESLint
尽管平时只是个搬砖的
但时刻以世界顶级企业的规范约束自己
于是?eslint-config-airbnb?成了我们的标配
一般新手是这样写的:
/* Low */
if (a) {
return b;
} else {
return c;
}
逼格稍微高一点的这样写:
/* Bigger */
if (a) return b; // 提前结束,免用大括号与else
return c;
实际上还能更进一步:
/* Bigger than bigger */
① return a ? b : c // 不要写分号,留白予人想象的空间
② return a && b || c
总而言之,代码越短,可读性越差,逼格越高
不能让人随便看懂,就像人不能轻易让人看透
§ 奇技淫巧
罄竹难书
§ 常用库
DOM库
标配是 jQuery,手机端有 Zepto 作为替代品
想要装逼且不怕坑,那就上 Mootools
Prototype?嗯,复古的逼格都是很高的
一定要说自己纯粹为了优雅简洁,不得不用 jQuery
(如何做到 jQuery-free,请看这篇文章)
当然,就算是写 jQuery
也能体现出逼格
我们来看看新手一般是怎么写的:
/* Low */
var value = $(".container .myInput1").val();
$(".container .myInput2").val(value);
$(".container .myInput3").attr("disabled", "disabled");
用双引号,以及对选择器性能认知不足,是新手的特征
一般直接使用类选择器的,都是对用户体验很有自信的
/* Bigger */
// 把div.container命名为myDiv
var $myDiv = $('#myDiv'), // 缓存DOM
v = $myDiv.find('.myInput1').val();
?
$myDiv
.find('.myInput2').val(v)
.end() // 坚持链式调用
.find('.myInput3').attr('disabled', 'disabled');
(有关 jQuery 选择器的性能以及最佳实践,请看这篇文章)
UI
BootStrap 烂大街
不是我们的菜
我们选择的标准是门槛要高
于是
Foundation6 / Ant Design
映入眼帘
请谨慎使用
Semantic UI / UIkit / Amaze UI …
避免不能自拔
工具库
后浪 lodash 把前浪 underscore 拍死在沙滩上
于是它成了唯一的选择
不过为了保持逼格
我们要尽量使用原汁原味的 ES6
就算要用也一定要注意素质:
/* Low */
import _ from 'lodash' // 把整个lodash打包进去了
/* Bigger */
import isEmpty from 'lodash/isEmpty' // 仅把个别函数打包
模板引擎
逼格最高显然是 Jade
但改名为 Pug(哈巴狗)后
就像是小龙女被尹志平不可描述后
再也无爱了
从此以后
留了胡子(Mustache)
扶着把手(Handlebars)
默默耕耘
异步编程
这里不谈 Q / Bluebird / Async / co / then 等库
皆因Babel已经支持所有的异步编程解决方案
当前最常用的还是Promise
有些新手会写出这种代码:
/* Low */
// 找出与用户1同市的所有用户
User.findById(1).then((user) => {
User.find({ city: user.city }).then((users) => {
res.json(users.toJSON())
})
})
这属于 Promise反模式,与回调函数无异
/* Bigger */
User.findById(1).then((user) => {
return User.find({ city: user.city }) // 返回Promise
}).then((users) => {
res.json(users.toJSON())
}).catch(next)
§ 包管理工具
如果你被
Bower / spm / Component / Duo …
坑过
请回到 npm 的怀抱
什么?jspm?有完没完…
§ 构建工具
想当年我不懂什么是自动构建工具
他们说:生命苦短,我们用 Grunt
好不容易用上 Grunt 的时候
他们又说:Gulp 基于流,符合 Unix 哲学
之后我虔诚地换上了 Gulp
他们双说:Webpack 最好用
最后终于用上了 Webpack
他们叒说:FIS3 约不约?。。。
§ 模块化方案
无论是
RequireJS (AMD)
SeaJS (CMD)
KMD.js (KMD)
Browserify (CommonJS)
…
最后都庆幸回归到 npm + Webpack
什么?SystemJS?有完没完…
§ MV*框架 / 技术栈 / 大型框架
Backbone
每个人都有一段不堪回首的经历
就像当年在 QQ 空间发“你若安好便是晴天”的说说
Backbone就是这样子的存在
Angular
一定要边吐槽边用,不然就一点都不 ng 了
“学习曲线陡峭”不应从你口中说出
“学习过程趣味盎然”才是你的菜
Vue
一定要用“优雅”来形容
就像用 ES6 一定要“大胆”
React技术栈
React 已经是前端高逼格的代名词
所以无论懂不懂都要喊:
“React 大法好”
因为这是一种信仰
称赞 JSX 的标新立异
谈谈 Flux / Redux
扯扯 Elm / RxJS
每到深入则戛然而止:
“太深入的太抽象,你们未必能理解”
由此,听者只会更加崇拜你
其他
还有国内相对小众的 Ember / Knockout / Avalon
(请别再把 YUI / Dojo / Ext / KISSY 扯进来了好伐)
§ 混合 / 原生开发
自从 PhoneGap 出来后
貌似我们也能抢 安卓/iOS 的饭碗了
Ionic 更是将 Hybrid APP 推向高潮
不过混合始终比不上原生
于是 React Native 应运而生
最近多了一个新的选择:Weex
别忘了还有桌面的 nw.js 以及 Electron
JSer从一入门开始,就掌握了改变世界的能力
也比其他程序员更容易走向人生的巅峰
§ 后端框架
我们一直标榜自己是全栈
不玩几下后端框架怎么行
快递员用 Express
风湿患者用 Koa
哲学家用 ThinkJS
水手用 Sails
还有全栈的 Meteor
上述都用一遍
相信也快转行了
§ 服务器进程管理
既然都玩上了后端框架
不懂部署服务器怎么行
二逼青年用 supervisor / nodemon
文艺青年用 forever
普通青年用 pm2
装逼青年用 Tmux + node 查看全部
Macbook Pro 是标配,美其名曰“提高开发体验”
什么?你还在用 Spotlight?赶紧给我换 Alfred!
编辑器,Sublime / Atom / VS Code 三选一
虽然很想用IDE,但一定要忍住,并且与人解释道:
“启动速度慢,消耗资源多,不适合我这种完美主义者
如果不是为了美观,我宁愿使用 Vim / Emacs”
命令行 iTerm2 + Oh-my-zsh
二逼青年用 bash,普通青年用 zsh
我们也只是想做一名普通人罢了
查资料虽然都是百度
但一定要称都是用 Google
且要说英文而不是中文的“谷歌”
使用美式发音,当自己是湾区老司机
尽管四级飘过,六级没过
在 Stack Overflow 上点数也低
但也要说每天都与各国程序员谈笑风生
§ 语言
这年头如果还不用 Babel + ES6
都不好意思说自己是 JSer
当然还有 TypeScript / CoffeeScript / Dart …
没学过没关系
对外人说自己“略懂”即可
反正最后都是编译为 ES5,你懂的
为了避免对方深入问
此时你应该继续发表高见:
“JS 是基于原型的函数式弱类语言
引入类与强类真的是不伦不类”
说到此,顿一下,表现出百感交集
随后继续徐徐道:
“可大势所趋,吾等小辈惟随波逐流”
说罢,即可挥挥衣袖转身离去
在这里不得不提一下,虽然使用 Babel 转码可以尽情装逼
但其对某些新特性的转换相当二逼(详情请看这篇文章)
一句话:Babel 虽好,但别贪杯哦(推荐Babel 在线实时编译)
§ 代码风格
摒 弃JSLint / JSHint / JSCS,拥抱 ESLint
尽管平时只是个搬砖的
但时刻以世界顶级企业的规范约束自己
于是?eslint-config-airbnb?成了我们的标配
一般新手是这样写的:
/* Low */
if (a) {
return b;
} else {
return c;
}
逼格稍微高一点的这样写:
/* Bigger */
if (a) return b; // 提前结束,免用大括号与else
return c;
实际上还能更进一步:
/* Bigger than bigger */
① return a ? b : c // 不要写分号,留白予人想象的空间
② return a && b || c
总而言之,代码越短,可读性越差,逼格越高
不能让人随便看懂,就像人不能轻易让人看透
§ 奇技淫巧
罄竹难书
§ 常用库
DOM库
标配是 jQuery,手机端有 Zepto 作为替代品
想要装逼且不怕坑,那就上 Mootools
Prototype?嗯,复古的逼格都是很高的
一定要说自己纯粹为了优雅简洁,不得不用 jQuery
(如何做到 jQuery-free,请看这篇文章)
当然,就算是写 jQuery
也能体现出逼格
我们来看看新手一般是怎么写的:
/* Low */
var value = $(".container .myInput1").val();
$(".container .myInput2").val(value);
$(".container .myInput3").attr("disabled", "disabled");
用双引号,以及对选择器性能认知不足,是新手的特征
一般直接使用类选择器的,都是对用户体验很有自信的
/* Bigger */
// 把div.container命名为myDiv
var $myDiv = $('#myDiv'), // 缓存DOM
v = $myDiv.find('.myInput1').val();
?
$myDiv
.find('.myInput2').val(v)
.end() // 坚持链式调用
.find('.myInput3').attr('disabled', 'disabled');
(有关 jQuery 选择器的性能以及最佳实践,请看这篇文章)
UI
BootStrap 烂大街
不是我们的菜
我们选择的标准是门槛要高
于是
Foundation6 / Ant Design
映入眼帘
请谨慎使用
Semantic UI / UIkit / Amaze UI …
避免不能自拔
工具库
后浪 lodash 把前浪 underscore 拍死在沙滩上
于是它成了唯一的选择
不过为了保持逼格
我们要尽量使用原汁原味的 ES6
就算要用也一定要注意素质:
/* Low */
import _ from 'lodash' // 把整个lodash打包进去了
/* Bigger */
import isEmpty from 'lodash/isEmpty' // 仅把个别函数打包
模板引擎
逼格最高显然是 Jade
但改名为 Pug(哈巴狗)后
就像是小龙女被尹志平不可描述后
再也无爱了
从此以后
留了胡子(Mustache)
扶着把手(Handlebars)
默默耕耘
异步编程
这里不谈 Q / Bluebird / Async / co / then 等库
皆因Babel已经支持所有的异步编程解决方案
当前最常用的还是Promise
有些新手会写出这种代码:
/* Low */
// 找出与用户1同市的所有用户
User.findById(1).then((user) => {
User.find({ city: user.city }).then((users) => {
res.json(users.toJSON())
})
})
这属于 Promise反模式,与回调函数无异
/* Bigger */
User.findById(1).then((user) => {
return User.find({ city: user.city }) // 返回Promise
}).then((users) => {
res.json(users.toJSON())
}).catch(next)
§ 包管理工具
如果你被
Bower / spm / Component / Duo …
坑过
请回到 npm 的怀抱
什么?jspm?有完没完…
§ 构建工具
想当年我不懂什么是自动构建工具
他们说:生命苦短,我们用 Grunt
好不容易用上 Grunt 的时候
他们又说:Gulp 基于流,符合 Unix 哲学
之后我虔诚地换上了 Gulp
他们双说:Webpack 最好用
最后终于用上了 Webpack
他们叒说:FIS3 约不约?。。。
§ 模块化方案
无论是
RequireJS (AMD)
SeaJS (CMD)
KMD.js (KMD)
Browserify (CommonJS)
…
最后都庆幸回归到 npm + Webpack
什么?SystemJS?有完没完…
§ MV*框架 / 技术栈 / 大型框架
Backbone
每个人都有一段不堪回首的经历
就像当年在 QQ 空间发“你若安好便是晴天”的说说
Backbone就是这样子的存在
Angular
一定要边吐槽边用,不然就一点都不 ng 了
“学习曲线陡峭”不应从你口中说出
“学习过程趣味盎然”才是你的菜
Vue
一定要用“优雅”来形容
就像用 ES6 一定要“大胆”
React技术栈
React 已经是前端高逼格的代名词
所以无论懂不懂都要喊:
“React 大法好”
因为这是一种信仰
称赞 JSX 的标新立异
谈谈 Flux / Redux
扯扯 Elm / RxJS
每到深入则戛然而止:
“太深入的太抽象,你们未必能理解”
由此,听者只会更加崇拜你
其他
还有国内相对小众的 Ember / Knockout / Avalon
(请别再把 YUI / Dojo / Ext / KISSY 扯进来了好伐)
§ 混合 / 原生开发
自从 PhoneGap 出来后
貌似我们也能抢 安卓/iOS 的饭碗了
Ionic 更是将 Hybrid APP 推向高潮
不过混合始终比不上原生
于是 React Native 应运而生
最近多了一个新的选择:Weex
别忘了还有桌面的 nw.js 以及 Electron
JSer从一入门开始,就掌握了改变世界的能力
也比其他程序员更容易走向人生的巅峰
§ 后端框架
我们一直标榜自己是全栈
不玩几下后端框架怎么行
快递员用 Express
风湿患者用 Koa
哲学家用 ThinkJS
水手用 Sails
还有全栈的 Meteor
上述都用一遍
相信也快转行了
§ 服务器进程管理
既然都玩上了后端框架
不懂部署服务器怎么行
二逼青年用 supervisor / nodemon
文艺青年用 forever
普通青年用 pm2
装逼青年用 Tmux + node
jquery-ui-autocomplete+Bootstrap modal 层级问题
bootstrap3.x • lopo1983 发表了文章 • 0 个评论 • 2141 次浏览 • 2016-08-22 11:27
display:block;
z-index:99999;
}
.ui-autocomplete{
display:block;
z-index:99999;
}
bootstrap+swiper 全文图片预览
bootstrap3.x • lopo1983 发表了文章 • 0 个评论 • 1851 次浏览 • 2016-08-16 15:26
var $index = $(this).index();
var temp = '<div class="modal fade" id="modalSwiper" tabindex="-1"><div class="modal-dialog modal-full" role="document"><div class="modal-content"><div class="modal-body"><div class="swiper-container" id="modSwiper"><div class="swiper-wrapper"></div><div class="swiper-pagination"></div><div class="swiper-button-prev iconfont icon-left"></div><div class="swiper-button-next iconfont icon-right"></div></div></div></div></div></div>';
$('body').append(temp);
var tempslider = '';
$('#product-info .pro-img img').each(function() {
tempslider += '<div class="swiper-slide"><img src="' + $(this).attr('src') + '" class="img-responsive center-block" alt="" /></div>';
});
$('#modalSwiper').find('.swiper-wrapper').append(tempslider);
var modalSwiper = $('#modSwiper').swiper({
autoplay: 4000,
speed: 1500,
loop: true,
pagination: '.swiper-pagination',
lazyLoading: true,
paginationClickable: true,
runCallbacksOnInit: true,
prevButton: '.swiper-button-prev',
nextButton: '.swiper-button-next',
});
$('#modalSwiper').modal('show');
$('#modalSwiper').on('shown.bs.modal', function() {
var a = $('#modalSwiper .modal-full').height(),
b = $('#modalSwiper .modal').height();
if(a < b) {
$('#modalSwiper .modal-full').css('transform', 'translate(0,' + (b - a) / 2 + ')')
}
modalSwiper.update(true);
modalSwiper.slideTo($index + 1,500);
});
$('#modalSwiper').on('hidden.bs.modal', function() {
$('#modalSwiper').remove();
})
}) 查看全部
$('#product-info .pro-img img').click(function() {
var $index = $(this).index();
var temp = '<div class="modal fade" id="modalSwiper" tabindex="-1"><div class="modal-dialog modal-full" role="document"><div class="modal-content"><div class="modal-body"><div class="swiper-container" id="modSwiper"><div class="swiper-wrapper"></div><div class="swiper-pagination"></div><div class="swiper-button-prev iconfont icon-left"></div><div class="swiper-button-next iconfont icon-right"></div></div></div></div></div></div>';
$('body').append(temp);
var tempslider = '';
$('#product-info .pro-img img').each(function() {
tempslider += '<div class="swiper-slide"><img src="' + $(this).attr('src') + '" class="img-responsive center-block" alt="" /></div>';
});
$('#modalSwiper').find('.swiper-wrapper').append(tempslider);
var modalSwiper = $('#modSwiper').swiper({
autoplay: 4000,
speed: 1500,
loop: true,
pagination: '.swiper-pagination',
lazyLoading: true,
paginationClickable: true,
runCallbacksOnInit: true,
prevButton: '.swiper-button-prev',
nextButton: '.swiper-button-next',
});
$('#modalSwiper').modal('show');
$('#modalSwiper').on('shown.bs.modal', function() {
var a = $('#modalSwiper .modal-full').height(),
b = $('#modalSwiper .modal').height();
if(a < b) {
$('#modalSwiper .modal-full').css('transform', 'translate(0,' + (b - a) / 2 + ')')
}
modalSwiper.update(true);
modalSwiper.slideTo($index + 1,500);
});
$('#modalSwiper').on('hidden.bs.modal', function() {
$('#modalSwiper').remove();
})
})
群规2018
bootstrap3.x • lopo1983 发表了文章 • 0 个评论 • 3295 次浏览 • 2016-07-30 18:51
(为同城交流更为便捷,望大家自觉准守)。?
2.请尊重群内其他群员,上班期间尽量少聊与群主题无关的内容,恶意发大图刷屏(除了qq自带表情外其他的一律视为大图),上班时间请勿红包刷屏(禁令时间为: 周一 ~ 周五 8:30~12:00 13:00~17:30 ),发引导用户注册的AD链接直接飞机。
3.问问题前,请先baidu和查看api无果后再提问,问问题时 请尽量图文并茂,以节约时间!bootstrap相关的问题,请先申明版本号(呵呵!本群不再讨论兼容问题)。
4.若提问暂时没人回答,可到www.bsfans.com/wenda/ 留言或查看是否有和你一样的问题已被解答,不要随意@别人,你忙别人也忙!
5.群内禁止发黄赌毒 反党反社会的言论 图片
6.猎头、招聘请到www.bsfans.com/wenda/ 发布,若急需发布的可联系群主!?
以上规定违反者 送禁言套餐一份 若多次再犯送全球通单程机票一张!
? 查看全部
(为同城交流更为便捷,望大家自觉准守)。?
2.请尊重群内其他群员,上班期间尽量少聊与群主题无关的内容,恶意发大图刷屏(除了qq自带表情外其他的一律视为大图),上班时间请勿红包刷屏(禁令时间为: 周一 ~ 周五 8:30~12:00 13:00~17:30 ),发引导用户注册的AD链接直接飞机。
3.问问题前,请先baidu和查看api无果后再提问,问问题时 请尽量图文并茂,以节约时间!bootstrap相关的问题,请先申明版本号(呵呵!本群不再讨论兼容问题)。
4.若提问暂时没人回答,可到www.bsfans.com/wenda/ 留言或查看是否有和你一样的问题已被解答,不要随意@别人,你忙别人也忙!
5.群内禁止发黄赌毒 反党反社会的言论 图片
6.猎头、招聘请到www.bsfans.com/wenda/ 发布,若急需发布的可联系群主!?
以上规定违反者 送禁言套餐一份 若多次再犯送全球通单程机票一张!
?
Fixalert
bootstrap3.x • lopo1983 发表了文章 • 0 个评论 • 1731 次浏览 • 2016-07-28 15:25
position: fixed;
max-width: 480px;
min-width: 100px;
width: auto;
height: auto;
overflow: hidden;
.alert {
.unbdr;
.close {
margin-left: 15px;
}
}
&[data-pos="br"] {
right: 5px;
bottom: 0;
}
&[data-pos="tr"] {
right: 5px;
top: 100px;
}
a {
display: block;
cursor: pointer;
&:hover {
color: inherit;
}
}
}less?function fixAlert(a, b, c, d) {
//a 位置 0 右下 1 右上 | b 类型 0警告 1 错误 2正确 | c 内容 | d 如果有 者为url
$('.alertbox').remove();
var pos, type;
var temp = '';
var tempChild = '';
if (a == 0) {
pos = 'br';
} else {
pos = 'tr';
};
if (b == 0) {
type = "warning";
} else if (b == 1) {
type = "danger";
} else {
type = "success";
};
if (d == undefined) {
d = "javascript:;"
};
temp += '<div class="alertbox" data-pos="' + pos + '"></a>';
$('body').append(temp);
tempChild += '<a class="alert ' + type + '" href="' + d + '"><button type="button" class="close" data-dismiss="alert"><span>×</span></button>' + c + '</a>';
$('.alertbox').append(tempChild);
$('.alert').on('closed.bs.alert', function() {
$('.alertbox').remove();
});
};js
?
fixAlert(1,0,'警告的内容','http://www.baidu.com') 查看全部
.alertbox {less?
position: fixed;
max-width: 480px;
min-width: 100px;
width: auto;
height: auto;
overflow: hidden;
.alert {
.unbdr;
.close {
margin-left: 15px;
}
}
&[data-pos="br"] {
right: 5px;
bottom: 0;
}
&[data-pos="tr"] {
right: 5px;
top: 100px;
}
a {
display: block;
cursor: pointer;
&:hover {
color: inherit;
}
}
}
function fixAlert(a, b, c, d) {js
//a 位置 0 右下 1 右上 | b 类型 0警告 1 错误 2正确 | c 内容 | d 如果有 者为url
$('.alertbox').remove();
var pos, type;
var temp = '';
var tempChild = '';
if (a == 0) {
pos = 'br';
} else {
pos = 'tr';
};
if (b == 0) {
type = "warning";
} else if (b == 1) {
type = "danger";
} else {
type = "success";
};
if (d == undefined) {
d = "javascript:;"
};
temp += '<div class="alertbox" data-pos="' + pos + '"></a>';
$('body').append(temp);
tempChild += '<a class="alert ' + type + '" href="' + d + '"><button type="button" class="close" data-dismiss="alert"><span>×</span></button>' + c + '</a>';
$('.alertbox').append(tempChild);
$('.alert').on('closed.bs.alert', function() {
$('.alertbox').remove();
});
};
?
fixAlert(1,0,'警告的内容','http://www.baidu.com')