365.
[问答题]
原生 JavaScript 中兼容浏览器绑定元素事件
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function addEventSamp(obj,evt,fn){ if () {
(evt, fn, false);
}else if(){ ('on'+evt,fn);
}
}
366.
[问答题]
原生 JavaScript 光标停在文字的后面,文本框获得焦点时调用
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function focusLast(){
var e = ; var r =();
('character',); (true);
();
}
367.
[问答题]
原生 JavaScript 检验 URL 链接是否有效
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getUrlState(URL){
var xmlhttp = new ActiveXObject(""); ("GET",URL, false);
try{
();
}catch(e){
}finally{
var result = ; if(result){
if(==200){ return(true);
}else{
return(false);
}
}else{
return(false);
}
}
}
368.
[问答题]
原生 JavaScript 格式化 CSS 样式代码
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function formatCss(s){//格式化代码
s = (/\s*([\{\}\:\;\,])\s*/g, "$1");
s = (/;\s*;/g, ";"); //清除连续分号 s = (/\,[\s\.\#\d]*{/g, "{");
s = (/([^\s])\{([^\s])/g, "$1 {\n\t$2");
s = (/([^\s])\}([^\n]*)/g, "$1\n}\n$2");
s = (/([^\s]);([^\s\}])/g, "$1;\n\t$2"); return s;
}
369.
[问答题]
原生 JavaScript 压缩 CSS 样式代码
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function yasuoCss (s) {//压缩代码
s = (/\/\*(.|\n)*?\*\//g, ""); //删除注释 s = (/\s*([\{\}\:\;\,])\s*/g, "$1");
s = (/\,[\s\.\#\d]*\{/g, "{"); //容错处理 s = (/;\s*;/g, ";"); //清除连续分号
s = (/^\s*(\S+(\s+\S+)*)\s*$/); //去掉首尾空白return (s == null) ? "" : s[1];
}
370.
[问答题]
原生 JavaScript 获取当前路径
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
var currentPageUrl = "";
if (typeof === "undefined") {
currentPageUrl = ().toLowerCase();
}
else {
currentPageUrl = ().toLowerCase();
}
371.
[问答题]
原生 JavaScriptIP 转成整型
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function _ip2int(ip){ var num = 0;
ip = (".");
num = Number(ip[0]) * 256 * 256 * 256 + Number(ip[1]) * 256 * 256 + Number(ip[2]) * 25
6 + Number(ip[3]);
num = num >>> 0; return num;
}
372.
[问答题]
原生 JavaScript 整型解析为 IP 地址
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function _int2iP(num){
}
373.
var str;
var tt = new Array();
tt[0] = (num >>> 24) >>> 0;
tt[1] = ((num << 8) >>> 24) >>> 0; tt[2] = (num << 16) >>> 24;
tt[3] = (num << 24) >>> 24;
str = String(tt[0]) + "." + String(tt[1]) + "." + String(tt[2]) + "." + String(tt[3]); return str;
[问答题]
原生 JavaScript 实现 checkbox 全选与全不选
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function checkAll() {
var selectall = ("selectall"); var allbox = ("allbox"); if () {
for (var i = 0; i < ; i++) { = true;
}
} else {
for (var i = 0; i < ; i++) { = false;
}
}
}
374.
[问答题]
原生 JavaScript 判断是否移动设备
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function isMobile(){
if (typeof this._isMobile === 'boolean'){ return this._isMobile;
}
var screenWidth = ();
var fixViewPortsExperiment = || rende ;
var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperi () === "new");
if(!fixViewPortsExperiment){ if(!()){
screenWidth = screenWidth/;
}
}
}
375.
var isMobileScreenSize = screenWidth < 600; var isMobileUserAgent = false;
this._isMobile = isMobileScreenSize && (); return this._isMobile;
[问答题]
原生 JavaScript 判断是否移动设备访问
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function isAppleMobileDevice(){
return (/iphone|ipod|ipad|Macintosh/(()));
}
376.
[问答题]
原生 JavaScript 判断是否苹果移动设备访问
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function isAppleMobileDevice(){
return (/iphone|ipod|ipad|Macintosh/(()));
}
377.
[问答题]
原生 JavaScript 判断是否安卓移动设备访问
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function isAndroidMobileDevice(){
return (/android/(()));
}
378.
[问答题]
原生 JavaScript 判断是否 Touch 屏幕
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function isTouchScreen(){
return (('ontouchstart' in window) || && document instanceof DocumentTouch);
}
379.
[问答题]
原生 JavaScript 判断是否在安卓上的谷歌浏览器
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function isNewChromeOnAndroid(){ if(()){
var userAgent = (); if((/chrome/(userAgent))){
var parts = ('chrome/');
var fullVersionString = parts[1].split(" ")[0];
var versionString = ('.')[0]; var version = parseInt(versionString);
if(version >= 27){
return true;
}
}
}
return false;
}
380.
[问答题]
原生 JavaScript 判断是否打开视窗
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function isViewportOpen() {
return !!('wixMobileViewport');
}
381.
[问答题]
原生 JavaScript 获取移动设备初始化大小
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getInitZoom(){ if(!this._initZoom){
var screenWidth = (, ); if(() && !()){
screenWidth = screenWidth/;
}
this._initZoom = screenWidth /;
}
return this._initZoom;
}
382.
[问答题]
原生 JavaScript 获取移动设备最大化大小
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getZoom(){
var screenWidth = (() === 90) ? (, sc ) : (, );
if(() && !()){ screenWidth = screenWidth/;
}
var FixViewPortsExperiment = || rend ;
var FixViewPortsExperimentRunning = FixViewPortsExperiment && (FixViewPortsExperi ment === "New" || FixViewPortsExperiment === "new");
if(FixViewPortsExperimentRunning){
return screenWidth / ;
}else{
return screenWidth / ;
}
}
383.
[问答题]
原生 JavaScript 获取移动设备屏幕宽度
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getScreenWidth(){
var smallerSide = (, );
var fixViewPortsExperiment = || rende ;
var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperi () === "new");
if(fixViewPortsExperiment){
if(() && !()){ smallerSide = smallerSide/;
}
}
return smallerSide;
}
384.
[问答题]
原生 JavaScript 完美判断是否为网址
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function IsURL(strUrl) {
var regular = /^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|n et|org|biz|info|name|museum|asia|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\ d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$/i
if ((strUrl)) { return true;
}
else {
return false;
}
}
385.
[问答题]
原生 JavaScript 根据样式名称检索元素对象
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getElementsByClassName(name) {
var tags = ('*') || ; var els = [];
for (var i = 0; i < ; i++) { if () {
var cs = (' '); for (var j = 0; j < ; j++) {
if (name == cs[j]) { (tags); break
}
}
}
}
return els
}
386.
[问答题]
原生 JavaScript 判断是否以某个字符串开头
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
= function (s) { return (s) == 0
}
387.
[问答题]
原生 JavaScript 判断是否以某个字符串结束
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
= function (s) { var d = - ;
return (d >= 0 && (s) == d)
}
388.
[问答题]
原生 JavaScript 返回 IE 浏览器的版本号
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getIE(){
if (){
var v = (/MSIE ([^;]+)/)[1]; return parseFloat((0, (".")))
}
return false
}
389.
[问答题]
原生 JavaScript 获取页面高度
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getPageHeight(){
var g = document, a = , f = , d = == "BackCom
pat"
}
? a
: ;
return (, , );
390.
[问答题]
原生 JavaScript 获取页面 scrollLeft
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getPageScrollLeft(){ var a = document;
return || ;
}
391.
[问答题]
原生 JavaScript 获取页面可视宽度
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getPageViewWidth(){
var d = document, a = == "BackCompat"
?
: ; return ;
}
392.
[问答题]
原生 JavaScript 获取页面宽度
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getPageWidth(){
var g = document, a = , f = , d = == "BackCom
pat"
}
? a
: ;
return (, , );
393.
[问答题]
原生 JavaScript 获取页面 scrollTop
----------------------------------------------------------------------------------------------------------------------------
来自:原生 Javascript 编程练习题参考:
function getPageScrollTop(){ var a = document;
return || ;
}
394.
[问答题]
考察知识点:作用域考虑如下代码: (function() {
var a = b = 5;
})();
(b);
请问控制台上会输出什么?
----------------------------------------------------------------------------------------------------------------------------
来自:Javascript 开发者面试典型题集输出:5
这一题的陷阱是,在函数表达式中有两个赋值,但 a 是用关键字var 来声明的,这意味着 a 是局部变量,而b 则被赋予为全局变量。
另一个陷阱是,它并没有使用严格模式(use strict)。在函数里面,如果启用了严格模式,代码就会报错:“Uncaught ReferenceError: b is not defined”。请记住,严格模式需要你显式地引用全局作用域,代码应该写成:
(function() { 'use strict';
var a = = 5;
})();
(b);
395.
[问答题]
考察知识点:创建“内置”方法
给 String 对象定义一个 repeatify 方法。该方法接收一个整数参数,作为字符串重复的次数,最后返回重复指定次数的字符串。例如:
('hello'.repeatify(3));
输出应该是
hellohellohello.
----------------------------------------------------------------------------------------------------------------------------
来自:Javascript 开发者面试典型题集参考:
一个可行的做法如下:
= || function(times) { var str = '';
for (var i = 0; i < times; i++) { str += this;
}
return str;
};
这题测试开发者对 Javascript 的继承及原型属性的知识,它同时也检验了开发者是否能扩展内置数据类型的方法。
这里的另一个关键点是,看你怎样避免重写可能已经定义了的方法。这可以通过在定义自己的方法之前,检测方法是否已经存在。
= || function(times) {/* code here */};
当被问起去扩展一个 Javascript 方法时,这个技术非常有用。
396.
[问答题]
考察知识点:声明提前
下面这段代码的结果是什么?为什么?
function test() { (a); (foo()); var a = 1;
function foo() { return 2;
}}
test();
----------------------------------------------------------------------------------------------------------------------------
来自:Javascript 开发者面试典型题集参考:
代码的运行结果:undefined 和 2
理由是,变量和函数的声明都被提前至函数体的顶部,而同时变量并没有被赋值。因此, 当打印变量a 时,它虽存在于函数体(因为 a 已经被声明),但仍然是 undefined。换句话说, 上面的代码等同于下面的代码:
function test() { var a;
function foo() { return 2;
}
(a); (foo()); a = 1;
}
test();
397.
[问答题]
考察知识点:JavaScript 中的 this
下面代码的运行结果是什么并做解释。
var fullname = 'John Doe'; var obj = {
fullname: 'Colin Ihrig', prop: {
fullname: 'Aurelio De Rosa', getFullname: function() {
return ;
}}};
(()); var test = ; (test());
----------------------------------------------------------------------------------------------------------------------------
来自:Javascript 开发者面试典型题集参考:
代码输出:Aurelio De Rosa 和 John Doe
理由是,Javascript 中关键字 this 所指代的函数上下文,取决于函数是怎样被调用的, 而不是怎样被定义的。
在第一个 (),getFullname()被作为 对象被调用。因此,当前的上下文指代后者,函数返回这个对象的 fullname 属性。相反,当 getFullname()被赋予 test 变量,当前的上下文指代全局对象 window,这是因为 test 被隐式地作为全局对象的属性。基于这一点,函数返回window 的 fullname,在本例中即为代码的第一行。
398.
[问答题]
考察知识点:call()和 apply()
修复前一个问题,让最后一个 () 打印输出 Aurelio De Rosa.
----------------------------------------------------------------------------------------------------------------------------
来自:Javascript 开发者面试典型题集参考:
这个问题可以通过运用 call()或者 apply()方法强制转换上下文环境。下面的代码中用了 call(),但 apply()也能产生同样的结果:
(());
399.
[问答题]
真假判断
var aLinks=('a'); for(i=0;i<;i++)
{
}
----------------------------------------------------------------------------------------------------------------------------
来自:百度 2011 年 6 月前端开发面试题参考:
复制代码修改后:
var aLinks=('a'); for(var i=0,l= ;i<l;i++)
{
}
400.
[问答题]
参照上题代码,给 a 添加事件,要求点击弹出提示相应的 index 值。
----------------------------------------------------------------------------------------------------------------------------
来自:百度 2011 年 6 月前端开发面试题参考:
(1)、第一种方法(加索引)
var aLinks=('a'); for(var i=0,l= ;i<l;i++)
{
aLinks[i].Index=I; aLinks[i].οnclick=function(){alert()};
}
(2)、第二种方法(闭包)
var aLinks=('a'); for(var i=0,l= ;i<l;i++)
{
}
401.
aLinks[i].οnclick=(function(a){ return function(){alert(a);}
})(i);
[问答题]
用户上传图片,没有刷新过程显示图片的功能【ajax】
----------------------------------------------------------------------------------------------------------------------------
来自:百度 2011 年 6 月前端开发面试题附加题参考:无
402.
[问答题]
写出下面 JS 的运行结果:
var a = 10,b = 20,c = 10; alert(a=b);alert(a==b);alert(a==c);
----------------------------------------------------------------------------------------------------------------------------
来自:搜道网前端开发面试题参考:
20 true false
403.
[问答题]
a:javascript 如何深度克隆一个对象?
b:javascript 如何消除一个数组里面重复的元素?
----------------------------------------------------------------------------------------------------------------------------
来自:搜道网前端开发面试题参考:
a:
function ()
{
function NEWOBJECT(){}; NEWOBJECT. prototype = this; var anObj = new NEWOBJECT(); for ( var ele in anObj )
{
if ( typeof anObj[ele] == “object” ) return anObj[ele]. cloneObj();
}
return anObj;
}
b:
function getNewArr(oldArr){
if(typeof oldArr != "object") return oldArr; var newArr = [];
var oldArrLen = -1, newArrLen = -1, flag = false; for(var i=oldArrLen; i>=0; i--){
flag = false;
for(var j=newArrLen; j>=0; j--){ if(oldArr === newArr[j]){
flag = true;
break;
}
}
if(!flag) newArrLen = (oldArr)-1;
}
return newArr;
}
404.
[问答题]
你玩微博吗? 现有这样的字符串: @ 小甜甜(xiaotiantian) 或者 @ 小王的后宫(hougong123) ..这样的字符串如何在计算字数的时候,省略括号里面的内容?比如 @小甜甜(xiaotiantian) 他的长度应该是省略 (xiaotiantian) 这个字符串后的长度,就是 3. 你有多少种方法来实现,请写下代码。
----------------------------------------------------------------------------------------------------------------------------
来自:搜道网前端开发面试题参考:
a:使用正则替换掉 (XXX),然后使用 返回长度,代码:
function getStrLen(str){return ((/[\(\w\)]/g, "")).lenght;}
b:使用 indexOf 查找"("与")",记录相关位置,然后使用 ()函数截取,得到新串,再.length 得到长度,代码:
function getStrLen(str){
return ((0, ("("))+((")")+1)).length;
}
405.
[问答题]
用 Html5+js 重现"新浪微博手机体验版"首页。
----------------------------------------------------------------------------------------------------------------------------
来自:UC(优视)前端面试题参考:无
406.
[问答题]
设计一个鼠标移入移出代理组件,在 UL 或 OL 上绑定事件,使得鼠标经过里面的 li 时可触发移入移出函数。
----------------------------------------------------------------------------------------------------------------------------
来自:乐视前端面试题参考:无
407.
[问答题]
有多个模块会用到同一个接口的数据(需要异步请求,并且只能请求一次),但各模块在什么时候执行不确定,请设计一个组件解决这个问题。
----------------------------------------------------------------------------------------------------------------------------
来自:乐视前端面试题参考:无
408.
[问答题]
请把以下用于连接字符串的 JavaScript 代码修改为更高效的方式
var htmlString = ‘<div class=”container”>’ +
‘<ul id=”news-list”>’;
for (var i = 0; i < ; i++) { htmlString += ‘<li><a href=”’ +
NEWS*i+.LINK + ‘”> +
NEWS*i+.TITLE + ‘</a></li>’;
}
htmlString += ‘</ul></div>’;
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
409.
[问答题]
尝试实现注释部分的 Javascript 代码,可在其他任何地方添加更多代码(如不能实现, 说明一下不能实现的原因):
var Obj = function(msg){ = msg; = function(){
alert();
}
= function(){
//隔五秒钟后执行上面的 shout 方法
}
}
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
410.
[问答题]
请编写一个 JavaScript 函数 toRGB,它的作用是转换 CSS 中常用的颜色编码。 要求:
alert(toRGB("#0000FF")); // 输出 rgb(0, 0, 255)
alert(toRGB("invalid")); // 输出 invalid
alert(toRGB("#G00")); // 输出 #G00
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
411.
[问答题]
javascript 有哪几种方法定义函数
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
- [ 函 数 声 明 表 达式](/en-US/docs/Web/JavaScript/Reference/Statements/function)
- [function 操 作符](/en-US/docs/Web/JavaScript/Reference/Operators/function)
- [Function 构 造 函数 ](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Functi on)
- [ES6:arrow
function](/en-US/docs/Web/JavaScript/Reference/arrow_functions)
412.
[问答题]
应用程序存储和离线 web 应用
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
HTML5 新增应用程序缓存,允许 web 应用将应用程序自身保存到用户浏览器中,用户离线状态也能访问。
- 为 html 元素设置 manifest 属性:<html manifest="">,其中后缀名只是一个约定,真正识别方式是通过 text/cache-manifest 作为 MIME 类型。所以需要配置服务器保证设置正确
- manifest 文件首行为 CACHE MANIFEST,其余就是要缓存的 URL 列表,每个一行,相对路径都相对于manifest 文件的 url。注释以#开头
- url 分为三种类型:CACHE:为默认类型。NETWORK:表示资源从不缓存。 FALLBACK: 每行包含两个 url,第二个 URL 是指需要加载和存储在缓存中的资源, 第一个 URL 是一个前缀。任何匹配该前缀的 URL 都不会缓存,如果从网络中载入这样的 URL 失败的话,就会用第二个 URL 指定的缓存资源来替代。以下是一个文件例子:
CACHE MANIFEST CACHE:
FALLBACK:
videos/ offline_help.html NETWORK:
cgi/
客户端存储 localStorage 和 sessionStorage
localStorage 有效期为永久,sessionStorage 有效期为顶层窗口关闭前
同源文档可以读取并修改 localStorage 数据,sessionStorage 只允许同一个窗口下的文档访问,如通过iframe 引入的同源文档。
Storage 对象通常被当做普通 javascript 对象使用:通过设置属性来存取字符串值,也可以通过 setItem(key, value)设置,getItem(key)读取,removeItem(key)删除,clear()删除所有数据,length 表示已存储的数据项数目,key(index)返回对应索引的 key
('x', 1); // storge x->1 ('x); // return value of x
// 枚举所有存储的键值对
for (var i = 0, len = ; i < len; ++i ) { var name = (i);
var value = (name);
}
('x'); // remove x (); // remove all data
413.
[问答题]
cookie 及其操作
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
cookie 是 web 浏览器存储的少量数据,最早设计为服务器端使用,作为 HTTP 协议的扩展实现。cookie 数据会自动在浏览器和服务器之间传输。
通过读写 cookie 检测是否支持
cookie 属性有名,值,有效期,作用域,secure;
cookie 默认有效期为浏览器会话,一旦用户关闭浏览器,数据就丢失,通过设置
max-age=seconds 属性告诉浏览器 cookie 有效期
cookie 作用域通过文档源和文档路径来确定,通过 path 和 domain 进行配置,web 页面同目录或子目录文档都可访问
通过 cookie 保存数据的方法为:为 设置一个符合目标的字符串如下读取 获得'; '分隔的字符串,key=value,解析得到结果 = 'name=qiu; max-age=9999; path=/; domain=domain; secure'; = 'name=aaa; path=/; domain=domain; secure';
// 要改变 cookie 的值,需要使用相同的名字、路径和域,新的值
// 来设置 cookie,同样的方法可以用来改变有效期
// 设置 max-age 为 0 可以删除指定cookie
//读取 cookie,访问 返回键值对组成的字符串,
//不同键值对之间用'; '分隔。通过解析获得需要的值:自己写的 cookie 操作工具
414.
[问答题]
javascript 有哪些方法定义对象
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
对象字面量: var obj = {};
构造函数: var obj = new Object();
(): var obj = ();
415.
[问答题]
===运算符判断相等的流程是怎样的
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题
参考:
如果两个值不是相同类型,它们不相等
如果两个值都是 null 或者都是 undefined,它们相等
如果两个值都是布尔类型 true 或者都是 false,它们相等如果其中有一个是NaN,它们不相等
如果都是数值型并且数值相等,他们相等, -0 等于 0
如果他们都是字符串并且在相同位置包含相同的 16 位值,他它们相等;如果在长度或者内容上不等,它们不相等;两个字符串显示结果相同但是编码不同==和===都认为他们不相等
如果他们指向相同对象、数组、函数,它们相等;如果指向不同对象,他们不相等
416.
[问答题]
==运算符判断相等的流程是怎样的
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
如果两个值类型相同,按照===比较方法进行比较如果类型不同,使用如下规则进行比较
如果其中一个值是 null,另一个是 undefined,它们相等
如果一个值是数字另一个是字符串,将字符串转换为数字进行比较
如果有布尔类型,将 true 转换为 1,false 转换为 0,然后用==规则继续比较
如果一个值是对象,另一个是数字或字符串,将对象转换为原始值然后用==规则继续比
较
其他所有情况都认为不相等
417.
[问答题]
对象到字符串的转换步骤
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
如果对象有 toString()方法,javascript 调用它。如果返回一个原始值(primitive value 如:
string number boolean),将这个值转换为字符串作为结果
如果对象没有 toString()方法或者返回值不是原始值,javascript 寻找对象的 valueOf()方法,如果存在就调用它,返回结果是原始值则转为字符串作为结果
否则,javascript 不能从 toString()或者 valueOf()获得一个原始值,此时 throws a TypeError
对象到数字的转换步骤
- 如果对象有valueOf()方法并且返回元素值,javascript 将返回值转换为数字作为结果
- 否则,如果对象有 toString()并且返回原始值,javascript 将返回结果转换为数字作为结果
- 否则,throws a TypeError
<,>,<=,>=的比较规则
所有比较运算符都支持任意类型,但是比较只支持数字和字符串,所以需要执行必要的转换然后进行比较,转换规则如下: 1. 如果操作数是对象,转换为原始值:如果valueOf 方法返回原始值,则使用这个值,否则使用 toString 方法的结果,如果转换失败则报错 2. 经过必要的对象到原始值的转换后,如果两个操作数都是字符串,按照字母顺序进行比较(他们的 16 位 unicode 值的大小) 3. 否则,如果有一个操作数不是字符串,将两个操作数转换为数字进行比较
418.
[问答题]
+运算符工作流程
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
- 如果有操作数是对象,转换为原始值
- 此时如果有**一个操作数是字符串**,其他的操作数都转换为字符串并执行连接
- 否则:**所有操作数都转换为数字并执行加法**
419.
[问答题]
函数内部 arguments 变量有哪些特性,有哪些属性,如何将它转换为数组
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
arguments 所有函数中都包含的一个局部变量,是一个类数组对象,对应函数调用时的实参。如果函数定义同名参数会在调用时覆盖默认对象
arguments[index]分别对应函数调用时的实参,并且通过 arguments 修改实参时会同时修改实参
为实参的个数( 表示形参长度)
为当前正在执行的函数本身,使用这个属性进行递归调用时需注意 this
的变化
为调用当前函数的函数(已被遗弃)
转换为数组:var args = (arguments, 0);
420.
[问答题]
DOM 事件模型是如何的,编写一个 EventUtil 工具类实现事件管理兼容
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
DOM 事件包含捕获(capture)和冒泡(bubble)两个阶段:捕获阶段事件从 window 开始触发事件然后通过祖先节点一次传递到触发事件的 DOM 元素上;冒泡阶段事件从初始元素依次向祖先节点传递直到window
标 准 事 件 监 听 (type, handler, capture)/(type, handler, capture):handler 接收保存事件信息的event对象作为参数, 为触发事件的对象,handler 调用上下文this 为绑定监听器的对象 , () 取 消 事 件 默 认 行 为 , ()/()取消事件传递
老版本 IE 事件监听 ('on'+type, handler)/('on'+type, handler):handler 不接收event 作为参数,事件信息保存在 中,触发事件的对象为,handler 执行上下文 this 为 window 使用闭包中调用 (elem, event)可模仿标准模型,然后返回闭包,保证了监听器的移除。 为 false 时取消事件默认行为, 为 true 时取消时间传播
通常利用事件冒泡机制托管事件处理程序提高程序性能。
/**
- 跨浏览器事件处理工具。只支持冒泡。不支持捕获
- @author (qiu_deqing@)
*/
var EventUtil = {
getEvent: function (event) {
return event || ;
},
getTarget: function (event) {
return || ;
},
// 返回注册成功的监听器,IE 中需要使用返回值来移除监听器
on: function (elem, type, handler) { if () {
(type, handler, false); return handler;
} else if () { var wrapper = function () {
var event = ; = ;
(elem, event);
};
('on' + type, wrapper); return wrapper;
}
},
off: function (elem, type, handler) { if () {
(type, handler, false);
} else if () { ('on' + type, handler);
}
},
preventDefault: function (event) { if () {
();
} else if ('returnValue' in event) { = false;
}
},
stopPropagation: function (event) { if () {
();
} else if ('cancelBubble' in event) { = true;
}
}
};
421.
[问答题]
评价一下三种方法实现继承的优缺点,并改进
function Shape() {} function Rect() {}
// 方法 1
= new Shape();
// 方法 2
= ;
// 方法 3
= (); = function () {
// do something
};
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
方法 1:
优点:正确设置原型链实现继承
优点:父类实例属性得到继承,原型链查找效率提高,也能为一些属性提供合理的默认
值
缺点:父类实例属性为引用类型时,不恰当地修改会导致所有子类被修改
缺点:创建父类实例作为子类原型时,可能无法确定构造函数需要的合理参数,这样提
供的参数继承给子类没有实际意义,当子类需要这些参数时应该在构造函数中进行初始化和设置
总结:继承应该是继承方法而不是属性,为子类设置父类实例属性应该是通过在子类构造函数中调用父类构造函数进行初始化
方法 2:
优点:正确设置原型链实现继承
缺点:父类构造函数原型与子类相同。修改子类原型添加方法会修改父类方法 3:
优点:正确设置原型链且避免方法 1.2 中的缺点缺点:ES5 方法需要注意兼容性
改进:
所有三种方法应该在子类构造函数中调用父类构造函数实现实例属性初始化
function Rect() {
(this);
}
用新创建的对象替代子类默认原型,设置 = Rect;保证一致性第三种方法的 polyfill:
function create(obj) {
if () {
return (obj);
}
422.
}
function f() {}; = obj; return new f();
[问答题]
完成一个函数,接受数组作为参数,数组元素为整数或者数组,数组元素包含整数或数组,函数返回扁平化后的数组
如:[1, [2, [ [3, 4], 5], 6]] => [1, 2, 3, 4, 5, 6]
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
var data = [1, [2, [ [3, 4], 5], 6]];
function flat(data, result) { var i, d, len;
for (i = 0, len = ; i < len; ++i) { d = data[i];
if (typeof d === 'number') { (d);
} else {
flat(d, result);
}
}
}
var result = []; flat(data, result); (result);
423.
[问答题]
如何判断一个对象是否为数组
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
如果浏览器支持 ()可以直接判断否则需进行必要判断
/**
- 判断一个对象是否是数组,参数不是对象或者不是数组,返回 false
*
- @param {Object} arg 需要测试是否为数组的对象
- @return {Boolean} 传入参数是数组返回 true,否则返回 false
*/
function isArray(arg) {
if (typeof arg === 'object') {
return (arg) === '[object Array]';
}
424.
}
return false;
[问答题]
请评价以下代码并给出改进意见
if () {
var addListener = function (el, type, listener, useCapture) { (type, listener, useCapture);
};
}
else if () {
addListener = function (el, type, listener) { ('on' + type, function () {
(el);
});
};
}
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
作用:浏览器功能检测实现跨浏览器 DOM 事件绑定优点:
测试代码只运行一次,根据浏览器确定绑定方法
通过 (el)解决 IE 下监听器 this 与标准不一致的地方
在浏览器不支持的情况下提供简单的功能,在标准浏览器中提供捕获功能缺点:
作为 IE 检测不可靠,应该使用 if() addListener 在不同浏览器下 API 不一样
使 this 与标准一致但监听器无法移除未解决 IE 下 listener 参数event。 target 问题
改进:
var addListener;
if () {
addListener = function (el, type, listener, useCapture) { (type, listener, useCapture); return listener;
};
}
else if () {
addListener = function (el, type, listener) {
// 标准化 this,event,target var wrapper = function () {
var event = ; = ; (el, event);
};
};
}
425.
('on' + type, wrapper); return wrapper;
// 返回 wrapper。调用者可以保存,以后 remove
[问答题]
如何判断一个对象是否为函数
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
/**
- 判断对象是否为函数,如果当前运行环境对可调用对象(如正则表达式)
- 的 typeof 返回'function',采用通用方法,否则采用优化方法
*
- @param {Any} arg 需要检测是否为函数的对象
- @return {boolean} 如果参数是函数,返回 true,否则 false
*/
function isFunction(arg) { if (arg) {
if (typeof (/./) !== 'function') {
return typeof arg === 'function';
} else {
return (arg) === '[object Function]';
}
426.
}
} // end if return false;
[问答题]
编写一个函数接受 url 中 query string 为参数,返回解析后的 Object,query string 使用
application/x-www-form-urlencoded 编码
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
/**
- 解析 query string 转换为对象,一个key 有多个值时生成数组
*
- @param {String} query 需要解析的 query 字符串,开头可以是?,
- 按照 application/x-www-form-urlencoded 编码
- @return {Object} 参数解析后的对象
*/
function parseQuery(query) { var result = {};
// 如果不是字符串返回空对象
if (typeof query !== 'string') { return result;
}
// 去掉字符串开头可能带的? if ((0) === '?') {
query = (1);
}
var pairs = ('&'); var pair;
var key, value; var i, len;
for (i = 0, len = ; i < len; ++i) { pair = pairs[i].split('=');
// application/x-www-form-urlencoded 编码会将' '转换为+ key = decodeURIComponent(pair[0]).replace(/\+/g, ' '); value = decodeURIComponent(pair[1]).replace(/\+/g, ' ');
// 如果是新 key,直接添加if (!(key in result)) {
result[key] = value;
}
// 如果 key 已经出现一次以上,直接向数组添加 value else if (isArray(result[key])) {
result[key].push(value);
}
// key 第二次出现,将结果改为数组
else {
var arr = [result[key]]; (value); result[key] = arr;
} // end if-else
} // end for return result;
}
function isArray(arg) {
if (arg && typeof arg === 'object') {
return (arg) === '[object Array]';
}
return false;
}
/**
(parseQuery('sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8'));
*/
427.
[问答题]
解析一个完整的 url,返回 Object 包含域与 相同
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
/**
- 解析一个 url 并生成 对象中包含的域
- location:
* {
- href: '包含完整的 url',
- origin: '包含协议到 pathname 之前的内容',
- protocol: 'url 使用的协议,包含末尾的:',
- username: '用户名', // 暂时不支持
- password: '密码', // 暂时不支持
- host: '完整主机名,包含:和端口',
- hostname: '主机名,不包含端口'
- port: '端口号',
- pathname: '服务器*问资源的路径/开头',
- search: 'query string,?开头',
- hash: '#开头的 fragment identifier'
* }
*
- @param {string} url 需要解析的 url
- @return {Object} 包含 url 信息的对象
*/
function parseUrl(url) { var result = {};
var keys = ['href', 'origin', 'protocol', 'host',
'hostname', 'port', 'pathname', 'search', 'hash'];
var i, len;
var regexp = /(([^:]+:)\/\/(([^:\/\?#]+)(:\d+)?))(\/[^?#]*)?(\?[^#]*)?(#.*)?/; var match = (url);
if (match) {
for (i = - 1; i >= 0; --i) {
result[keys[i]] = match[i] ? match[i] : '';
}
}
return result;
}
428.
[问答题]
完成函数 getScrollOffset 返回窗口滚动条偏移量
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
/**
- 获取指定 window 中滚动条的偏移量,如未指定则获取当前window
- 滚动条偏移量
*
- @param {window} w 需要获取滚动条偏移量的窗口
- @return {Object} 为水平滚动条偏移量, 为竖直滚动条偏移量
*/
function getScrollOffset(w) { w = w || window;
// 如果是标准浏览器
if ( != null) { return {
x: , y:
};
}
// 老版本 IE,根据兼容性不同访问不同元素var d = ;
if ( === 'CSS1Compat') { return {
x: , y:
}
}
return {
x: , y:
};
}
429.
[问答题]
现有一个字符串 richText,是一段富文本,需要显示在页面上。有个要求,需要给其中只包含一个 img 元素的 p 标签增加一个叫 pic 的 class。请编写代码实现。可以使用 jQuery 或 KISSY。
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
function richText(text) {
var div = ('div'); = text;
var p = ('p'); var i, len;
for (i = 0, len = ; i < len; ++i) {
if (p[i].getElementsByTagName('img').length === 1) { p[i].('pic');
}
}
return ;
}
430.
[问答题]
请实现一个 Event 类,继承自此类的对象都会拥有两个方法 on 和 trigger
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
431.
[问答题]
编写一个函数将列表子元素顺序反转
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
<ul >
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var target = ('target'); var i;
var frag = ();
for (i = - 1; i >= 0; --i) { ([i]);
}
(frag);
</script>
432.
[问答题]
以下函数的作用是?空白区域应该填写什么
// define
(function (window) { function fn(str) {
= str;
}
= function () { var arg = 1 ;
return ( 2 , function (a, b) { return arg[b] || '';
});
};
= fn;
})(window);
// use (function () {
var t = new fn('<p><a href="{0}">{1}</a><span>{2}</span></p>'); (('', 'Alibaba', 'Welcome'));
})();
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
define 部分定义一个简单的模板类,使用{}作为转义标记,中间的数字表示替换目标,
format 实参用来替换模板内标记
横线处填:
(arguments, 0)
/\{\s*(\d+)\s*\}/g
433.
[问答题]
编写一个函数实现 form 的序列化(即将一个表单中的键值序列化为可提交的字符串)
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
/**
- 将一个表单元素序列化为可提交的字符串
*
- @param {FormElement} form 需要序列化的表单元素
- @return {string} 表单序列化后的字符串
*/
function serializeForm(form) {
if (!form || () !== 'FORM') { return;
}
var result = []; var i, len;
var field, fieldName, fieldType;
for (i = 0, len = ; i < len; ++i) { field = [i];
fieldName = ; fieldType = ;
if ( || !fieldName) { continue;
} // enf if
switch (fieldType) { case 'text':
case 'password':
case 'hidden':
case 'textarea': (encodeURIComponent(fieldName) + '=' +
encodeURIComponent()); break;
case 'radio':
case 'checkbox':
if () { (encodeURIComponent(fieldName) + '=' +
encodeURIComponent());
}
break;
case 'select-one':
case 'select-multiple':
for (var j = 0, jLen = ; j < jLen; ++j) { if ([j].selected) {
(encodeURIComponent(fieldName) + '=' + encodeURIComponent([j].value || [j].text));
}
} // end for break;
case 'file':
case 'submit':
break; // 是否处理?
default:
break;
} // end switch
} // end for
return ('&');
}
434.
[问答题]
使用原生javascript 给下面列表中的li 节点绑定点击事件,点击时创建一个Object 对象, 兼容 IE 和标准浏览器
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
<ul >
<li><a href="http://11111">111</a></li>
<li><a href="http://2222">222</a></li>
<li><a href="http://333">333</a></li>
<li><a href="http://444">444</a></li>
</ul>
Object:
{
"index": 1,
"name": "111", "link": "http://1111"
}
script:
var EventUtil = {
getEvent: function (event) {
return event || ;
},
getTarget: function (event) {
return || ;
},
// 返回注册成功的监听器,IE 中需要使用返回值来移除监听器
on: function (elem, type, handler) { if () {
(type, handler, false); return handler;
} else if () { function wrapper(event) {
return (elem, event);
};
('on' + type, wrapper); return wrapper;
}
},
off: function (elem, type, handler) { if () {
(type, handler, false);
} else if () { ('on' + type, handler);
}
},
preventDefault: function (event) { if () {
();
} else if ('returnValue' in event) { = false;
}
},
stopPropagation: function (event) { if () {
();
} else if ('cancelBubble' in event) { = true;
}
}
};
var DOMUtil = {
text: function (elem) {
if ('textContent' in elem) { return ;
} else if ('innerText' in elem) { return ;
}
},
prop: function (elem, propName) {
return (propName);
}
};
var nav = ('nav');
(nav, 'click', function (event) { var event = (event); var target = (event);
var children = ; var i, len;
var anchor; var obj = {};
for (i = 0, len = ; i < len; ++i) { if (children[i] === target) {
= i + 1;
anchor = ('a')[0]; = (anchor);
= (anchor, 'href');
}
}
});
alert('index: ' + + ' name: ' + + ' link: ' + );
435.
[问答题]
有一个大数组,var a = ['1', '2', '3', ...]; a 的长度是 100,内容填充随机整数的字符串。请先构造此数组a,然后设计一个算法将其内容去重
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:无
/**
* 数组去重
**/
function normalize(arr) {
if (arr && (arr)) { var i, len, map = {};
for (i = ; i >= 0; --i) { if (arr[i] in map) {
(i, 1);
} else {
map[arr[i]] = true;
}
}
}
return arr;
}
/**
* 用 100 个随机整数对应的字符串填充数组。
**/
function fillArray(arr, start, end) {
start = start == undefined ? 1 : start; end = end == undefined ? 100 : end;
if (end <= start) {
end = start + 100;
}
var width = end - start; var i;
for (i = 100; i >= 1; --i) {
('' + ((() * width) + start));
}
return arr;
}
var input = []; fillArray(input, 1, 100); (function (a, b) {
return a - b;
});
(input);
normalize(input); (input);
436.
[谈话题]
前端是庞大的,包括 HTML、CSS、Javascript、Image、Flash 等等各种各样的资源。前端优化是复杂的,针对方方面面的资源都有不同的方式。随便聊聊有关优化方面的技术话题。
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试题参考:
前端优化的目的是什么?
-
- 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时, 能够给用户提供更为友好的体验。
- 从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。
总之,恰当的优化不仅能够改善站点的用户体验并且能够节省相当的资源利用。前端优化的途径有很多,按粒度大致可以分为两类,第一类是页面级别的优化,例
如 HTTP 请求数、脚本的无阻塞加载、内联脚本的位置优化等;第二类则是代码级别的优化, 例如 Javascript 中的 DOM 操作优化、CSS 选择符优化、图片优化以及 HTML 结构优化等等。另外,本着提高投入产出比的目的,后文提到的各种优化策略大致按照投入产出比从大到小的顺序排列。
一、页面级优化
- 减少 HTTP 请求数
这条策略基本上所有前端人都知道,而且也是最重要最有效的。都说要减少 HTTP 请求,那请求多了到底会怎么样呢?首先,每个请求都是有成本的,既包含时间成本也包含 资源成本。一个完整的请求都需要经过 DNS 寻址、与服务器建立连接、发送数据、等待服务器响应、接收数据这样一个“漫长”而复杂的过程。时间成本就是用户需要看到或者“感 受”到这个资源是必须要等待这个过程结束的,资源上由于每个请求都需要携带数据,因此 每个请求都需要占用带宽。另外,由于浏览器进行并发请求的请求数是有上限的(具体参见 此处),因此请求数多了以后,浏览器需要分批进行请求,因此会增加用户的等待时间,会 给用户造成站点速度慢这样一个印象,即使可能用户能看到的第一屏的资源都已经请求完了, 但是浏览器的进度条会一直存在。
减少 HTTP 请求数的主要途径包括:
- 从设计实现层面简化页面
如果你的页面像百度首页一样简单,那么接下来的规则基本上都用不着了。保持页面简洁、减少资源的使用时最直接的。如果不是这样,你的页面需要华丽的皮肤,则继续阅读下面的内容。
- 合理设置 HTTP 缓存
缓存的力量是强大的,恰当的缓存设置可以大大的减少 HTTP 请求。以有啊首页为例,当浏览器没有缓存的时候访问一共会发出 78 个请求,共 600 多K 数据(如图 1.1),而当第二次访问即浏览器已缓存之后访问则仅有 10 个请求,共 20 多 K 数据(如图 1.2)。(这里需要说明的是,如果直接 F5 刷新页面的话效果是不一样的,这种情况下请求数还是一样,不过被缓存资源的请求服务器是 304 响应,只有 Header 没有Body,可以节省带宽)
怎样才算合理设置?原则很简单,能缓存越多越好,能缓存越久越好。例如,很少变化的图片资源可以直接通过 HTTP Header 中的 Expires 设置一个很长的过期头;变化不频繁而又可能会变的资源可以使用 Last-Modifed 来做请求验证。尽可能的让资源能够在缓存中待得更久。关于 HTTP 缓存的具体设置和原理此处就不再详述了,有兴趣的可以参考下列文章:
HTTP1.1 协议中关于缓存策略的描述Fiddler HTTP Performance 中关于缓存的介绍(3). 资源合并与压缩
如果可以的话,尽可能的将外部的脚本、样式进行合并,多个合为一个。另外,CSS、
Javascript、Image 都可以用相应的工具进行压缩,压缩后往往能省下不少空间。
- CSS Sprites
合并 CSS 图片,减少请求数的又一个好办法。
- Inline Images
使用 data: URL scheme 的方式将图片嵌入到页面或 CSS 中,如果不考虑资源管理上的问题的话,不失为一个好办法。如果是嵌入页面的话换来的是增大了页面的体积,而且无法利用浏览器缓存。使用在 CSS 中的图片则更为理想一些。
- Lazy Load Images
这条策略实际上并不一定能减少 HTTP 请求数,但是却能在某些条件下或者页面刚加载时减少HTTP 请求数。对于图片而言,在页面刚加载的时候可以只加载第一屏,当用户继续往后滚屏的时候才加载后续的图片。这样一来,假如用户只对第一屏的内容感兴趣时, 那剩余的图片请求就都节省了。有啊首页曾经的做法是在加载的时候把第一屏之后的图片地址缓存在 Textarea 标签中,待用户往下滚屏的时候才“惰性”加载。
- 将外部脚本置底
前文有谈到,浏览器是可以并发请求的,这一特点使得其能够更快的加载资源,然而外链脚本在加载时却会阻塞其他资源,例如在脚本加载完成之前,它后面的图片、样式以及其他脚本都处于阻塞状态,直到脚本加载完成后才会开始加载。如果将脚本放在比较靠前的位置,则会影响整个页面的加载速度从而影响用户体验。解决这一问题的方法有很多,在这里有比较详细的介绍(这里是译文和更详细的例子),而最简单可依赖的方法就是将脚本尽可能的往后挪,减少对并发下载的影响。
- 异步执行 inline 脚本
inline 脚本对性能的影响与外部脚本相比,是有过之而无不及。首页,与外部脚本一样,inline 脚本在执行的时候一样会阻塞并发请求,除此之外,由于浏览器在页面处理方面是单线程的,当inline 脚本在页面渲染之前执行时,页面的渲染工作则会被推迟。简而言之,inline 脚本在执行的时候,页面处于空白状态。鉴于以上两点原因,建议将执行时间较长的 inline 脚本异步执行,异步的方式有很多种,例如使用 script 元素的 defer 属性(存在兼
容性问题和其他一些问题,例如不能使用 )、使用 setTimeout,此外,在 HTML5
中引入了 Web Workers 的机制,恰恰可以解决此类问题。
- Lazy Load Javascript
随着 Javascript 框架的流行,越来越多的站点也使用起了框架。不过,一个框架往往包括了很多的功能实现,这些功能并不是每一个页面都需要的,如果下载了不需要的脚本则算得上是一种资源浪费-既浪费了带宽又浪费了执行花费的时间。目前的做法大概有两种, 一种是为那些流量特别大的页面专门定制一个专用的 mini 版框架,另一种则是 Lazy Load。YUI 则使用了第二种方式,在 YUI 的实现中,最初只加载核心模块,其他模块可以等到需要使用的时候才加载。
- 将 CSS 放在 HEAD 中
如果将 CSS 放在其他地方比如BODY 中,则浏览器有可能还未下载和解析到 CSS 就已经开始渲染页面了,这就导致页面由无 CSS 状态跳转到 CSS 状态,用户体验比较糟糕。除此之外,有些浏览器会在 CSS 下载完成后才开始渲染页面,如果 CSS 放在靠下的位置则会导致浏览器将渲染时间推迟。
- 异步请求 Callback
在某些页面中可能存在这样一种需求,需要使用 script 标签来异步的请求数据。类
似:
Javascript:
/*Callback 函 数 */ function myCallback(info){
//do something here
}
HTML:
<script type="text/javascript" src="/cb"></script> cb 返回的内容:
myCallback('Hello world!');
像以上这种方式直接在页面上写<script>对页面的性能也是有影响的,即增加了页面首次加载的负担,推迟了 DOMLoaded 和 事件的触发时机。如果时效性允许的话,可以考虑在 DOMLoaded 事件触发的时候加载,或者使用 setTimeout 方式来灵活的控制加载的时机。
- 减少不必要的 HTTP 跳转
对于以目录形式访问的 HTTP 链接,很多人都会忽略链接最后是否带’/',假如你的服务器对此是区别对待的话,那么你也需要注意,这其中很可能隐藏了 301 跳转,增加了多余请求。具体参见下图,其中第一个链接是以无’/'结尾的方式访问的,于是服务器有了一次跳转。
- 避免重复的资源请求
这种情况主要是由于疏忽或页面由多个模块拼接而成,然后每个模块中请求了同样的资源时,会导致资源的重复请求
二、代码级优化
- Javascript (1). DOM
DOM 操作应该是脚本中最耗性能的一类操作,例如增加、修改、删除 DOM 元素或者对 DOM 集合进行操作。如果脚本中包含了大量的 DOM 操作则需要注意以下几点:
- HTML Collection
在脚本中 、、getElementsByTagName()返回的都是HTMLCollection 类型的集合,在平时使用的时候大多将它作为数组来使用,因为它有 length 属性,也可以使用索引访问每一个元素。不过在访问性能上则比数组要差很多,原因是这个集合并不是一个静态的结果,它表示的仅仅是一个特定的查询,每次访问该集合时都会重新执行这个查询从而更新查询结果。所谓的“访问集合”包括读取集合的 length 属性、访问集合中的元素。
因此,当你需要遍历 HTML Collection 的时候,尽量将它转为数组后再访问,以提高性能。即使不转换为数组,也请尽可能少的访问它,例如在遍历的时候可以将 length 属性、成员保存到局部变量后再使用局部变量。
- Reflow & Repaint
除了上面一点之外,DOM 操作还需要考虑浏览器的 Reflow 和 Repaint,因为这些都是需要消耗资源的,具体的可以参加以下文章:
如 何 减 少 浏 览 器 的 repaint 和 reflow? Understanding Internet Explorer Rendering Behaviour Notes on HTML Reflow
- 慎用 with
with(obj){ p = 1}; 代码块的行为实际上是修改了代码块中的执行环境,将 obj 放在了其作用域链的最前端,在 with 代码块中访问非局部变量是都是先从 obj 上开始查找, 如果没有再依次按作用域链向上查找,因此使用 with 相当于增加了作用域链长度。而每次查找作用域链都是要消耗时间的,过长的作用域链会导致查找性能下降。
因此,除非你能肯定在 with 代码中只访问 obj 中的属性,否则慎用 with,替代的可以使用局部变量缓存需要访问的属性。
- 避免使用eval 和Function
每次 eval 或 Function 构造函数作用于字符串表示的源代码时,脚本引擎都需要将源代码转换成可执行代码。这是很消耗资源的操作 —— 通常比简单的函数调用慢 100 倍以上。
eval 函数效率特别低,由于事先无法知晓传给 eval 的字符串中的内容,eval 在其上下文中解释要处理的代码,也就是说编译器无法优化上下文,因此只能有浏览器在运行时解释代码。这对性能影响很大。
Function 构造函数比 eval 略好,因为使用此代码不会影响周围代码;但其速度仍很
慢。
此外,使用 eval 和 Function 也不利于 Javascript 压缩工具执行压缩。
- 减少作用域链查找
前文谈到了作用域链查找问题,这一点在循环中是尤其需要注意的问题。如果在循
环中需要访问非本作用域下的变量时请在遍历之前用局部变量缓存该变量,并在遍历结束后再重写那个变量,这一点对全局变量尤其重要,因为全局变量处于作用域链的最顶端,访问时的查找次数是最多的。
低效率的写法:
//全局变量
var globalVar = 1;
function myCallback(info){ for( var i = 100000; i--;){
//每次访问 globalVar 都需要查找到作用域链最顶端,本例中需要访问 100000 次
globalVar += i;
}
}
更高效的写法:
//全局变量
var globalVar = 1;
function myCallback(info){
//局部变量缓存全局变量var localVar = globalVar; for( var i = 100000; i--;){
//访问局部变量是最快的localVar += i;
}
//本例中只需要访问 2 次全局变量
globalVar = localVar;
}
此外,要减少作用域链查找还应该减少闭包的使用。
- 数据访问
Javascript 中的数据访问包括直接量(字符串、正则表达式)、变量、对象属性以及数
组,其中对直接量和局部变量的访问是最快的,对对象属性以及数组的访问需要更大的开销。当出现以下情况时,建议将数据放入局部变量:
- 对任何对象属性的访问超过 1 次
- 对任何数组成员的访问次数超过 1 次
另外,还应当尽可能的减少对对象以及数组深度查找。
- 字符串拼接
在 Javascript 中使用"+"号来拼接字符串效率是比较低的,因为每次运行都会开辟新的内存并生成新的字符串变量,然后将拼接结果赋值给新变量。与之相比更为高效的做法是使用数组的 join 方法,即将需要拼接的字符串放在数组中最后调用其 join 方法得到结果。不过由于使用数组也有一定的开销,因此当需要拼接的字符串较多的时候可以考虑用此方法。
关于 Javascript 优化的更详细介绍请参考:
Write Efficient Javascript(PPT) Efficient JavaScript
- CSS 选择符
在大多数人的观念中,都觉得浏览器对 CSS 选择符的解析式从左往右进行的,例如
#toc A { color: #444; }
这样一个选择符,如果是从右往左解析则效率会很高,因为第一个 ID 选择基本上就把查找的范围限定了,但实际上浏览器对选择符的解析是从右往左进行的。如上面的选择符,浏览器必须遍历查找每一个 A 标签的祖先节点,效率并不像之前想象的那样高。根据浏览器的这一行为特点,在写选择符的时候需要注意很多事项,有人已经一一列举了,详情参考此处。
- HTML
对 HTML 本身的优化现如今也越来越多的受人关注了,详情可以参见这篇总结性文
章。
- Image 压缩
图片压缩是个技术活,不过现如今这方面的工具也非常多,压缩之后往往能带来不
错的效果,具体的压缩原理以及方法在《Even Faster Web Sites》第 10 章有很详细的介绍, 有兴趣的可以去看看。
总结
上面从页面级以及代码级两个粒度对前端优化的各种方式做了一个总结,这些方法基本上都是前端开发人员在开发的过程中可以借鉴和实践的,除此之外,完整的前端优化还应该包括很多其他的途径,例如 CDN、Gzip、多域名、无 Cookie 服务器等等,由于对于开发人员的可操作性并不强大,在此也就不多叙述了,详细的可以参考 Yahoo 和 Google 的网站优化。
437.
[谈话题]
简单说说 Javascript 的历史。
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
HTML 是纯静态的的页面,而 Javascript 让页面有了动态的效果,比如;OA 中模块的拖拉所有的浏览器都会内置 Javascript 的解释器
1992 年 Nombas 公司开发出 C 减减的嵌入式脚本语言。这是最好的 HTML 页面的脚本语言。
Netscape 为了扩展其浏览器的功能,开发了一套 LiveScript,并与 1995 年与 SUN 公司联合把其改名为 javascript,它的主要目的是处理一些输入的有效性验证,而之前这个工作是留给 perl 之类的服务器端语言完成,在以前使用电话线调制解调器(28.8kb/s)的时代,如此慢的与服务器交互,这绝对是一件很痛苦的事情。Javascript 的出现,解决了这个问题,因为它的验证是基于客户端的。
微软公司早期版本的浏览器仅支持自己的 vbscript,但后来不得不加入 javascript IE3 中搭载 Javascipt 的克隆版本,命名为 jscript
在一次技术会议中,sun,microsoft,netscape 公司联合制定了ECMA-Script 标准
在 2005 前,网页上提示框,广告越来越多,把 javascipt 滥用,使 javascript 背上了大量的罪名。
2005 年,google 公司的网上产品(google 地图,gmail,google 搜索建议)等使得 ajax
兴起,而 javascript 便是 ajax 最重要的元素之一
Javascript 有三个部分组成ECMAScript DOM BOM WEB 标准
网页主要有三部分组成
(结构 HTML,XHTML,表现 CSS,行为 DOM,ECMA)
438.
[思考题]
Javascript 的基本语法
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
- 区分大小写
- 弱类型变量 var age=10 var name=”dd”
- 每行结尾的分号可有可无,但建议还是加上
- 注释与 java 相同变量
变量是通过 var 关键字来声明的。(Variable) 变量的命名规则与 java 一致
注释有三种:// /**/ <!-- --> 这个只能注释单行
439.
[比较题]
slice()、substring()、subtr
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
Slice 和 substring (2,5) 指的是从第 3 为开始,取(5-2)=3 个数,其中 slice 的参数可以为负
Substr(2,5)指的是从第 3 为开始,取 5 个数。但 ECMAscript 没有对该方法进行标准化,因此尽量少使用该方法
440.
[比较题]
indexOf()和 lastIndexOf(),isNan,typeOf
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
indexOf(”i”) //从前往后,i 在第几位 indexOf(”i”,3)可选参数,从第几个字符开始往后找lastIndexOf(”i”) //从后往前,i 在第几位 lastIndexOf (”i”,3) //从后往前,i 在第几位
如果没找到,则返回-1
String 类型的变量,在 Java 中,用“”符号表示字符串,用’’表示单个字符。而在 javascript
中这两种都可以
Nan(not a number)
Alert(nan ==nan)返回 false,因此不推荐使用 nan 本身,推荐函数isNan
Alert(isNanN(“ab”));//返回 false typeof 运算符
var stmp = “test”;
alert(typeof stmp); //输出 string alert(type of 1);//输出 number
此外:还有 boolean,undefined,object(如果是引用类型或者 null 值,null 值返回 object,这其实是 ecmascript 的一个错误)
当声明的变量未初始化的时候,它的值就是 undefined.当没有这个变量的时候,typeof
变
返回的值也是 undefined。但是没声明的变量是不能参与计算的。当函数无明确返回值时,返回的也是 undefined
Function a(){
}
Alert(a() == undefined) //返回 true Alert(null == undefined)//返回 true
441.
[技巧题]
数值计算
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
var mynum1 = 23.345; var mynum2 = 45;
var mynum3 = -34;
var mynum4 = 9e5; //科学计数法 为 9*10 五次方
var fNumber = 123.456;
alert((1));//保留的小数点数 1.2e+2 alert((2));//1.23e+2
442.
[技巧题]
布尔值
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
var married = true;
alert("1." + typeof(married));//Boolean married = "true";
alert("2." + typeof(married));//String
443.
[技巧题]
类型转换
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
转换成 string 类型有三种方式
var a = 3;
var b = a + "";
var c = (); var d = "student" + a;
toString() var a=11;
((2) + "<br>");//转成 2 进制((3) + "<br>");//转成 3 进制如果不是数值,则转换报错
parseInt()
(parseInt("1red6") + "<br>");//返回 1,后面非数值的将全部忽略(parseInt("53.5") + "<br>");// 返 回 53 (parseInt("0xC") + "<br>"); // 直 接 十 进 制 转 换 12 (parseInt("isaacshun@") + "<br>");//NAN (parseInt("011",8) + "<br>"); 返 回 9 (parseInt("011",10) + "<br>"); //指定为十进制 返回 11 parseFloat()与 parseInt()类似
444.
[思考题]
数组
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
var aMap = new Array("China","USA","Britain"); aMap[20] = "Korea";
alert( + " " + aMap[10] + " " + aMap[20]);//aMap[10]返回 undefined (("][") + "<br>"); //用“][”来连接
var sFruit = "apple,pear,peach,orange";
var aFruit = (",");
var aFruit = ["apple","pear","peach","orange"]; alert(().toString());
var aFruit = ["pear","apple","peach","orange"]; ();
var stack = new Array(); ("red"); ("green"); ("blue");
(() + "<br>"); var vItem = (); // blue (vItem + "<br>");
(()); // red green
445.
[思考题] if 语句
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点用法提示:
//首先获取用户的一个输入,并用Number()强制转换为数字
var iNumber = Number(prompt("输入一个5 到100 之间的数字", ""));//第二个参数,用于显示输入框的默认值
if(isNaN(iNumber)) //判断输入的是否是数字 NaN “Not a Number” ("请确认你的输入正确");
else if(iNumber > 100 || iNumber < 5) //判断输入的数字范围("你输入的数字范围不在 5 和 100 之间");
else
("你输入的数字是:" + iNumber);
446.
[思考题] switch
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点用法提示:
iWeek = parseInt(prompt("输入 1 到 7 之间的整数","")); switch(iWeek){
case 1:
("Monday"); break;
case 2:
("Tuesday"); break;
case 3:
("Wednesday"); break;
case 4:
("Thursday"); break;
case 5:
("Friday"); break;
case 6:
("Saturday"); break;
case 7:
("Sunday"); break;
default:
("Error");
}
447.
[思考题] while 语句
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点用法提示:
var i=iSum=0; while(i<=100){
iSum += i; i++;
}
alert(iSum);
for break continue (与JAVA 语法一致)
448.
[思考题]
函数
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点用法提示:
function ArgsNum(){
return ;
}
(ArgsNum("isaac",25) + "<br>"); (ArgsNum() + "<br>"); (ArgsNum(3) + "<br>");
从这个例子可以看出,方法可以没有参数,也可以没有返回值,但是照样可以传入参数和返回值。
449.
[思考题] Date 对象
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
var myDate1 = new Date(); //运行代码前的时间for(var i=0;i<3000000;i++);
var myDate2 = new Date(); //运行代码后的时间(myDate2);
var oMyDate = new Date();
var iYear = ();
var iMonth = () + 1; //月份是从 0 开始的
var iDate = ();
var iDay = (); //0 为 星期日 1 为 星期一
function disDate(oDate, iDate){
var ms = (); //换成毫秒数
ms -= iDate*24*60*60*1000; //计算相差的毫秒数return new Date(ms); //返回新的时间对象
}
var oBeijing = new Date(2008,7,8);
var iNum = 100; //前 100 天
var oMyDate = disDate(oBeijing, iNum);
450.
[思考题]
检测浏览器和操作系统
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点提示:
var sUserAgent = ;
//检测 Opera、KHTML
var isOpera = ("Opera") > -1;
var isKHTML = ("KHTML") > -1 || ("Konqueror") > -1
|| ("AppleWebKit") > -1;
//检测 IE、Mozilla
var isIE = ("compatible") > -1 && ("MSIE") > -1 && !isOpera;
var isMoz = ("Gecko") > -1 && !isKHTML;
//检测操作系统
var isWin = ( == "Win32") || ( == "Windows");
var isMac = ( == "Mac68K") || ( == "MacPPC") || ( == "Macintosh");
var isUnix = ( == "X11") && !isWin && !isMac; if(isOpera) ("Opera ");
if(isKHTML) ("KHTML "); if(isIE) ("IE ");
if(isMoz) ("Mozilla "); if(isWin) ("Windows"); if(isMac) ("Mac"); if(isUnix) ("Unix");
451.
[思考题] Global 对象
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点重点提示:
其实 isNan,paraseInt 等都是 Global 对象的方法
EncodeURI.因为有效的 URI 不能包含某些字符,如空格。这个方法就是用于将这个字符转换成 UTF-8 编码,使浏览器可以接受他们。
Var suil = “/pro file/”; Alert(encodeURI(suil));//www.os/pro%20file/
即将空格编码成%20 Eval 方法
Eval(“alert(‘hi’)”);
当解析程序发现 eval()时,它将把参数解析成真正的 ECMA-script 语句,然后插入该语句所在位置。
Global 除了有内置方法外,还有很多内置的属性:如:undefined,nan,Array,String,Number,
Date,RegExp 等
452.
[思考题] Math 对象
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点提示:
Max 方法,min 方法,ceil,floor,round,sqrt,random Max(1,2,3);min(1.2,3.4);
想取到 1~10 的数据(()*10+1) 2~9 的数据(()*9+2);
453.
[ 思 考 题 ] getElementsByTagName
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点提示:
function searchDOM(){
//放在函数内,页面加载完成后才用<body>的 onload 加载,这时如果把 alert 这句改成用 则会把原内容覆盖掉,因为是后面才执行的
var oLi = ("li");
//输出长度、标签名称以及某项的文本节点值
alert( + " " +oLi[0].tagName + " " + oLi[3].childNodes[0].nodeValue);
var oUl = ("ul"); var oLi2 = oUl[1].getElementsByTagName("li");
alert( + " " +oLi2[0].tagName + " " + oLi2[1].childNodes[0].nodeValue);
}
<body οnlοad="searchDOM()">
<ul>客户端语言
<li>HTML</li>
<li>JavaScript</li>
<li >CSS</li>
</ul>
<ul>服务器端语言
<li></li>
<li>JSP</li>
<li>PHP</li>
</ul>
</body>
454.
[ 思 考 题 ] getElementById
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点提示:
var oLi = ("cssLi"); .backgroundColor="yellow"
//输出标签名称以及文本节点值
alert( + " " + [0].nodeValue);
455.
[ 思 考 题 ] getElementsByName
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点提示:
alert(("a").length);
456.
[技巧题]
访问子节点
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点
参考:
function myDOMInspector(){
var oUl = ("myList"); //获取<ul>标记var DOMString = "";
if(()){ //判断是否有子节点var oCh = ;
for(var i=0;i<;i++) //逐一查找DOMString += oCh[i].nodeName + "\n";
}
457.
}
alert(DOMString);
[技巧题]
访问父节点
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
nodeName 如果为文本节点,则返回#text tagName 如果为文本节点,则返回 undefined function myDOMInspector(){
var myItem = ("myDearFood"); alert();
}
function myDOMInspector(){
var myItem = ("myDearFood"); var parentElm = ;
while( != "colorful" && parentElm != ) parentElm = ; //一路往上找
alert();
}
<body οnlοad="myDOMInspector()">
<div class="colorful">
<ul>
<li>糖醋排骨</li>
<li>圆笼粉蒸肉</li>
<li>泡菜鱼</li>
<li >板栗烧鸡</li>
<li>麻婆豆腐</li>
</ul>
</div>
</body>
458.
[技巧题]
访问兄弟节点
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
function myDOMInspector(){
var myItem = ("myDearFood");
//访问兄弟节点
var nextListItem = ; var preListItem = ;
alert( +" "+ );
}
在 Firefox 中不支持,但是 IE 中却是支持的。
459.
[技巧题]
第一个 最后一个 子节点
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
function nextSib(node){
var tempLast = ;
//判断是否是最后一个节点,如果是则返回 null if(node == tempLast)
return null;
var tempObj = ;
//逐一搜索后面的兄弟节点,直到发现元素节点为止while(!=1 && !=null)
tempObj = ;
//三目运算符,如果是元素节点则返回节点本身,否则返回 null return (==1)?tempObj:null;
}
function prevSib(node){
var tempFirst = ;
//判断是否是第一个节点,如果是则返回 null if(node == tempFirst)
return null;
var tempObj = ;
//逐一搜索前面的兄弟节点,直到发现元素节点为止while(!=1 && !=null)
tempObj = ; return (==1)?tempObj:null;
}
function myDOMInspector(){
var myItem = ("myDearFood");
//获取后一个元素兄弟节点
var nextListItem = nextSib(myItem);
//获取前一个元素兄弟节点
var preListItem = prevSib(myItem);
alert("后一项:" + ((nextListItem!=null)?:null) + " 前一项:" + ((preListItem!=null)?:null) );
}
460.
[思考题] nodeType
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
元素element 1
属性 attr 2
文本 text 3
注释 comments 8
文档 document 9 function showAttr(){
var btnShowAttr=("btnShowAttr"); //演示按钮,有很多属性var attrs=;
for(var i=0;i< ;i++){ var attr=attrs[i];
alert('nodeType:'+); //attribute 的 nodeType=2 alert('attr:'+attr);
alert(':'++'='+);
}
function showDocument(){ alert('nodeType:'+); //9 alert('nodeName:'+);
alert(document);
}
461.
[技巧题]
getAttribute setAttribute
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
function myDOMInspector(){
//获取图片
var myImg = ("img")[0];
//获取图片 title 属性
alert(("title"));
}
function changePic(){
//获取图片
var myImg = ("img")[0];
//设置图片 src 和 title 属性("src",""); ("title","紫荆公寓");
}
462.
[技巧题]
创建新节点
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
function createP(){
var op = ("p");
var otext = ("HHHHH"); (otext); ("style","text-align:center"); (op);
//创建完节点,就马上会影响到下面的操作,比如P 的数量就会多 1 个
}
463.
[技巧题]
删除节点
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
需要注意的是标签之间的父子关系!!!
function deleteP(){
var oP = ("p")[0]; (oP); //删除节点
}
464.
[技巧题]
替换节点
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
function replaceP(){
var oOldP = ("p")[0];
var oNewP = ("p"); //新建节点
var oText = ("这是一个感人肺腑的故事"); (oText); (oNewP,oOldP); //替换节点
}
465.
[技巧题]
插入节点
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
function insertP(){
var oOldP = ("p")[0];
var oNewP = ("p"); //新建节点
var oText = ("这是一个感人肺腑的故事");
(oText); (oNewP,oOldP); //插入节点
}
没有 insertAfter,但是可以自己写一个function insertAfter(newElement, targetElement){
var oParent = ; //首先找到目标元素的父元素if( == targetElement) //如果目标元素已经是最后一个子元素了
(newElement); //则直接用 appendChild()加到子元素列
表的最后
else //否则用insertBefore()插入到目标元素的下一个兄弟元素之前
(newElement,);
}
function insertP(){
var oOldP = ("myTarget");
var oNewP = ("p"); //新建节点
var oText = ("这是一个感人肺腑的故事"); (oText);
insertAfter(oNewP,oOldP); //插入节点
}
其实这个也是通过 insertBefore 原理来实现的
466.
[ 技 巧 题 ] cloneNode(deepBoolean)
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
复制并返回当前节点的复制节点,这个复制得到的节点是一个孤立的节点,不在document 树中。复制原来节点的属性值,包括 ID 属性,所以在把这个新节点加到 document之前,一定要修改 ID 属性,以便使它保持唯一。当然如果 ID 的唯一性不重要可以不做处理。这个方法支持一个布尔参数,当 deepBoolean 设置 true 时,复制 当前节点的所有子节
点,包括该节点内的文本。
<p id=”mypara”>11111</p> p=("mypara") pclone = (true); (pclone
467.
[技巧题]
文档碎片
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
function insertPs(){
var aColors = ["red","green","blue","magenta","yellow","chocolate","black","aquamarine","lime","fuchsia","br
ass","azure","brown","bronze","deeppink","aliceblue","gray","copper","coral","feldspar","orange ","orchid","pink","plum","quartz","purple"];
var oFragment = (); //创建文档碎片for(var i=0;i<;i++){
var oP = ("p");
var oText = (aColors[i]); (oText);
(oP); //将节点先添加到碎片中
}
468.
}
(oFragment); //最后一次性添加到页面
[技巧题] innerHTML
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
function myDOMInnerHTML(){
var myDiv = ("myTest"); alert(); //直接显示 innerHTML 的内容
//修改 innerHTML,可直接添加代码 = "<img src='' title='情人坡'>";
}
innerHTML 可同时显示没有的代码
469.
[问答题]
换皮肤
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点
参考:
<style type="text/css">
.myUL1{
color:#0000FF; font-family:Arial; font-weight:bold;
}
.myUL2{
color:#FF0000;
font-family:Georgia, "Times New Roman", Times, serif;
}
</style>
<script language="javascript"> function check(){
var oMy = ("ul")[0];
=(=="myUL1"? "myUL2":"myUL1"); //修改 CSS 类
}
</script>
</head>
<body>
<ul οnclick="check()" class="myUL1">
<li>HTML</li>
<li>JavaScript</li>
<li>CSS</li>
</ul>
</body>
470.
[技巧题]
动态添加行
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
<script language="javascript"> window.οnlοad=function(){
var oTr = ("member").insertRow(2); //插入一行var aText = new Array();
aText[0] = ("fresheggs"); aText[1] = ("W610"); aText[2] = ("Nov 5th"); aText[3] = ("Scorpio");
aText[4] = ("1038818"); for(var i=0;i<;i++){
var oTd = (i); (aText[i]);
}
}
</script>
471.
[技巧题]
修改单元格内容
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
<script language="javascript"> window.οnlοad=function(){
var oTable = ("member"); [3].cells[4].innerHTML = "lost"; //修改单元格内容
}
</script>
472.
[技巧题]
动态删除
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
parentElement 是 IE dom, parentNode 是标准 DOM
<script language="javascript"> window.οnlοad=function(){
var oTable = ("member");
(2); //删除一行,后面的行号自动补齐//指从 table 中的第 2
行开始进行删除
[2].deleteCell(1); //删除一个单元格,后面的也自动补齐
}
</script>
<script language="javascript"> function myDelete(){
var oTable = ("member");
//删除该行();
}
window.οnlοad=function(){
var oTable = ("member"); var oTd;
//动态添加 delete 链接
for(var i=1;i<;i++){ oTd = [i].insertCell(5);
= "<a href='#'>delete</a>"; = myDelete; //添加删除事件
}
}
</script>
473.
[技巧题]
动态删除列
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
<script language="javascript"> function deleteColumn(oTable,iNum){
//自定义删除列函数,即每行删除相应单元格for(var i=0;i<;i++)
[i].deleteCell(iNum);
}
window.οnlοad=function(){
var oTable = ("member"); deleteColumn(oTable,2);
}
</script>
474.
[技巧题]
控制 textarea 的字符个数
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
<script language="javascript"> function LessThan(oTextArea){
//返回文本框字符个数是否符号要求的 boolean 值
return < ("maxlength");
}
</script>
475.
[思考题] BOM 模型
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
浏览器对象模型,可以对浏览器窗口进行访问和操作,使用 BOM,开发者可以移动窗口, 改变状态栏中的文本等与页面内容不相关的操作
Window 对象
这里可以用 [0]或者用 [“topFrame”]来引用框架,也可以用 topl 来代替 window 属性。[0] 。window 对象可以忽略
提供的方法有 moveto,moveBy,resizeTo,resizeBy 等方法。但尽量避免使用它们,因为会对用户浏览产生影响
Open 方法
除了 open 方法,还有 alert,comfirm,prompt 方法状态栏
Settimeout 与 setInterval Settimeout
下面的代码都是在 1 秒钟后显示一条警告
Settimeout(“alert(‘aa’),1000”);
Settimeout(function(),alert(‘aa’);-,1000);
如果要还未执行的暂停,可调用 clearTimeOut()方法Var si = Settimeout(function(),alert(‘aa’);-,1000); clearTimeout(si);
setInterval History
向后一页(-1); 等于 ();
向前一页(1); 等于 (); Document
LastModified,title,URL 属性都是比较常用
Location 对象
Navigator 对象
Screen 对象
476.
[思考题]
冒泡型事件
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
<script language="javascript"> function add(sText){
var oDiv = ("display"); += sText; //输出点击顺序
}
</script>
</head>
<body οnclick="add('body<br>');">
<div οnclick="add('div<br>');">
<p οnclick="add('p<br>');">Click Me</p>
</div>
<div ></div>
</body>
先执行最里面的 p,再往外执行
477.
[思考题]
监听函数
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
<script language="javascript"> = function(){
var oP = ("myP"); //找到对象 = function(){ //设置事件监听函数
alert('我被点击了');
}
}
</script>
</head>
<body>
<div>
<p >Click Me</p>
</div>
</body>
Function a(){} = a
这样会先把 a 函数加载到缓存,不是最佳方案
Var A = Function(){} = a
这样只有在 onclick 事件发生的时候,加载该函数
若以上的监听函数,在 onclick 的时候,需要执行多个函数,那就只能用以下的方法:
IE 标准:
<script language="javascript"> function fnClick(){
alert("我被点击了");
("onclick",fnClick); //点击了一次后删除监听函数
}
var oP;//声明在函数外,这样就可以两个函数一起使用 = function(){
oP = ("myP"); //找到对象("onclick",fnClick); //添加监听函数
}
</script>
</head>
<body>
<div>
<p >Click Me</p>
</div>
</body>
也可以添加多个监听器
("onclick",fnClick1); //添加监听函数 1
("onclick",fnClick2); //添加监听函数 2
执行顺序为 fnClick2-> fnClick1
但是以上的监听器均为 IE 中的标准,而符合标准 DOM(firefox)的监听器如下("click",fnClick1,false); //添加监听函数 1
("click",fnClick2,false); //添加监听函数 2
因此这种方式在 Firefox 中支持,而在 IE 中不支持为了兼容性,可这样写
if (){
('click', KindDisableMenu, false);
} else if (){ ('onclick', KindDisableMenu);
}
第三个参数为 useCapture
而 useCapture 这个参数就是在控制这时候两个 click 事件的先后顺序。如果是 false,那就会使用 bubbling,他是从内而外的流程,所以会先执行蓝色元素的 click 事件再执行红色元素的 click 事件,如果是true,那就是 capture,和 bubbling 相反是由外而内
478.
[思考题]
事件的类型
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
IE 浏览器中事件对象是 window 对象的一个属性event =function(){ var o = }
而标准 DOM 中规定event 对象必须作为唯一的参数传给事件处理函数
Op.οnclick=function(oevent){
}
因此为了兼容两种浏览器,通常采用下面的方法
Op.οnclick=function(o){
If()//假如不等于空,则为 IE 浏览器
O = ;
}
<script language="javascript"> function handle(oEvent){
var oDiv = ("display");
if() oEvent = ; //处理兼容性,获得事件对象if( == "click") //检测事件名称
+= "你点击了我  "; else if( == "mouseover")
+= "你移动到我上方了  ";
}
= function(){
var oImg = ("img")[0]; = handle;
= handle;
}
</script>
还有很多鼠标事件
= function(){
}
479.
var oImg = ("img")[0]; = handle; //将鼠标事件除了 mousemove 外都监听 = handle;
= handle; = handle; = handle; = handle;
[思考题]
事件的激活元素 或者 target
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
<script language="javascript"> function handle(oEvent){
if() oEvent = ; //处理兼容性,获得事件对象var oTarget;
if() //处理兼容性,获取事件目标oTarget = ; //IE 支持的写法
else
oTarget = ; //Firefox 支持的写法
alert(); //弹出目标的标记名称
}
= function(){
var oImg = ("img")[0]; = handle;
}
</script>
<script language="javascript"> function TestClick(oEvent){
var oDiv = ("display"); if()
oEvent = ;
+= ; //输出 button 的值
}
= TestClick; = TestClick; //测试未按下任何键
</script>
</head>
<body>
<div ></div>
</body>
在 IE/Opera 中,是 ,而在 Firefox 中,是event
而事件的对象,在 IE 中是 ,在 Firefox 中是 ,而在Opera 中则两者都支持。
在 IE 里面
左键是 = 1 右键是 = 2 中键是 = 4
没有按键动作的时候 = 0
在 Firefox 里面
左键是 = 0 右键是 = 2 中键是 = 1
没有按键动作的时候 = 0
在 Opera 7.23/7.54 里面
鼠标左键是 = 1
没有按键动作的时候 = 1
右键和中键无法获取键盘事件
= function(){
var oTextArea = ("textarea")[0]; = handle; //监听所有键盘事件 = handle;
= handle;
}
;
onkeypress 是在用户按下并放开任何字母数字键时发生。系统按钮(例如,箭头键和功能键, Shift、Ctrl、Alt、F1、F2)无法得到识别。
onkeyup 是在用户放开任何先前按下的键盘键时发生。
onkeydown 是在用户按下任何键盘键(包括系统按钮,如箭头键和功能键)时发生屏蔽鼠标右键
第一种方式:
<script language="javascript"> function block(oEvent){
if()
oEvent = ; if( == 2)
alert("鼠标右键不可用");
}
= block;
</script>
第二种方式:
<script language="javascript"> function block(oEvent){
if(){
oEvent = ;
= false; //取消默认事件 支持 IE
}else
}
(); //取消默认事件 支持 Firefox
= block;
</script>
480.
[技巧题]
伸缩的菜单
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
<script language="javascript"> function change(){
//通过父元素 li,找到兄弟元素 ul
var oSecondDiv = ("ul")[0];//这里的 this 就是下面的 OA
//CSS 交替更换来实现显、隐
if( == "myHide") = "myShow";
else
}
= "myHide";
= function(){
var oUl = ("listUL"); var aLi = ; //子元素
var oA;
for(var i=0;i<;i++){
//如果子元素为 li,且这个 li 有子菜单 ul
if(aLi[i].tagName == "LI" && aLi[i].getElementsByTagName("ul").length){ oA = aLi[i].firstChild; //找到超链接
= change; //动态添加点击函数
}
}
}
</script>
481.
[思考题]
Event DOM 常用属性
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点提示:
tagName nodeValue nodeName nodeType parentNode childNodes firstChild lastChild nextSibling (IE)
previousSibling (IE) attributes innerHTML
style className
方 法 getElementById getElementsByName
getElementsByTagName hasChildNodes() getAttribute setAttribute createElement createTextNode appendChild removeChild replaceChild insertBefore
cloneNode createDocumentFragment detachEvent
attachEvent(IE) addEventListener(DOM) event 属性
type keyCode
srcElement(IE) target(DOM) button
鼠标事件onclick onmouseover onmousedown onmouseup onmouseout ondblclick
键盘事件onkeydown onkeyup onkeypress
window 事件
onload
document 事件oncontextmenu write onmousedown
482.
[思考题]
错误和异常
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
拼写错误、访问不存在的变量,括号不匹配,等号与赋值
声明变量时,要记住局部变量和全局变量的区别
Function square(num){ Total = num*num;
Return total;
}
Var total = 50;
Var number = Square(20); Alert(total);
这些代码将不可避免地导致全局变量 total 的值发生变化。
Function square(num){
Var Total = num*num; Return total;
}
483.
[思考题]
错误处理
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
onerror
<head>
<title>onerror</title>
<script language="javascript"> = function(){
alert("出错啦!");
return true; //屏蔽系统事件
}
</script>
</head>
<body οnlοad="nonExistent()">
</body>
Try..catch
<script language="javascript"> try{
alert("this is an example"); alert(fresheggs);
} catch(exception){ var sError = "";
for(var i in exception)
sError += i + ":" + exception[i] + "\n"; alert(sError);
}
</script>
484.
[思考题]
调试器
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
IE-工具-Intenet 选项-高级->禁用调试,显示脚本错误
Firefox 错误控制台Microsoft script debugger Venkman firefox 的插件
485.
[ 思 考 题 ] JavaScript 优化
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考知识点参考:
- 提高 JavaScript 下载时间。将JavaScript 写到同一行
- 尽量使用内置函数(因为内置函数是通过C 语言编译到浏览器中的)
.实例
1 图片查看器
<html>
<head>
<title></title>
<script>
function showPic(obj){
var h = ("href"); ("image").setAttribute("src",h);
}
</script>
</head>
<body>
<h1>Snapshots</h1>
<ul>
<li><a href="photo/" title="a" οnclick="showPic(this);return false;">01</a></li>
<li><a href="photo/" title="b" οnclick="showPic(this);return false;">02</a></li>
<li><a href="photo/" title="c" οnclick="showPic(this);return false;">03</a></li>
<li><a href="photo/" title="d" οnclick="showPic(this);return false;">04</a></li>
<li><a href="photo/" title="e" οnclick="showPic(this);return false;">05</a></li>
</ul>
<img src="photo/" alt="my image"></img>
</body>
</html>
Return false 指的是把默认的 noclick 事件取消给其加上 css
<style>
body{
color:#333; background:#ccc; margin:1em 10%;
}
a{
text-decoration:none; padding:10px; color:#c60;
}
a:link, a:visited{
color: #A62020; background-color: #ecd8db; text-decoration: none; padding:4px 10px 4px 10px;
border-top:1px solid #EEE; border-left:1px solid #EEE;
border-bottom:1px solid #717171;
border-right:1px solid #717171;
}
a:hover{
color:#821818; background-color:#e2c4c9; padding:5px 8px 3px 12px; border-top:1px solid #717171;
border-left:1px solid #717171; border-bottom:1px solid #EEE; border-right:1px solid #EEE;}
ul{
}
li{
}
img{
}
margin:0px; padding:0px;
list-style-type:none; display:inline;
margin:10px 0px;
</style>
当时现在有个缺陷,就是onclick 的事件直接写在了 HTML 上,分离先给 ul 加上个属性 id<ul id=”img_ul”>
= prepareGalley;
function prepareGalley(){
var img_ul = ("img_ul"); var links = img_ul.getElementsByTagName("a");
for(var i=0;i<;i++){ links[i].onclick = function(){
showPic(this); return false;
}
}
}
有一个问题,如果 onload 的函数有多个怎么办?
= prepareGalley1; = prepareGalley2;
显然,这样第一个函数就会被第二个函数覆盖。可以这样写
= function(){ prepareGalley1(); prepareGalley2();
}
还有一个比这个更NB 的写法,由 Simon Willison 写的
function addLoadEvent(func){
var oldonload = ; if(typeof !='function'){
= func;
}else{
= function(){ oldonload();
func();
}
}
}
addLoadEvent(prepareGalley1); addLoadEvent(prepareGalley2);
486.
[问答题]
编写一个方法 求一个字符串的字节长度
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
new function(s){
if(!||!s) return null; if(""==s) return 0;
var l=0;
for(var i=0;i<;i++){ if((i)>255) l+=2; else l++;
}
alert(l);
}("hello world!");
487.
[问答题]
如何控制 alert 中的换行
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参 考 : alert("hello\nworld");
488.
[问答题]
解释 ("ElementID").="1.5em"
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
设置 id 为 ElementID 的元素的字体大小为 1.5 个相对单位
Em 为相对长度单位。相对于当前对象内文本的字体尺寸。
如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
1em=16px
489.
[问答题]
按照格式 xxxx 年 xx 月 xx 日 xx 时 xx 分 xx 秒动态显示时间 要求不足 10 的补 0
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
<script type="text/javascript" language="javascript"> function tick(){
var d=new Date();
var t=function(a){return a<10?"0"+a:a;}
=()+" 年"+t(()+1)+" 月"+t(())+"
日"+t(())+"时"
+t(())+"分"+t(())+"秒"; ("tick()",1000);
}
window.οnlοad=tick;
</script>
<body>
<div ></div>
</body>
490.
[问答题]
编写一个方法 去掉一个数组的重复元素
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
=function(){ if(<2) return [this[0]]||[]; var arr=[];
for(var i=0;i<;i++){
((i--,1));//将本数组中第一个元素取出放入到数组 arr 中
的元素
for(var j=0;j<;j++){ if(this[j]==arr[-1]){
(j--,1);//删除本数组中与数组 arr 中最后一个元素相同
}
}
}
return arr;
}
var arr=["abc",85,"abc",85,8,8,1,2,5,4,7,8];
alert(());
491.
[问答题]
说出 3 条以上 ff 和 ie 的脚本兼容问题
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
IE 有 children,FF 没有;
IE 有 parentElement,FF 没有;
IE 有 innerText,outerText,outerHTML,FF 没有;
IE 有数据岛,FF 没有;
FF 有
HTMLElement,HTMLDivElement,XMLDocument,DocumentFragment,Node,Event,Element
等等,IE 没有;
IE 跟 FF 创建 HttpRequest 实例的方法不一样
492.
[问答题]
DIV 中 border、margin 和 padding 的区别和用法
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
边框属性(border)用来设定一个元素的边线
外边距属性(margin)是用来设置一个元素所占空间的边缘到相邻元素之间的距离内边距属性(padding)是用来设置元素内容到元素边界的距离
493.
[问答题]
为 Array 写一个 indexof 方法
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
= function(e){ for(var i=0,j; j=this[i]; i++){
if(j==e){return i;}
}
return -1;
}
= function(e){ for(var i=-1,j; j=this[i]; i--){
if(j==e){return i;}
}
return -1;
}
var arr=[1,2,3,4,5]; alert((5));
494.
[问答题]
说说元素克隆
----------------------------------------------------------------------------------------------------------------------------
来自:前端开发面试易考题参考:
浅复制(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用
深复制(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的
= function(){ var objClone;
if( == Object ) objClone = new ();
else
objClone = new (()); for ( var key in this ){
if ( objClone[key] != this[key] ){
if ( typeof(this[key]) == 'object' ){ objClone[key] = this[key].Clone();
}else{
objClone[key] = this[key];
}
}
}
= ; = ; return objClone;
}