`
zccst
  • 浏览: 3320085 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

2014年7-12月 犯的几个小错误

阅读更多
作者:zccst

这些错误不大,却很耽误时间。有时一个很小的问题,耽误1-2天都很正常。

把这些列出来,可以发现自己的缺点到底在什么地方:

2014-12-21
15,backbone的router和history
(1)router


(2)history



2014-12-19

14,上传文件控件一大堆问题
解决了两个bug
(1)防重复提交
解决方法一:url+参数逐个比较全部相同时不能提交两次;
//避免重复提交		
var task = {
    caller: curOptions.caller,
    methond: curOptions.type,
    url: curOptions.url,
    args: curOptions.data
};
if (this._isDuplicateRquest(task)) {return;}

// 当做完防止重复提交校验之后,为url价格参数t
if (curOptions.url.indexOf('?') > 0) {
    curOptions.url += "&t=" + (new Date()).getTime();
} else {
    curOptions.url += "?t=" + (new Date()).getTime();
}
//ajax请求成功返回事件处理
curOptions.success = function (response, statusText, xhr) {
    _this._removeTask(task);
    if ( typeOf(customSuccess) === 'function' ) {
        if ( response.flag === '0' || response.flag === 0 ) {
            customSuccess(response.data, response, xhr);
            return;					
        } else {
            if ( typeOf(customFail) === 'function' ) {
                customFail(response.msg, response, xhr);				
            } else {
                alert((response.msg && response.msg.join('\r\n')) || '系统繁忙,请稍后再试');	
            }
        }
    } else {
        _this._defaultSuccess(response, statusText, xhr, curOptions);
    }
};

//ajax请求发生错误事件处理
curOptions.error = function (xhr, statusText, errorThrown) {	
    _this._removeTask(task);
    _this._defaultError(xhr, statusText, errorThrown, curOptions);
};

Ajax.prototype._isDuplicateRquest = function (task) {
    for (var i = 0, len = this.taskQueue.length; i < len; i++) {
        var t = this.taskQueue[i];
        if (task.caller === t.caller
            && task.url === t.url
            && task.methond === t.methond
            && $.param(task.args) === $.param(t.args)) {
            return true;
        }
    };
    this.taskQueue.push(task);
    return false;
};

Ajax.prototype._removeTask = function (task) { 
    for (var i = 0, len = this.taskQueue.length; i < len; i++) {
        var t = this.taskQueue[i];
        if (task.caller === t.caller 
            && task.url === t.url 
            && task.methond === t.methond 
            && $.param(task.args) === $.param(t.args)) {
            this.taskQueue.splice(i, 1);
            break;
        }
    };
};


方法二:disabled按钮
用户提交后,disabled按钮,直到后端返回再enable,当然,后端只要返回就行。不论是成功还是失败。

(2)创建excel类型的feed,在IE下捕捉后端返回的异常
try {
    // IE浏览器走这个逻辑
    if ($.type(response) === "string") { 
        res = $.parseJSON(response);
    } //FF,Chrome走这个逻辑
    else if ($.type(response) === "object") {
        res = response;
    } //奇怪的第三种情况
    else {
        res = $.parseJSON($(response).text());
    }
} catch ( e ){
    //创建失败
    res = {
        'flag' : 1
    };
}



引用
历数uploader.js里出过的异常

(1)后端返回必须是content-type:text/html
(2)前端需要防止除file字段之外的其他字段多次重复添加。
(3)前端需要防止file字段提交一次后清空文件字段(isFileInputRefresh:false)
(4)防止用户多次提交,参加多条记录。防重复提交 或 disabled按钮。
(5)防止IE浏览器下报错。try catch

引用
历数双日历控件出过的异常

(1)span标签配对
(2)日历控件能够选择的时间范围是当天之后的。原因是:对当天以后的要加提示。修改控件,因为控件默认的是只能选择昨天的日期。
(3)控件没问题后,选择当前的提示语不对
(4)修改日历控件的默认选择,由昨天改为最近七天。





2014-12-10
转义字符又栽了一次。productDetail的key中带特殊字符,从页面获取值时应先unescapleHTML

正则表达式匹配qq号:
1,必须是数字,且是整数,且不能是负数
2,不能全0
3,不能以0开头,如果以0开头,需要去掉前面的0

uploader.js又有新问题:
就是重复提交的问题。
(1)File字段,增加一个参数isFileInputRefresh
true,提交完立即清空,避免重复提交
false,提交完不清空,需要重复提交
(2)其他字段,如name,indexType等也需要先判断是否已存在
已存在,更新值
不存在,添加


2014-12-04
13,转义字符

HTML的&lt; &gt;&amp;&quot;&copy;分别是<,>,&,",©;的转义字符
XML只有5个转义符: &lt; &gt;&amp; &quot; &apos;
例如:;;@@。::!!、?'‘’“”"=【】<><>《》~~•,
如果不转义,则会出现a标签出错。
详情参考:http://zccst.iteye.com/blog/2157743


2014-12-01
12, <meta http-equiv="X-UA-Compatible" content="IE=Edge">
解决了兼容性视图的问题

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
IE=edge告诉IE使用最新的引擎渲染网页,chrome=1则可以激活Chrome Frame

11,创建时多次订阅的问题
feed和product来回切换过程中,原有的feedMain没有destroy,导致多次初始化。
Router 里  判断feedMain 里面没有多次new
feedMain里  判断feedListManage,里面多次new(问题根源)
feedListManage里  初始化initialize时订阅

    //监听事件
this.subs = [];
this.subs.push(PubSub.subscribe(TOPIC.FEED.FEEDTEMPLATE.CREATE, $.proxy(function(){
this.queryTable();
}, this)));
this.subs.push(PubSub.subscribe(TOPIC.FEED.FEEDTEMPLATE.MODIFY, $.proxy(function(){
this.queryTable();
}, this)));
this.subs.push(PubSub.subscribe(TOPIC.FEED.FEEDTEMPLATE.DELETE, $.proxy(function(){
this.queryTable();
}, this)));

    //取消订阅
    if(this.subs.length > 0){
for(var i = 0; i < this.subs.length; i++){
    PubSub.unsubscribe(this.subs[i]);
    }
    }

2014-11-20
10,jQuery动态添加select的option在IE9下异常
错误的添加方式:(因为不兼容所有浏览器)
this.$el.find("select[name='updateFrequency']").append("<option value='3'>每隔数小时</option>"));
正确的添加方式:(因为兼容所以浏览器)
this.$el.find("select[name='updateFrequency']")[0].options.add(new Option("每隔数小时","3"));


9,IE浏览器封闭标签
双日历控件报错,IE7下浏览器左下角有两个字“取消”。
通过关键词搜索,发现是标签封闭错误。


8,content-type在IE浏览器中的错误解析
在上传文件组件中,后端返回content-type:text/javascript,在IE浏览器中会下载文件。文件的名字是actionName.js,内容是{"flag":0,"msg":"","data":[]};

如何解决?
通过设置content-type:text/html解决

原因:
在IE情况下,是表单提交,这时候需要设置表单的target为一个iframe,服务器端返回的数据将会回填到iframe中。在iframe中监听load事件,取iframe的内容,并解析。
此时如果iframe离的内容是html时,就当字符串处理了,所以可以成功解析。如果是text/javascript,IE会当成一段脚本,直接下载了。


7,在Backbone框架的项目中,创建的dialog到底要显示在哪里?
两种方式:
第一种是在调用的页面里写一个div作为父容器元素。也即是可以嵌套。
在new CrownCommonKeyPreview时传入el
var preview = new CrownCommonKeyPreview({
	el     : this.$el.find('div[name="crownCommonKeyPreview"]'),
	device : data.device,
	list   : data.crownCommonKeyRowList
});

CrownCommonKeyPreview收到options后,将el直接传给自己的view了。此时view的el就是传来的父容器。
var PreviewView = Backbone.View.extend({
        events: {
        	'click .new_bt a' : 'demoClick',
        },
        initialize: function(options){
            this.model.bind('change:list', this.renderPreviewView, this);
            this.renderPreviewView();
        },
...
});

el根本没有知名,但由于之前通过options传过来,所以是指定的父元素。


第二种是给 el 一个$("<div></div>")作为父容器,情况又分两种
(1)将this.view.$el.jdialog();作为一个弹窗
上代码:
/**
	 * Class DeadLink
	 */
    var DeadLink = function(options){
        this.options= options || {};
        this.model = new Model(this.options.modelOptions || {}),
        this.view  = new View($.extend(true, {model: this.model}, this.options.viewOptions||{}));
    }

    DeadLink.prototype.showInDialog = function(){
        this.dialog = this.view.$el.jdialog({
            title: this.options.dialogTitle == undefined ? '死链URL优化':this.options.dialogTitle,
            width : '820px',
            destroyOnClose : true,
            destroyContent: true,
            buttons: {
            }
        });
    }

    DeadLink.prototype.destroy = function(){
        if(this.view && this.view.destroy && typeof this.view.destroy == 'function'){
            this.view.destroy();
        }
    }

再来看view
var View = Backbone.View.extend({
	        el: '<div></div>',
	        events: {
	            //'click a[name="tab"]': 'changeContent',
	            'click a[name="batchReCheck"]'    : 'batchReCheck',
	            'click a[name="batchModifyUrl"]'  : 'batchModifyUrl',
	            'click a[name="downloadMaterial"]': 'downloadMaterial',
	            'click a[name="downloadUrl"]'     : 'downloadUrl',
	            'click th input'                  : 'selectAll',
	            'click td input'                  : 'selectOne'
	        },
	        initialize: function(){
	            //画上方黄色提示话术
	            this.model.bind('change:deadLinkCount', this.renderCount, this);
	            this.render();
	        },
});


(2)将el直接append到body里




/*------------------华丽的分割线表明好久没有更新了---------------*/


6,keydown, keyup区别(onpropertychange)
keydown  没有实时将输入的内容,放到输入框。
keypress 没有实时将输入的内容,放到输入框。
keyup    将输入的内容实时放到输入框。

原因:
触发顺序: keydown  -->  keypress -->  keyup
可以在这途中被中断。

结论:keydown和keypress,还没有将当前输入内容放入input框,所以也无法获取最新的值。
//IE浏览器兼容性。成功,在键盘松开时将值放到input,然后获取时已是最新
			if($.browser.msie){
				var inputArr = this.$el.find("input.colName, input.colurl");
				for(var i = 0; i < inputArr.length; i++){
					$(inputArr[i]).on('keyup', function(){
						_this.model.set('crownListRowList', _this.getSrcData());
					});
				}
			}


//IE浏览器兼容性。失败,属性太强
			if($.browser.msie){
				var inputArr = this.$el.find("input.colName, input.colurl");
				for(var i = 0; i < inputArr.length; i++){
					$(inputArr[i])[0].attachEvent("onpropertychange",function(){
						this.getSrcData();
					});
				}
			}


onpropertychange 除非置为disabled,否则任何变化都会触发。
缺点是:任何属性都会变化,不够灵活。比如想在input输入框加验证。这次就会触发对应的回调函数。





5,backbone子类调用的问题
应该放到render里调用。而不是放到initialize中。


4,backbone的new View(参数),在View的initialize中如何拿到

var view = new View({
    model:model,
    data:data
});

var View = Backbone.extend.View({
    initialize:function(){
         this.model.set(this.options.data);
    }
});
结论:通过this.options可以获取传递的参数


3,this作用域的问题
$.each(json,function(index, item){
    //此时的this是item,不再是外面的this
});
if($.browser.msie){
	var inputArr = this.$el.find("input.colName, input.colurl");
	for(var i = 0; i < inputArr.length; i++){
		$(inputArr[i])[0].attachEvent("onpropertychange",function(){
			_this.model.set({crownListRowList: eval(_this.crownSheet.getEditedDataForPreview())});
		});
	}
}




2,IE浏览器下实时预览用户在input输入框中输入的数据
在非IE浏览器下,用input事件
在IE浏览器想,用onpropertychange事件

再加上paste,就完美了。

但是,经查找,onpropertychange属性监听不到的情况:
1,input是disabled时。
2,使用jQuery或其他手段向input设值。

尽管我目前够用了。查到的解决办法只有一个那就是定时监控。
当input获取到焦点时,定时器开启,每隔0.1秒去读input中最新的结果。
一旦input失去焦点,则清除定时器。


1,拼接JSON串耗时较长,完全是试着来的
//在另一个函数里
_constructor.prototype.bindXX = function(){
	this.colNames = [], this.colurls = [];
	var tblObj = null;
	if(this.device == 1){
		tblObj = this.$el.find("#form_pc");
	}else if(this.device == 2){
		tblObj = this.$el.find("#form_mobile");
	}
	var trs = tblObj.find("tr:visible");
	for (var i = 1; i < trs.length; i++) {
		var rowNameArr = [], 
			rowUrlArr  = [],
			tds        = $(trs[i]).find("td:visible");
		for (var j = 1; j < tds.length; j++) {
			rowNameArr.push($(tds[j]).find("input.colName"));
			rowUrlArr.push($(tds[j]).find("input.colurl"));
		}
		this.colNames.push(rowNameArr);
		this.colurls.push(rowUrlArr);
	}
}

//
var str = "[";
for (var i = 0; i < this.colNames.length; i++) {
	var rowStr = "{";
	for (var j = 0; j < this.colNames[i].length; j++) {
		rowStr += (rowStr=="{"?("col"+(j+1)+"Name:"):(",col"+(j+1)+"Name:")) + "'"+$.trim($(this.colNames[i][j]).val())+"'";
		rowStr += ",col"+(j+1)+"url:" + ( $(this.colurls[i][j]).prop("disabled") ? "''" : "'"+$.trim($(this.colurls[i][j]).val())+"'" );
	}
	rowStr += "},";
	str += rowStr;
}
str = (str.slice(0,str.length-1) + "]");
//return eval(str);
return str;

二维json的格式是:
[{k11:v11, k12:v12,  ... },
{k21:v21, k22:v22,  ... },
{k31:v31, k32:v32,  ... },
...
{kn1:vn1, kn2:vn2,  ... },
]
拼接完之后是字符串,还需要用eval转成对象,才能使用。
分享到:
评论

相关推荐

    2014-cp-personal

    描述中提到的"计算机编程部分"以及"笔记",表明这是一个关于编程的学习记录或者代码库,可能包含作者在2014年12月23日学习或开发过程中的一些心得、示例代码和进度。 标签“JavaScript”明确了这个项目或笔记主要...

    2014年Java最全面试题以及答案.

    2014年Java试题及答案涉及了Java基础知识、J2EE技术、Java EE的Web组件技术,以及SSH框架等。以下是对上述内容的知识点详细说明: 1. super()与this()的区别? super关键字用于访问父类的属性、方法和构造器,而...

    2014年12月考试可视化程序设计(VB) B 卷.doc

    - **整型数组声明**: `Dim a(1 to 12) As Integer`创建了一个包含12个整型元素的数组(选项B正确)。 以上内容涵盖了给定文件中提到的主要知识点,有助于理解Visual Basic编程的基本概念和技术细节。

    广东省韶关市第五中学2013_2014学年高二数学12月月考试题理新人教A版.rar

    标题中的“广东省韶关市第五中学2013_2014学年高二数学12月月考试题理新人教A版.rar”表明这是一个针对广东省韶关市第五中学高二年级学生的数学月考试题,时间是2013至2014学年的12月份,试题类型为理科,使用的教材...

    湖南省湘乡市泉塘镇湖山2014-2015学年七年级地理12月月考试题(无答案).doc

    这份文档是湖南省湘乡市泉塘镇湖山中学2014-2015学年七年级地理12月的月考试题,主要涵盖了初中地理的基础知识,涉及气候、天气现象、气温分布规律、降水影响因素等多个核心概念。下面将详细解释其中涉及的地理知识...

    全国2014年4月高等教育自学考试财务报表分析(一)试题.pdf

    根据提供的文件信息,这份文件是关于“全国2014年4月高等教育自学考试财务报表分析(一)试题”的内容。这份试题所涉及的知识点主要集中在财务报表分析的领域内,具体的知识点可以从几个方面来阐述: 1. 财务比率分析...

    2014年广东工业大学汇编试卷

    广东工业大学2014年12月的汇编试卷,旨在考察学生对汇编语言基础知识的掌握程度,包括但不限于以下几个方面: 1. **指令系统**:汇编语言中的指令包括数据处理指令(如加法、减法)、转移指令(如跳转、条件跳转)...

    2014年10月自考电子商务概论(00896)试题及答案.pdf

    2014年10月的试题及答案旨在测试考生对这门课程的理解和掌握程度。 1. Ss1协议是一种网络通信协议,它包含握手协议和消息加密协议,用于保证通信的安全性。选项D描述不正确,因为Ss1协议的使用可以有效防止商家欺诈...

    sqlserver错误日志

    1. **日志时间**:2014年12月19日13:06:52,这是一个具体的记录时间点。 2. **SPID (Session Process ID)**:spid213,标识了当前会话的进程ID。 3. **错误信息**:“系统资源池'default'中没有足够的系统内存来运行...

    2014c语言必做题

    - 描述:已知2013年1月1日是星期二,输入2013年的一个日期(月和日),判断这天是星期几。 - 关键知识点: - 输入输出操作:使用`scanf`接收月份和日期,使用`printf`输出星期几。 - 算法实现:利用基姆拉尔森...

    2014年浙大远程教育会计电算化在线作业.doc

    在2014年浙江大学远程教育会计电算化在线作业中,涉及的知识点主要包括以下几个方面: 1. **会计电算化实施准备**:会计电算化的准备阶段包括制定实施计划、统一认识、整顿基础工作等。这要求单位有明确的实施策略...

    2014北大数算期末考试

    考试时间为2014年1月1日,由任课教师监考。考试要求学生严格遵守考场纪律,包括隔位就座、不允许携带非必需品进入考场、禁止作弊等行为。 #### 题目分析 ##### 填空题部分 1. **BFS算法与单源最短路径** - **...

    近年-近年学年三年级数学上册第七单元年、月、日测试卷北师大版(最新整理).pdf

    一年有12个月,其中7个大月(1月、3月、5月、7月、8月、10月、12月)各有31天,4个小月(4月、6月、9月、11月)各有30天。 2. **闰年规则**:通常情况下,每4年有一个闰年,闰年全年有366天,2月有29天。但非世纪年...

    三年级数学下册第9单元总复习9.1年月日课时练新人教版

    - 判断题中提到,一年中有6个月是大月,6个月是小月,这个表述是错误的,因为实际上一年中有7个大月(1月、3月、5月、7月、8月、10月、12月,各有31天),4个小月(4月、6月、9月、11月,各有30天),加上2月的特殊...

    2014年9月计算机四级网络工程师题库.pdf

    统的描述中,错误的是(A某些版本可支持Intel平台B由一家公司开发与维护C具有分时、多用户的特点D第一个版本用汇编语言写成) 这些题目涉及了计算机网络、操作系统、网络安全以及网络拓扑等多个方面的知识。让我们...

    poi-3.11-20141221

    这个"poi-3.11-20141221"压缩包包含的是Apache POI库的3.11版本,发布于2014年12月21日。在Java开发中,Apache POI是一个非常重要的工具,因为它允许开发者在不依赖Microsoft Office的情况下读取、写入和修改这些...

    2014年广州州会计从业资格考试《会计电算化》考点重点.docx

    在2014年广州会计从业资格考试《会计电算化》的考点中,主要涉及了以下几个方面的重要知识点: 1. **系统软件和应用软件的关系**:应用软件以前者为基础,依赖系统软件提供的环境和服务来运行。因此,正确答案为D。...

    java实现简单日期计算功能

    该方法用于计算指定时间属于月份中的第几周,例如 2014-12-05 属于 12 月的第一周,2014-12-12属于 12 月的第二周。 4. 获取今天所在周的星期一: public static String getMondyOfToday(String format) 该方法用于...

    文章管理系统

    2011年12月4日 bug修复 1.改进采集栏目中对过滤标签进行注释 2.采集过程中,加入 采集标题 去HTML化处理 3.改进保存远程图片和采集图片逻辑 4.几个小细节纠正 2011年11月24日 V2.3升级包 1.MSXML2.XMLHTTP...

Global site tag (gtag.js) - Google Analytics