试题3
写一个通用的事件侦听器函数
// event(事件)工具集,来源:github.com/markyun
markyun.Event = {
// 页面加载完成后
readyEvent : function(fn) {
if (fn==null) {
fn=document;
}
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = fn;
} else {
window.onload = function() {
oldonload();
fn();
};
}
},
// 视能力分别使用dom0||dom2||IE方式 来绑定事件
// 参数: 操作的元素,事件名称 ,事件处理程序
addEvent : function(element, type, handler) {
if (element.addEventListener) {
//事件类型、需要执行的函数、是否捕捉
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, function() {
handler.call(element);
});
} else {
element['on' + type] = handler;
}
},
// 移除事件
removeEvent : function(element, type, handler) {
if (element.removeEnentListener) {
element.removeEnentListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent('on' + type, handler);
} else {
element['on' + type] = null;
}
},
// 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
stopPropagation : function(ev) {
if (ev.stopPropagation) {
ev.stopPropagation();
} else {
ev.cancelBubble = true;
}
},
// 取消事件的默认行为
preventDefault : function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
// 获取事件目标
getTarget : function(event) {
return event.target || event.srcElement;
},
// 获取event对象的引用,取到事件的所有信息,确保随时能使用event;
getEvent : function(e) {
var ev = e || window.event;
if (!ev) {
var c = this.getEvent.caller;
while (c) {
ev = c.arguments[0];
if (ev && Event == ev.constructor) {
break;
}
c = c.caller;
}
}
return ev;
}
};
Node.js 的适用场景
- 高并发
- 聊天
- 实时消息推送
JavaScript 原型,原型链 ? 有什么特点?
- 原型对象也是普通的对象,是对象一个自带隐式的 proto 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为 null 的话,我们就称之为原型链
- 原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链
怎么重构页面?
- 编写 CSS
- 让页面结构更合理化,提升用户体验
- 实现良好的页面效果和提升性能
WEB应用从服务器主动推送Data到客户端有那些方式?
- html5 websocket
- WebSocket 通过 Flash
- XHR长时间连接
- XHR Multipart Streaming
- 不可见的Iframe
- <script>标签的长时间连接(可跨域)
事件、IE与火狐的事件机制有什么区别? 如何阻止冒泡?
- 我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为
- 事件处理机制:IE是事件冒泡、firefox同时支持两种事件模型,也就是:捕获型事件和冒泡型事件
- ev.stopPropagation();
注意旧ie的方法:ev.cancelBubble = true;
Ajax 是什么?Ajax 的交互模型?同步和异步的区别?如何解决跨域问题?
Ajax 是什么:
- 通过异步模式,提升了用户体验
- 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用
- Ajax 在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。
Ajax 的最大的特点:
- Ajax可以实现动态不刷新(局部刷新)
- readyState 属性 状态 有5个可取值: 0 = 未初始化,1 = 启动, 2 = 发送,3 = 接收,4 = 完成
Ajax 同步和异步的区别:
- 同步:提交请求 -> 等待服务器处理 -> 处理完毕返回,这个期间客户端浏览器不能干任何事
- 异步:请求通过事件触发 -> 服务器处理(这是浏览器仍然可以作其他事情)-> 处理完毕
ajax.open方法中,第3个参数是设同步或者异步。
Ajax 的缺点:
- Ajax 不支持浏览器 back 按钮
- 安全问题 Ajax 暴露了与服务器交互的细节
- 对搜索引擎的支持比较弱
- 破坏了程序的异常机制
- 不容易调试
解决跨域问题:
- jsonp
- iframe
- window.name、window.postMessage
- 服务器上设置代理页面
js对象的深度克隆代码实现
function clone(Obj) {
var buf;
if (Obj instanceof Array) {
buf = []; // 创建一个空的数组
var i = Obj.length;
while (i--) {
buf[i] = clone(Obj[i]);
}
return buf;
} else if (Obj instanceof Object){
buf = {}; // 创建一个空对象
for (var k in Obj) { // 为这个对象添加新的属性
buf[k] = clone(Obj[k]);
}
return buf;
}else{
return Obj;
}
}
对网站重构的理解
网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变 UI 的情况下,对网站进行优化,在扩展的同时保持一致的 UI。
对于传统的网站来说重构通常是:
- 表格(table)布局改为 DIV + CSS
- 使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对 IE6 有效的)
- 对于移动平台的优化
- 针对于 SEO 进行优化
- 深层次的网站重构应该考虑的方面
- 减少代码间的耦合
- 让代码保持弹性
- 严格按规范编写代码
- 设计可扩展的API
- 代替旧有的框架、语言(如VB)
- 增强用户体验
- 通常来说对于速度的优化也包含在重构中
- 压缩JS、CSS、image等前端资源(通常是由服务器来解决)
- 程序的性能优化(如数据读写)
- 采用CDN来加速资源加载
- 对于JS DOM的优化
- HTTP服务器的文件缓存
如何获取UA
<script>
function whatBrowser() {
document.Browser.Name.value=navigator.appName;
document.Browser.Version.value=navigator.appVersion;
document.Browser.Code.value=navigator.appCodeName;
document.Browser.Agent.value=navigator.userAgent;
}
</script>
js 数组去重
方法1
Array.prototype.uniq = function () {
// 长度只有1,直接返回当前的拷贝
if (this.length <= 1) {
return this.slice(0);
}
var aResult = [];
for (var i = 0, l = this.length; i < l; i++) {
if (!_fExist(aResult, this[i])) {
aResult.push(this[i]);
}
}
return aResult;
// 判断是否重复
function _fExist(aTmp, o) {
if (aTmp.length === 0) {
return false;
}
var tmp;
for (var i = 0, l = aTmp.length; i < l; i++) {
tmp = aTmp[i];
if (tmp === o) {
return true;
}
// NaN 需要特殊处理
if (!o && !tmp && tmp !== undefined && o !== undefined && isNaN(tmp) && isNaN(o)) {
return true;
}
}
return false;
}
}
方法2
Array.prototype.rmRepeat = function(){
var res = [],hash={};
var len=this.length;
for (var i=0;i<len ;i++) {
if( !hash.hasOwnProperty('_'+this[i]) )
{
hash['_'+this[i]] = 1;
res.push(this[i]);
}
}
return res;
}
方法3
function unarr(array){
array.sort();
var re = [array[0]];
for(var i = 1; i < array.length; i++){
if(array[i] !== re[re.length - 1]){
re.push(array[i]);
}
}
return re;
}
方法4
//下标判断
function uarr(array){
var n = [array[0]];//结果数组
for(var i = 1; i < array.length; i++){
//如果当前数组的第i项在当前数组中第一次出现的位置不是i;
//那么表示第i项是重复的,忽略掉。否则存入数组
if(array.indexOf(array[i]) == i){
n.push(array[i]);
}
}
return n;
}
HTTP状态码
-
100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
-
200 OK 正常返回信息
-
201 Created 请求成功并且服务器创建了新的资源
-
202 Accepted 服务器已接受请求,但尚未处理
-
301 Moved Permanently 请求的网页已永久移动到新位置
-
302 Found 临时性重定向
-
303 See Other 临时性重定向,且总是使用 GET 请求新的 URI
-
304 Not Modified 自从上次请求后,请求的网页未修改过
-
400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求
-
401 Unauthorized 请求未授权
-
403 Forbidden 禁止访问
-
404 Not Found 找不到如何与 URI 相匹配的资源
-
500 Internal Server Error 最常见的服务器端错误
-
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)
cache-control
网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。
Expires 头部字段提供一个日期和时间,响应在该日期和时间后被认为失效。允许客户端在这个时间之前不去检查(发请求),等同max-age的效果。但是如果同时存在,则被Cache-Control的max-age覆盖。
Expires = "Expires" ":" HTTP-date
例如:
Expires: Thu, 01 Dec 1994 16:00:00 GMT (必须是GMT格式)
如果把它设置为-1,则表示立即过期
Expires 和 max-age 都可以用来指定文档的过期时间,但是二者有一些细微差别
- Expires在HTTP/1.0中已经定义,Cache-Control:max-age在HTTP/1.1中才有定义,为了向下兼容,仅使用max-age不够
- Expires指定一个绝对的过期时间(GMT格式),这么做会导致至少2个问题:
2.1客户端和服务器时间不同步导致Expires的配置出现问题。
2.2很容易在配置后忘记具体的过期时间,导致过期来临出现浪涌现象 - max-age 指定的是从文档被访问后的存活时间,这个时间是个相对值(比如:3600s),相对的是文档第一次被请求时服务器记录的Request_time(请求时间)
- Expires 指定的时间可以是相对文件的最后访问时间(Atime)或者修改时间(MTime),而max-age相对对的是文档的请求时间(Atime)
- 如果值为 no-cache,那么每次都会访问服务器。如果值为max-age,则在过期之前不会重复访问服务器。
js 操作获取和设置 cookie
// 创建cookie
function setCookie(name, value, expires, path, domain, secure) {
var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
if (expires instanceof Date) {
cookieText += '; expires=' + expires;
}
if (path) {
cookieText += '; expires=' + expires;
}
if (domain) {
cookieText += '; domain=' + domain;
}
if (secure) {
cookieText += '; secure';
}
document.cookie = cookieText;
}
// 获取cookie
function getCookie(name) {
var cookieName = encodeURIComponent(name) + '=';
var cookieStart = document.cookie.indexOf(cookieName);
var cookieValue = null;
if (cookieStart > -1) {
var cookieEnd = document.cookie.indexOf(';', cookieStart);
if (cookieEnd == -1) {
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
}
return cookieValue;
}
// 删除cookie
function unsetCookie(name) {
document.cookie = name + "= ; expires=" + new Date(0);
}