我有,我没有
你有没有过,从某个商铺的橱窗
偶然瞟见一样东西
立刻就对它一见倾心
等你鼓足了勇气买下了它
就更加爱不释手
你会越来越发现
我买对了,而且每天都倍加珍惜
你有没有过,在某个转角
遇到一个人
立刻就想去了解关于她的一切
原来她在趁你不注意的时候也在偷偷地看你
直到一天,你们相视一笑
从此相依相伴,而且
你会越来越发现,
我遇到了对的人,而且越来越依赖
可是等哪天它不在
或她不再
就像如梦初醒
我有,我没有
你有没有过,从某个商铺的橱窗
偶然瞟见一样东西
立刻就对它一见倾心
等你鼓足了勇气买下了它
就更加爱不释手
你会越来越发现
我买对了,而且每天都倍加珍惜
你有没有过,在某个转角
遇到一个人
立刻就想去了解关于她的一切
原来她在趁你不注意的时候也在偷偷地看你
直到一天,你们相视一笑
从此相依相伴,而且
你会越来越发现,
我遇到了对的人,而且越来越依赖
可是等哪天它不在
或她不再
就像如梦初醒
我有,我没有
input框输入的时候如果需要异步请求资源做autosuggest功能或者其他情况的话就需要绑定keyup/keydown/keypress事件,在键入的过程中根据用户输入的内容通过异步接口获取对应suggest信息,例如:
<input type="text" id="inputTimerTest" placeholder="inputTimer测试">
<script>
(function($){
$('inputTimerTest').on('keyup',function(){
$.get('/path',function(){
//do something here
})
})
})(jQuery)
</script>
但是如果用户量过大,或者键入信息过多由于各种情况(尤其是中文输入法),只要触发一次keyup/keydown/keypress事件就会发送一次请求。对服务器的压力是相当大的,对正在快速键入的用户来说也没有任何体验上的好处。
如何在一定的键入时间内,如果用户正在连续接入就不用再去发送请求,对比了几个实现方案,发现一个简单的思路: 在一连串的键入事件中,只要取消上一次的键入延时程序即可 ,根据这个思路对上面的代码做一下改动:
<input type="text" id="inputTimerTest" placeholder="inputTimer测试">
<script>
(function($){
var timer,
delayTime = 300;//可感知的延时,300ms以下最合适
$('inputTimerTest').on('keyup',function(){
clearTimeout(timer);//取消上一次的操作延时
timer = setTimeout(function(){//定义本次键入操作的延时
$.get('/path',function(){
//do something here
})
},delayTime)
})
})(jQuery)
</script>
这样只需要去操作延时程序即可实现,思路很简单,实现代码也很容易;唯一的缺憾是产生了一个timer的变量在绑定方法的作用域外,但无关紧要。
这里是DEMO/demo/inputTimer.html
JS编码中有一个方法的形参需要判断类型:
var test = function(ele){
if((typeof ele).toLowerCase() == 'string' || ele==''){
//do something here
}else{
}
}
正常情况下在传递一个element作为形参去执行这个方法程序应该走到else的分支中去;但是断点发现,一个的节点作为形参却走到了if中的代码,断电发现:
ele==''
竟然为true , console打出来的参数确实是一个element,typeof出来也是object。经大神提示:
var a = document.createElement('div');
a.toString = function(){
return 'test'
};
a=='test'//true
但是,这个并没有重写toString方法。为何会toString会返回””呢。
var b = document.createElement('a');
b.href='http://www.baidu.com';
b.toString() == 'http://www.baidu.com/';//true
这下全都明白了。
工作需要,要写一个简单的文件异步上传功能,首先想到的是jquery的ajaxUpload组件,但是公司用的是tangram,为了这样的一个功能再去引一个jquery实在太亏了;问了一圈同事好像都没有提供这个功能的“库存”,只好自己写了。
查了一些资料,实现单文件异步提交还是很简单的。大致思路是 生成一个form表单,target到iframe中去,由后端进行处理,然后再把上传结果信息以html 里的JS全局变量形式返回到iframe,外层实时监听iframe里的JS全局变量即可 。(看起来像是发起跨域异步请求的方法,但事实上这是不支持跨域的)
还有一点需要注意的是, 如果需要修改提交表单的样式,最佳方案是隐藏当前表单 (这里是指:opacity: 0;或 filter:progid:DXImageTransform.Microsoft.Alpha(opacity:0);),然后在下面加上按钮背景。
JS代码如下:
(function($, ns){
"use strict";
function ajaxUpload(cfg){
this.name = cfg.name || "";
this.rendId = cfg.rendId;
this.actionUrl = cfg.actionUrl || '/sec/forgot/appeal/upload';
this.method = cfg.method || "post";
this.data = cfg.data;
this.status = '0';//初始状态
this.onSuccess = cfg.onSuccess || function(){};
this.onSending = cfg.onSending || function(){};
this.onFailure = cfg.onFailure || function(){};
var _init = function(me){
me.init();
}
_init(this);
}
ajaxUpload.prototype.init = function(){
this.render();
}
ajaxUpload.prototype.hiddenTpl = function(){
var hiddenTpl = '';
for(var item in this.data){
hiddenTpl = hiddenTpl + '<input type="hidden" name="'+item+'" value="'+this.data[item]+'">'
}
return hiddenTpl;
}
ajaxUpload.prototype.getTpl = function(){
return {
wrapper:'<div class="ajaxUpload">',
buttonEle:'<div class="ajaxUpload-show clearfix" ><button class="ajaxUpload-button">选择文件</button><span class="ajaxUpload-info"></span></div>',
form:''+
'<form class="ajaxupload-form" enctype="multipart/form-data" target="ajaxUploadIframe" action="'+this.actionUrl+'" method="'+this.method+'">'+
'<input type="file" name="'+this.name+'" class="ajaxupload-form-file"/>'+
'<input type="hidden" name="picid" class="ajaxupload-form-picid" value="">'+
this.hiddenTpl()+
'</form>',
iframe:''+
'<iframe class="ajaxupload-iframe" name="ajaxUploadIframe" style="display:none"></iframe>'
}
}
ajaxUpload.prototype.render = function(){
var tpl = this.getTpl(),
ele = {},
me = this;
ele.wrapper = $(tpl.wrapper);
ele.formEle = $(tpl.form);
ele.buttonEle = $(tpl.buttonEle);
ele.iframeEle = $(tpl.iframe);
$('#'+this.rendId).append(ele.wrapper);
$(ele.wrapper).append(ele.buttonEle);
$(ele.wrapper).append(ele.formEle);
$(document.body).append(ele.iframeEle);
ele.fileEle = $('.ajaxUpload .ajaxupload-form-file');
ele.picidEle = $('.ajaxUpload .ajaxupload-form-picid');
ele.msgEle = $('.ajaxUpload .ajaxUpload-info');
this.ele = ele;
$(ele.buttonEle).on('click',function(){
ele.fileEle.trigger('click');
})
$(ele.fileEle).on('change',function(event){
var filesData = {};
if(event.target.files && event.target.files[0]){
filesData.type = event.target.files[0].type;
filesData.name = event.target.files[0].name;
filesData.size = event.target.files[0].size;
}else if(event.target && event.target.value){
filesData.type = 'image/' + event.target.value.substr(event.target.value.lastIndexOf('.')+1);
filesData.name = event.target.value.substr(event.target.value.lastIndexOf('\\')+1);
filesData.size;
}
me.changeFile(filesData,me.renderResult)
})
};
ajaxUpload.prototype.renderResult =function(result,me){
if(result.errno == '110000'){
me.status = '6';//上传成功
me.ele.picidEle.val(result.picid);
me.onSuccess(result,me);
me.changeMsgView('done');
}else{
me.onFailure(result,me);
me.changeMsgView('fail');
me.status = '5';//上传失败
me.ele.msgEle.html(result.msg)
}
};
ajaxUpload.prototype.changeMsgView = function(type){
if(type == 'sending'){
this.ele.msgEle.addClass('sending');
this.ele.msgEle.removeClass('done');
this.ele.msgEle.removeClass('fail');
}else if(type == 'done'){
this.ele.msgEle.addClass('done');
this.ele.msgEle.removeClass('sending');
this.ele.msgEle.removeClass('fail');
}else if(type == 'fail'){
this.ele.msgEle.addClass('fail');
this.ele.msgEle.removeClass('sending');
this.ele.msgEle.removeClass('done');
}
}
ajaxUpload.prototype.changeFile =function(files,callback){
var type = files.type.toLowerCase(),
size = files.size || '',
name = files.name || '',
allowType = 'image/png'+','+'image/jpg'+','+'image/bmp'+','+'image/jpeg'+','+'image/gif',
err = {
errno:'',
msg:''
},
interval,
result = '',
me = this;
this.status = '1';
me.changeMsgView('sending');
me.ele.msgEle.html(name);
if(allowType.indexOf(type) == -1){
err.msg = '文件格式错误'
return callback(err,me);
}else if(size && size>1024000){
err.msg = '您上传的图片过大,请上传小于1M的图片吧'
return callback(err,me);
}else{
$(this.ele.formEle).submit();
var times = 0;
this.onSending && this.onSending(me);
interval = setInterval(function(){
if(times<90){
result = window.frames ? window.frames['ajaxUploadIframe'].ajaxUpload : me.ele.iframeEle[0].contentDocument ? me.ele.iframeEle[0].contentDocument.ajaxUpload: me.ele.iframeEle[0].contentWindow ? me.ele.iframeEle[0].contentWindow.ajaxUpload:'';
if(result){
clearInterval(interval);
err.msg = result.msg;
err.errno = result.errno;
err.picid = result.picid;
err.name = name;
me.status = '4';//上传有结果
return callback(err,me);
}
times++
me.status = '3';//上传中
}else{
me.ele.msgEle.removeClass('sending');
me.ele.msgEle.removeClass('done');
me.status = '2';//上传超时
clearInterval(interval)
err.msg = '上传超时,请稍后再试!';
return callback(err,me);
}
},1000)
}
};
ns.define('module/ajaxUpload', ajaxUpload);
})(baidu, window.Pass);
返回上传信息的HTML代码如下:
<!doctype html>
<html>
<head>
<meta charset='utf-8'/>
<script type="text/javascript" charset="UTF-8" >
var ajaxUpload = {
"errno":'',
"msg":'',
"picid":''
}
</script>
</head>
<body>
</body>
</html>
http://www.w3.org/TR/html5/single-page.html
http://www.w3.org/TR/html51/single-page.html
http://www.w3.org/TR/css-style-attr/
http://www.w3.org/TR/html-templates/
http://www.w3.org/TR/SVG/single-page.html
http://www.w3.org/TR/eventsource/
http://www.w3.org/TR/websockets/
http://www.w3.org/TR/webmessaging/
http://www.w3.org/TR/cssom-view/
http://www.w3.org/TR/XMLHttpRequest2/
http://www.w3.org/TR/XMLHttpRequest/
http://www.w3.org/TR/ElementTraversal/
http://www.w3.org/TR/2dcontext2/
http://www.w3.org/TR/2dcontext/
http://www.w3.org/TR/webstorage/
http://www.w3.org/TR/webaudio/
http://www.w3.org/TR/IndexedDB/
http://www.w3.org/TR/clipboard-apis/
http://www.w3.org/TR/resource-timing/
http://www.w3.org/TR/notifications/
http://www.w3.org/TR/selectors-api/
http://www.w3.org/TR/selectors-api2/
http://www.w3.org/TR/file-system-api/
http://www.w3.org/TR/file-writer-api/
http://www.w3.org/TR/web-animations/
http://www.w3.org/TR/selectors/
http://www.w3.org/TR/selectors4/
http://www.w3.org/TR/css3-mediaqueries/
http://www.w3.org/TR/css3-cascade
http://www.w3.org/TR/css3-syntax
http://www.w3.org/TR/css3-animations
http://www.w3.org/TR/css-device-adapt/
http://www.w3.org/TR/css3-namespace/
http://www.w3.org/TR/css3-color
http://www.w3.org/TR/css3-values
http://www.w3.org/TR/css3-conditional
http://www.w3.org/TR/css3-flexbox
http://www.w3.org/TR/css3-background
http://www.w3.org/TR/css3-images
http://www.w3.org/TR/css4-images/
http://www.w3.org/TR/css3-speech
http://www.w3.org/TR/css3-multicol
http://www.w3.org/TR/css3-marquee
http://www.w3.org/TR/css-text-decor-3/
http://www.w3.org/TR/compositing-1/
http://www.w3.org/TR/css-masking/
http://www.w3.org/TR/css3-exclusions
http://www.w3.org/TR/css3-regions
http://www.w3.org/TR/filter-effects/
http://www.w3.org/TR/css3-align
http://www.w3.org/TR/css-overflow-3/
http://www.w3.org/TR/css3-grid-layout
http://www.w3.org/TR/css3-page
http://www.w3.org/TR/css-counter-styles-3/
http://www.w3.org/TR/css3-fonts
http://www.w3.org/TR/css3-transitions
http://www.w3.org/TR/css3-writing-modes
http://www.w3.org/TR/css3-text
http://www.w3.org/TR/css3-sizing
http://www.w3.org/TR/css3-transforms
http://www.w3.org/TR/css3-break
http://www.w3.org/TR/css3-positioning
http://www.w3.org/TR/css3-2d-transforms
http://www.w3.org/TR/css3-layout
http://www.w3.org/TR/css3-gcpm
http://www.w3.org/TR/css3-ruby
http://www.w3.org/TR/css3-lists
http://www.w3.org/TR/css3-3d-transforms
http://www.w3.org/TR/css3-grid
http://www.w3.org/TR/css3-hyperlinks
http://www.w3.org/TR/css3-reader
http://www.w3.org/TR/css3-preslev
http://www.w3.org/TR/css3-content
http://www.w3.org/TR/css3-border
http://www.w3.org/TR/css3-linebox
http://www.w3.org/TR/css3-webfonts
http://www.w3.org/TR/css3-roadmap