开发一个消息推送平台。就是类似于公众号等的消息推送。
下面进行开发过程中遇到问题的一个总结:
(1)事件冒泡和事件捕获
事件捕获:
通俗地讲,就是点击了子元素,相当于从该元素最外层元素开始向内挨个点击,如果每一层都有点击事件的话,就会挨个触发。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>事件捕获</title>
</head>
<body>
<div id="father" style="border:1px solid black;">
father
<div id="son" style="border:1px solid black;">
son
</div>
father
</div>
</body>
<script>
var father=document.getElementById("father");
var son=document.getElementById("son");
function fatherEvent(){
alert("父事件")
}
function sonEvent(){
alert("子事件")
}
son.addEventListener("click",sonEvent,true);
father.addEventListener("click",fatherEvent,true);
</script>
</html>
事件冒泡:
通俗地讲,就是点击了子元素,相当于从最该层元素往外层外开始挨个点击,如果每一层都有点击事件的话,就会挨个触发。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<div id="father" style="border:1px solid black;">
father
<div id="son" style="border:1px solid black;">
son
</div>
father
</div>
</body>
<script>
var father=document.getElementById("father");
var son=document.getElementById("son");
function fatherEvent(){
alert("父事件")
}
function sonEvent(){
alert("子事件")
}
son.addEventListener("click",sonEvent,false);
father.addEventListener("click",fatherEvent,false);
</script>
</html>
需要注意的是:当给某一元素绑定了事件后,如果触发了两次或者是多次的话,那么就要在事件冒泡和事件捕获中考虑了。
(2)高度塌陷
高度塌陷是在开发过程中写css样式时遇到的问题,涉及的东西不是很多,但因为这个名词听起来很专业,故做记录。
通俗地讲。就是由于子元素使用了float浮动,脱离了父元素的“管辖”,导致父元素的高度没有东西填充(撑开),以至于父元素的高度为0。下面看一个例子就可以清楚明白:
<!DOCTYPE html>
<html>
<head></head>
<body>
<div style="border: 1px solid black">
<div style=" float: left;width:150px;height:50px;border:1px solid red;"><span>Block</span></div>
<div style=" float: left;width:150px;height:50px;border:1px solid red;"><span>Block</span></div>
<div style=" float: left;width:150px;height:50px;border:1px solid red;"><span>Block</span></div>
</div>
</body>
</html>
导致的结果就是父元素的高度为0;
黑线就是父元素,高度为0.因为三个Block使用了浮动脱离了文档流,其实也可以这么理解,浮动就是把平面的东西抽了出来,使得从二维变成了三维,二维平面上由于东西被抽走,没有其他元素撑开其高度,最终导致高度为0。
解决办法:
方式一:
<div style="clear: both;"></div>
方式二:
父类元素也设置浮动。
方式三:
方式四:
<!DOCTYPE html>
<html>
<head>
<style>
.father:after{
content: "."; /*生成内容作为最后一个元素,至于content里面是什么没有影响*/
display: block; /*使得生成的元素以块级元素显示,占满剩余空间*/
height: 0; /*避免生成的内容破坏原有空间的高度*/
clear: both; /*闭合浮动*/
visibility: hidden; /*使得生成内容不可见,并允许可能生成内容盖住的内容进行点击和交互*/
}
.father {
zoom : 1; /*触发IE6/7的haslayout*/
}
</style>
</head>
<body>
<div class="father" style=" border: 1px solid black">
<div style=" float: left;width:150px;height:60px;border:1px solid red;"><span>Block</span></div>
<div style=" float: left;width:150px;height:50px;border:1px solid red;"><span>Block</span></div>
<div style=" float: left;width:150px;height:50px;border:1px solid red;"><span>Block</span></div>
</div>
</body>
</html>
(3)js绑定事件的失效与解决办法
使用$().click()开始给指定的元素绑定事件,当js动态添加该元素后,事件无法绑定。使用$(document).on("click","",function(){})即可。为什么会出现这样的问题呢?
jQuery 1.7开始,on()函数提供了绑定事件处理程序所需的所有功能,用于统一取代以前bind(),delegate(),live()等事件函数。
$().bind()直接绑定在元素上,和click,blur,mouseon一样的点击事件。
$().live()是通过冒泡的方式来绑定到元素上的。更适合列表类型的,绑定到document DOM节点上。
$().delegate()是更精确的小范围的使用事件代理。
$().on()结合了这三个方法的优势摒弃了劣势。
该函数可以为同一元素、同一事件类型绑定多个事件处理函数。触发事件时,jQuery会按照绑定的先后顺序依次执行绑定的事件处理函数。
阻止事件冒泡和事件委托的方法:
A:return false。 在事件的处理中,可以阻止默认事件和冒泡事件。
B:event.preventDefault()在事件的处理中,可以阻止默认事件但是允许冒泡事件的发生。
C:event.stopPropagation().。在事件的处理中,可以阻止冒泡但是允许默认事件的发生。
(4)tpl模板的使用:art-template.js和require.js的使用
引入require.js(JavaScript模块加载器)和template-web.js即可,看如下示例代码:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>basic-demo</title>
<script src="web/testA/js/require.js"></script>
</head>
<body>
<div id="content"></div>
<script id="test" type="text/html">
{{if isAdmin}}
<h1>{{title}}</h1>
<ul>
{{each list value i}}
<li>索引 {{i + 1}} :{{value}}</li>
{{/each}}
</ul>
{{/if}}
{{$data}}
</script>
<script>
require.config({
baseUrl:'web/testA/',
paths: {
'art-template': 'js/template-web'
}
});
require(['art-template'], function(template) {
var data = {
title: '基本例子',
isAdmin: true,
list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']
};
var html = template('test', data);
document.getElementById('content').innerHTML = html;
});
</script>
</body>
</html>
使用tpl模板实际上只需要做三步事情,写模板,调用函数将数据插入模板得到返回值html,将返回值放入指定位置。
(5)ajax格式及各属性含义ajax
(6)原生js查找元素,jquery方式查找子类元素(要注意,原生的方法应该多加使用,框架会过时,但最原始的,往往才是更古不变的)
jQuery.parent(expr) 找父亲节点,可以传入expr进行过滤,比如$("span").parent()或者$("span").parent(".class")
jQuery.parents(expr),类似于jQuery.parents(expr),但是是查找所有祖先元素,不限于父元素
jQuery.children(expr).返回所有子节点,这个方法只会返回直接的孩子节点,不会返回所有的子孙节点
jQuery.contents(),返回下面的所有内容,包括节点和文本。这个方法和children()的区别就在于,包括空白文本,也会被作为一个
jQuery对象返回,children()则只会返回节点
jQuery.prev(),返回上一个兄弟节点,不是所有的兄弟节点
jQuery.prevAll(),返回所有之前的兄弟节点
jQuery.next(),返回下一个兄弟节点,不是所有的兄弟节点
jQuery.nextAll(),返回所有之后的兄弟节点
jQuery.siblings(),返回兄弟姐妹节点,不分前后
jQuery.find(expr),跟jQuery.filter(expr)完全不一样。jQuery.filter()是从初始的jQuery对象集合中筛选出一部分,而jQuery.find()的返回结果,不会有初始集合中的内容,比如$("p"),find("span"),是从<p>元素开始找<span>,等同于$("p span")
(7)Json的标准格式Json格式
(8)json字符串解析成Json对象(这里要注意该字符串是json的单个object对象还是json的数据对象)单个对象直接使用JSONObject.parseObject(str)即可,如果是对象数组,那么要解析成JSON数组JSONObject.arrayObject(str),当然,这里要注意的是,切记切记:如果字符串(也就是双引号里面的内容不满足JSON的标准格式(单个对象或者对象数组的标准格式)),那么解析就会失败,通俗的将也就是控制台报错,日志打印该错误等。
(9)在写接口的过程中,要学会善于拼接前端所需要的数据,以相对应的数据格式,将数据传输到前端,便于前端展示。这是作为前后端协同开发很关键的一点,一个很乱,很难解析的数据格式,会导致整个项目的进度停滞不前。
(10)开发结束后,要想这个系统的鲁棒性更强,用户使用体验感更好,那么你就需要不断地优化,比如给推送的消息做分页,原先是一次性请求所有的消息,做完分页后,一次请求十条或者是二十条,将极大的提高用户的使用体验,因为该简易版的推送消息系统做得急,几天的时间需要配套其他系统的上线,因此是很不完善的,在用户数目不断增加,推送消息不断增多的时候,问题就很大的暴露出来了,消息渲染的很慢,用户要等很长的时间,因此不断地优化才能使开发的系统越来越完善,其次系统请求了其他公司的接口,由于其他公司的接口响应缓慢,导致这边的查询也会有很大延迟,那么其中的解决方法就有,建立中缓存表,将从其他公司请求来的数据插入自己的表中,下次访问是否就快了呢,当然,聪明的同学可能就会想到,以后如果每次都请求自己的缓存表数据,万一用户的数据更新了怎么办?答案是我也不知道怎么办,具体情况具体分析,涉及到一个数据实时性的问题,如果对实时性不高的系统,是否可以写个定时任务去更新表数据?实时性高的呢,是否可以起个线程??,很相信那句话,方法总比困难多,一个系统或者一款软件要想有很强的生命力,那么就要不断改进,不断优化,不断地客服困难,不断地提高用户体验。