独书先生 Menu

Cropper.js 实现上传图片裁剪功能 | 支持移动端

分类:Web

需求分析:

实现上传图片文件,弹窗对图片进行自定义裁剪,裁剪完后能够保存裁剪完后新的图片,以发送到服务器。具体场景比如换头像功能,裁剪成正方形或圆形,上传一张新的产品图裁剪成长方形等。

实现思路:

点击input [file]上传图片,监听这个input的 change事件,实例化FileReader读取图片的src地址传给cropper.js裁剪框插件,插件内自动实现裁剪功能,后使用cropper.js的getCroppedCanvas方法得到裁剪后的图片url,传给服务器存储,再显示到前台。 Continue reading…

HTML通用组件模板:获取验证码60s倒计时后重新获取

分类:Web

需求:常见的用于登陆验证中,输入电话号码后点击“获取验证码”,开始60s倒计时,这段时间内获取验证码按钮无法点击,60s倒计时结束后,方可“重新获取”。

verify_code

解析:使用setTime定时器,每秒刷新一次。 Continue reading…

HTML通用组件模板:点击上传图片HTML组件 | CSS

分类:Web

目的:记录下自己平时编写的HTML组件,抽离常用的HTML元素组合,添加基础CSS样式,之后的项目稍作修改即可实现复用,提高工作效率。

解析:点击上传图像框,实际点击隐藏的input,上传完成后,图片显示在原处的img标签内。
upload_pic

Continue reading…

HTML倒计时效果:天、时、分、秒 | 固定时间倒计时

需求分析:

希望制作一个固定时间倒计时效果,比如某某活动在4小时之后结束,点开网页,触发倒计时事件,开始4小时倒计时。考虑使用setInterval定时器,在时间为0后,clearInterval清除定时器。

代码实例:

写一个span用于显示,记得引用jQuery Continue reading…

CSS:progress 样式,自定义animation进度条案列

需求分析:

等待加载网页,上传文件均需要进度条,初步选用HTML5 自带progress标签+JS定时器实现一个固定时间加载完成的进度条。

1.先看下原始进度条:

HTML:

<progress  id="load" ></progress>

未加任何样式,进度条在左右跳动,可用作持续加载文件或网页。

2.设置加载完成(0~100)进度条到头后即停止的效果,需写JS

HTML:

<progress max="100" value="0" id="load" ></progress>

CSS:

progress{
background:green;
border:1px solid #000;
appearance: none;/*设置iOS下清除灰色背景*/
-webkit-appearance: none;
}

/*设置进度条颜色*/
::-ms-fill{
background:red;
}
::-moz-progress-bar{
background:red;
}
::-webkit-progress-value{
background:red;
}

/*设置进度条背景颜色*/
::-webkit-progress-bar{
background:green;
}

JS:

/*定时器,value到达100即停止*/
var pg = document.getElementById("load");
var setpg = setInterval(function(e){
if(pg.value != 100){
pg.value++;
}else{
clearInterval(setpg);
}
},80);

 

PS :这里不能设置border-radius圆角效果,不需要圆角样式的,可以修改颜色匹配项目即可。

需要圆角样式的,往下看看自定义progress

3.使用animation动画自定义progress,纯CSS

解析:使用两层DIV嵌套,外层可设置边框、背景,内层设置进度条的渐变、动画。

不熟悉动画的同学先移步 CSS:animation 简单动画效果

效果:

HTML :

<div id="out-progress">

<div id=in-progress></div>

  </div>

 

CSS:

#out-progress{
width:100%;
border:1px solid #ccc;
border-radius:10px;
background:#EEE8AA;
height:20px;
padding:1px;
}
#in-progress{
width:100%;
height:100%;
border-radius:10px;
background:-webkit-linear-gradient(left,#FFEFDB,#FF8247);
-webkit-animation:loadpg 5s 1s linear infinite;/*实际应用中infinite改为1即可实现一次性加载到头后停止*/
}
@keyframes loadpg{
0%{
width:0%;
}
100%{
width:100%;
}
}

 

CSS: 自定义reset.css 适配移动端

最近在做移动端的Web app项目,在正式写CSS之前,要做一个CSS重置,即初始化各类基本样式。大部分样式是可以通用的,或者说,我们可以写一套reset.css样式,应用于多个项目。本代码是结合网络上资料,以及自己的业务需求来定制,大家可自行参照修改使用。

@charset "utf-8";

*{
-webkit-box-sizing:border-box;
-moz-box-sizing: border-box;
box-sizing:border-box;
}
/*禁止文字缩放 字体设置 取消touch高亮效果*/
html{
min-width:340px;
max-width:640px;
margin:0 auto;
-webkit-text-size-adjust:100%; /*关闭横屏时字体大小自动调整功能.*/
background:transparent;

font-family:"Microsoft Yahei",Arial,Helvetica,sans-serif;
/*方案二:-apple-system,BlinkMacSystemFont,"PingFang SC","Helvetica Neue",Helvetica,STHeiti,"Microsodt Yahei",Tahoma,Simsun,sans-serif;*/
-webkit-tap-highlight-color:rgba(0,0,0,0);
font-size:62.5%; /*之后设置字体大小rem*/
}
body{
width:100%;
height:100%;

background-color:#fff;
color:#333;
-webkit-overflow-scrolling:touch; /*快速滚动和回弹的效果*/
}
article,aside,dialog,footer,header,section,footer,nav,figure,a{
display:block;
}
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,figure,section,legend,textarea,p,blockquote,th,td,input,select,textarea,button{
margin:0;padding:0;
}
fieldset, img ,button{ border: none;outline:none; }
table{border-collapse:collapse;border-spacing:0;} /*去除单元格之间的距离*/

h1,h2,h3,h4,h5,h6{
font-size:1.4rem;font-weight:normal;
}
/*清除输入框内阴影*/
input,select,textarea{
border:none;
-webkit-appearance:none; /*去除系统默认appearance的样式,常用于IOS下移除原生样式*/
appearance:none;
}

/*chrome表单自动填充去掉input黄色背景*/
input:-webkit-autofill,textarea:-webkit-autofill,select:-webkit-autofill{
-webkit-box-shadow:0 0 0px 1000px white inset;
}

ul,ol,dd,dt,dl{
list-style-type:none;
}

i,em{font-style:normal;}

a{display:block;color:#333;font-size:1.3rem;-webkit-user-select:none;}
a:focus{
outline:none;
}

/*禁止长按页面弹出菜单(iOS)*/
img,a{
-webkit-touch-callout:none;
}

a,a:active,a:hover{
text-decoration:none;
}

/*去掉点击链接和文本框对象时默认的灰色半透明覆盖层(iOS)或者虚框(Android)*/
a,button,input,textarea,select{
-webkit-tap-highlight-color:transparent;
-webkit-border-radius:0;
}

/*iphone6*/
@media(min-device-width:375px)and(max-device-width:667px)and(-webkit-min-device-pixel-ratio:2){html{font-size:10px;}}

/*iponhe6 plus*/
@media(min-device-width:414px)and(max-device-width:736px)and(-webkit-min-device-pixel-ratio:3){html{font-size:12px;}}

/*原子类*/
.clear{clear:both;}
.clear:after{display: block;clear:both;visibility:hidden;height:0;width:0;overflow:hidden;content:"";}
.db{display: block;}
.dn{display: none;}
.fl{float:left;}
.fr{float:right;}
.mt10{margin-top:10px;}
.mb10{margin-bottom:10px;}
.wh1{width:100%;height:100%;}
.tl{text-align:left;}
.tr{text-align:right;}
.tc{text-align:center;}

Node.js学习笔记(4)–Nodejs核心库之Buffer/FileSystem/Stream/Path简单示例总结

1.Buffer(缓冲区)

//Buffer简单示例
//1.创建指定容量的buffer
var buf1 = new Buffer(10);
console.log(buf1);  //Result: &amp;amp;lt;Buffer 88 41 66 ed a0 02 00 00 00 00&amp;amp;gt;

//2.根据数组创建buffer
var buf2 = new Buffer([1,2,3,4,5]);
console.log(buf2);  //Result: &amp;amp;lt;Buffer 01 02 03 04 05&amp;amp;gt;

//3.根据字符串创建buffer
var buf3 = new Buffer('string','utf8');
console.log(buf3); //Result:&amp;amp;lt;Buffer 73 74 72 69 6e 67&amp;amp;gt;
buf3 = new Buffer('string','hex'); //16进制
console.log(buf3); //Result:&amp;amp;lt;Buffer &amp;amp;gt;
//Node.js buffer支持的编码utf8/ascii/utf16le/ucs2/base64/binary/hex

//判断编码是否被支持
console.log(Buffer.isEncoding('ascii')); //Result: true

//判断对象是否是buffer的示例
console.log(Buffer.isBuffer(buf3)); //Resule: true

//获取buffer的字节长度,与编码有关
console.log(Buffer.byteLength('string','hex')); //Resule:3

//连接bufffer,可选参数为最大长度
console.log(Buffer.concat([buf1,buf2,buf3])); //Result:&amp;amp;lt;Buffer f0 a4 99 15 75 01 00 00 d0 a6 01 02 03 04 05&amp;amp;gt;

//将字符串写入buffer
buf1.write('string',0,6,'utf8');
console.log(buf1); //Result:&amp;amp;lt;Buffer 73 74 72 69 6e 67 01 00 00 00&amp;amp;gt;

//将buffer打印出来
console.log(buf1.toString('utf8',0,6)); //Result: string

//将buffer转换为json对象
console.log(buf1.toJSON()); //Result: { type: 'Buffer',
                            //data: [ 115, 116, 114, 105, 110, 103, 0, 0, 0, 0 ] }

//buffer复制
var buf4 = new Buffer(10);
var buf5 = new Buffer('string','utf8');
//将buf5中的第1位开始,第3位结束的内容复制到buf4上的第2位开始的位置
buf5.copy(buf4,2,1,3); //2是buf4的起点,1/3是buf5的起始点/结束点
console.log(buf4.toString('utf8',2,4)); //Result:tr

2.FileSystem(文件系统) / Stream(流) /Path(路径处理)

1)FileSystem 与Stream

var fs = require('fs');
var newFile = './核心库/tpl1.txt';

//追加指定内容到文件
fs.appendFile(newFile,'No.2 New Content','utf8',function (err) {
    if(err){
        console.log(err);
    }
});

//打开文件和关闭文件
fs.open(newFile,'w',0666,function (err,fd) { //打开文件时找出fd,后续用于关闭
   if(err){
       throw err;
   }
   //关闭文件时,第一个参数是文件句柄
    fs.close(fd,function (err) {
        if(err){
            console.log(err);
        }
    })
});

//Stream(流) :创建可读可写流
var rStream = fs.createReadStream(newFile,{bufferSize:200});
var wStream = fs.createWriteStream(newFile,{bufferSize:200});

//判断文件是否存在
//同步方法
console.log(fs.existsSync(newFile)); //Result:true
//异步方法
fs.exists(newFile,function (result) {
   console.log(result);  //Result:true
});

//复制文件,
fs.link(newFile,'./核心库/tpl2.txt',function (err) {
    if(err){console.log(err);}
});

//删除文件
fs.unlink('./核心库/tpl2.txt');

//创建文件夹
fs.mkdir('./核心库/mk',function (err) {
    if(err){
        console.log(err);
    }
});
fs.rmdir('./核心库/mk');

2)FileSystem与Path

var fs = require('fs');
var path = require('path');

//递归遍历文件夹下所有文件
function consoleFiles(dir) {
    var files = fs.readdirSync(dir); //只能读取下一级的所有文件或文件夹名
    files.forEach(function (name) {
        var pathName = path.join(dir,name); // 成为一个完整的目录
        if(fs.statSync(pathName).isDirectory()){
            consoleFiles(pathName); //遇到文件夹使用递归继续往下获取一级,直至获取到文件名
        }else{
            console.log(pathName); //遇到文件名即可输出
        }
    });
}
consoleFiles('./核心库');

3)Path

var path = require('path');
var p = 'https://dushusir.com/abc/cde.html';

//路径标准化
var p1 = path.normalize(p);
console.log(p1);  //Result: https:\www.dushusir.com\abc\cde.html
//组合多个路径
console.log(path.join('https://dushusir.com/','abc','../abc')); //Result:http:\dushusir.com\abc

//将相对路径换成绝对路径
console.log(path.resolve('./')); //Result: 向上一层 D:\Code\前端开发技术\Node.js\NodeTest
console.log(path.resolve('../')); //Result: 向上两层 D:\Code\前端开发技术\Node.js

//输出路径的直接上级
console.log(path.dirname(p)); //Result: https://dushusir.com/abc
//输出路径的最后一部分
console.log(path.basename(p)); //Result: cde.html

//输出扩展名,以最后一个点开始
console.log(path.extname(p)); // Result: .html
//常量
console.log(path.sep); //Result: \
console.log(path.delimiter); //Result: ;

Node.js学习笔记(3)–Nodejs核心库之timers/util/events简单示例总结

1.Node.js核心库之timers

方法 描述
setTimeout 间隔一定时间后执行方法,执行一次
clearTimeout 清除定时器
setInterval 间隔一定时间执行方法,执行执行
clearInterval 清除定时器
setImmediate 类似setTimeout,将代码加入下一个事件循环
clearImmediate 清除setImmediate。

 

JS:

//setTimeout 和 clearTimeout
var i=0;
function print() {
    console.log(i++);
    timeOut = setTimeout(print,1000);
    if(i&gt;10){
        clearTimeout(timeOut);
    }
}

//第二个参数是间隔时间,单位是毫秒
console.time('l1');
var timeOut = setTimeout(print,1000);
console.timeEnd('l1');

Continue reading…