javascript
JavaScript 习题及面试题 3
365.
?
[問答題]
原生 JavaScript 中兼容瀏覽器綁定元素事件
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function addEventSamp(obj,evt,fn){ if (obj.addEventListener) {
obj.addEventListener(evt, fn, false);
?
}else if(obj.attachEvent){ obj.attachEvent('on'+evt,fn);
}
}
?
366.
?
[問答題]
原生 JavaScript 光標停在文字的后面,文本框獲得焦點時調用
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function focusLast(){
var e = event.srcElement; var r =e.createTextRange();
r.moveStart('character',e.value.length); r.collapse(true);
r.select();
}
?
367.
?
[問答題]
原生 JavaScript 檢驗 URL 鏈接是否有效
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getUrlState(URL){
var xmlhttp = new ActiveXObject("microsoft.xmlhttp"); xmlhttp.Open("GET",URL, false);
try{
xmlhttp.Send();
}catch(e){
}finally{
var result = xmlhttp.responseText; if(result){
if(xmlhttp.Status==200){ return(true);
}else{
return(false);
}
?
}else{
return(false);
}
}
}
?
368.
?
[問答題]
原生 JavaScript 格式化 CSS 樣式代碼
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function formatCss(s){//格式化代碼
s = s.replace(/\s*([\{\}\:\;\,])\s*/g, "$1");
s = s.replace(/;\s*;/g, ";"); //清除連續分號 s = s.replace(/\,[\s\.\#\d]*{/g, "{");
s = s.replace(/([^\s])\{([^\s])/g, "$1 {\n\t$2");
s = s.replace(/([^\s])\}([^\n]*)/g, "$1\n}\n$2");
s = s.replace(/([^\s]);([^\s\}])/g, "$1;\n\t$2"); return s;
}
?
369.
?
[問答題]
原生 JavaScript 壓縮 CSS 樣式代碼
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function yasuoCss (s) {//壓縮代碼
s = s.replace(/\/\*(.|\n)*?\*\//g, ""); //刪除注釋 s = s.replace(/\s*([\{\}\:\;\,])\s*/g, "$1");
s = s.replace(/\,[\s\.\#\d]*\{/g, "{"); //容錯處理 s = s.replace(/;\s*;/g, ";"); //清除連續分號
s = s.match(/^\s*(\S+(\s+\S+)*)\s*$/); //去掉首尾空白return (s == null) ? "" : s[1];
}
?
370.
?
[問答題]
原生 JavaScript 獲取當前路徑
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
var currentPageUrl = "";
if (typeof this.href === "undefined") {
currentPageUrl = document.location.toString().toLowerCase();
}
else {
currentPageUrl = this.href.toString().toLowerCase();
}
?
371.
?
[問答題]
原生 JavaScriptIP 轉成整型
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function _ip2int(ip){ var num = 0;
ip = ip.split(".");
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 = document.getElementById("selectall"); var allbox = document.getElementsByName("allbox"); if (selectall.checked) {
for (var i = 0; i < allbox.length; i++) { allbox.checked = true;
}
} else {
for (var i = 0; i < allbox.length; i++) { allbox.checked = false;
}
}
}
?
374.
?
[問答題]
原生 JavaScript 判斷是否移動設備
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function isMobile(){
if (typeof this._isMobile === 'boolean'){ return this._isMobile;
?
}
var screenWidth = this.getScreenWidth();
var fixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rende rerModel.runningExperiments.fixviewport;
var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperi ment.toLowerCase() === "new");
if(!fixViewPortsExperiment){ if(!this.isAppleMobileDevice()){
screenWidth = screenWidth/window.devicePixelRatio;
}
}
?
?
?
?
?
?
}
?
375.
?
var isMobileScreenSize = screenWidth < 600; var isMobileUserAgent = false;
this._isMobile = isMobileScreenSize && this.isTouchScreen(); return this._isMobile;
?
?
[問答題]
原生 JavaScript 判斷是否移動設備訪問
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function isAppleMobileDevice(){
return (/iphone|ipod|ipad|Macintosh/i.test(navigator.userAgent.toLowerCase()));
}
?
376.
?
[問答題]
原生 JavaScript 判斷是否蘋果移動設備訪問
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function isAppleMobileDevice(){
return (/iphone|ipod|ipad|Macintosh/i.test(navigator.userAgent.toLowerCase()));
}
?
377.
?
[問答題]
原生 JavaScript 判斷是否安卓移動設備訪問
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function isAndroidMobileDevice(){
return (/android/i.test(navigator.userAgent.toLowerCase()));
}
?
378.
?
[問答題]
原生 JavaScript 判斷是否 Touch 屏幕
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function isTouchScreen(){
return (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
}
?
379.
?
[問答題]
原生 JavaScript 判斷是否在安卓上的谷歌瀏覽器
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function isNewChromeOnAndroid(){ if(this.isAndroidMobileDevice()){
var userAgent = navigator.userAgent.toLowerCase(); if((/chrome/i.test(userAgent))){
var parts = userAgent.split('chrome/');
var fullVersionString = parts[1].split(" ")[0];
var versionString = fullVersionString.split('.')[0]; var version = parseInt(versionString);
if(version >= 27){
?
return true;
}
}
}
return false;
}
?
380.
?
[問答題]
原生 JavaScript 判斷是否打開視窗
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function isViewportOpen() {
return !!document.getElementById('wixMobileViewport');
}
?
381.
?
[問答題]
原生 JavaScript 獲取移動設備初始化大小
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getInitZoom(){ if(!this._initZoom){
var screenWidth = Math.min(screen.height, screen.width); if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){
screenWidth = screenWidth/window.devicePixelRatio;
}
this._initZoom = screenWidth /document.body.offsetWidth;
}
return this._initZoom;
}
?
382.
?
[問答題]
原生 JavaScript 獲取移動設備最大化大小
?
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getZoom(){
var screenWidth = (Math.abs(window.orientation) === 90) ? Math.max(screen.height, sc reen.width) : Math.min(screen.height, screen.width);
if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){ screenWidth = screenWidth/window.devicePixelRatio;
}
var FixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rend ererModel.runningExperiments.fixviewport;
var FixViewPortsExperimentRunning = FixViewPortsExperiment && (FixViewPortsExperi ment === "New" || FixViewPortsExperiment === "new");
if(FixViewPortsExperimentRunning){
return screenWidth / window.innerWidth;
}else{
return screenWidth / document.body.offsetWidth;
}
}
?
383.
?
[問答題]
原生 JavaScript 獲取移動設備屏幕寬度
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getScreenWidth(){
var smallerSide = Math.min(screen.width, screen.height);
var fixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rende rerModel.runningExperiments.fixviewport;
var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperi ment.toLowerCase() === "new");
if(fixViewPortsExperiment){
if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){ smallerSide = smallerSide/window.devicePixelRatio;
}
}
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 (regular.test(strUrl)) { return true;
}
else {
return false;
}
}
?
385.
?
[問答題]
原生 JavaScript 根據樣式名稱檢索元素對象
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getElementsByClassName(name) {
var tags = document.getElementsByTagName('*') || document.all; var els = [];
for (var i = 0; i < tags.length; i++) { if (tags.className) {
var cs = tags.className.split(' '); for (var j = 0; j < cs.length; j++) {
if (name == cs[j]) { els.push(tags); break
}
}
}
}
return els
?
}
?
386.
?
[問答題]
原生 JavaScript 判斷是否以某個字符串開頭
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
String.prototype.startWith = function (s) { return this.indexOf(s) == 0
}
?
387.
?
[問答題]
原生 JavaScript 判斷是否以某個字符串結束
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
String.prototype.endWith = function (s) { var d = this.length - s.length;
return (d >= 0 && this.lastIndexOf(s) == d)
}
?
388.
?
[問答題]
原生 JavaScript 返回 IE 瀏覽器的版本號
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getIE(){
if (window.ActiveXObject){
var v = navigator.userAgent.match(/MSIE ([^;]+)/)[1]; return parseFloat(v.substring(0, v.indexOf(".")))
}
return false
}
?
389.
?
[問答題]
原生 JavaScript 獲取頁面高度
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getPageHeight(){
var g = document, a = g.body, f = g.documentElement, d = g.compatMode == "BackCom
?
pat"
?
?
?
?
}
?
?
? a
: g.documentElement;
return Math.max(f.scrollHeight, a.scrollHeight, d.clientHeight);
?
?
390.
?
[問答題]
原生 JavaScript 獲取頁面 scrollLeft
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getPageScrollLeft(){ var a = document;
return a.documentElement.scrollLeft || a.body.scrollLeft;
}
?
391.
?
[問答題]
原生 JavaScript 獲取頁面可視寬度
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getPageViewWidth(){
var d = document, a = d.compatMode == "BackCompat"
? d.body
: d.documentElement; return a.clientWidth;
?
}
?
392.
?
[問答題]
原生 JavaScript 獲取頁面寬度
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getPageWidth(){
var g = document, a = g.body, f = g.documentElement, d = g.compatMode == "BackCom
?
pat"
?
?
?
?
}
?
?
? a
: g.documentElement;
return Math.max(f.scrollWidth, a.scrollWidth, d.clientWidth);
?
?
393.
?
[問答題]
原生 JavaScript 獲取頁面 scrollTop
?
----------------------------------------------------------------------------------------------------------------------------
來自:原生 Javascript 編程練習題參考:
function getPageScrollTop(){ var a = document;
return a.documentElement.scrollTop || a.body.scrollTop;
}
?
394.
?
[問答題]
考察知識點:作用域考慮如下代碼: (function() {
var a = b = 5;
})();
console.log(b);
請問控制臺上會輸出什么?
?
----------------------------------------------------------------------------------------------------------------------------
來自:Javascript 開發者面試典型題集輸出:5
這一題的陷阱是,在函數表達式中有兩個賦值,但 a 是用關鍵字var 來聲明的,這意味著 a 是局部變量,而b 則被賦予為全局變量。
另一個陷阱是,它并沒有使用嚴格模式(use? strict)。在函數里面,如果啟用了嚴格模式,代碼就會報錯:“Uncaught ReferenceError: b is not defined”。請記住,嚴格模式需要你顯式地引用全局作用域,代碼應該寫成:
(function() { 'use strict';
var a = window.b = 5;
})();
console.log(b);
?
395.
?
[問答題]
考察知識點:創建“內置”方法
給 String 對象定義一個 repeatify 方法。該方法接收一個整數參數,作為字符串重復的次數,最后返回重復指定次數的字符串。例如:
console.log('hello'.repeatify(3));
輸出應該是
hellohellohello.
?
----------------------------------------------------------------------------------------------------------------------------
來自:Javascript 開發者面試典型題集參考:
一個可行的做法如下:
String.prototype.repeatify = String.prototype.repeatify || function(times) { var str = '';
for (var i = 0; i < times; i++) { str += this;
}
return str;
};
這題測試開發者對 Javascript 的繼承及原型屬性的知識,它同時也檢驗了開發者是否能擴展內置數據類型的方法。
這里的另一個關鍵點是,看你怎樣避免重寫可能已經定義了的方法。這可以通過在定義自己的方法之前,檢測方法是否已經存在。
String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};
當被問起去擴展一個 Javascript 方法時,這個技術非常有用。
?
396.
?
[問答題]
考察知識點:聲明提前
下面這段代碼的結果是什么?為什么?
function test() { console.log(a); console.log(foo()); var a = 1;
function foo() { return 2;
}}
test();
?
----------------------------------------------------------------------------------------------------------------------------
來自:Javascript 開發者面試典型題集參考:
代碼的運行結果:undefined 和 2
理由是,變量和函數的聲明都被提前至函數體的頂部,而同時變量并沒有被賦值。因此, 當打印變量a 時,它雖存在于函數體(因為 a 已經被聲明),但仍然是 undefined。換句話說, 上面的代碼等同于下面的代碼:
function test() { var a;
function foo() { return 2;
}
console.log(a); console.log(foo()); a = 1;
}
test();
?
397.
?
[問答題]
考察知識點:JavaScript 中的 this
下面代碼的運行結果是什么并做解釋。
var fullname = 'John Doe'; var obj = {
fullname: 'Colin Ihrig', prop: {
fullname: 'Aurelio De Rosa', getFullname: function() {
?
return this.fullname;
}}};
console.log(obj.prop.getFullname()); var test = obj.prop.getFullname; console.log(test());
?
----------------------------------------------------------------------------------------------------------------------------
來自:Javascript 開發者面試典型題集參考:
代碼輸出:Aurelio De Rosa 和 John Doe
理由是,Javascript 中關鍵字 this 所指代的函數上下文,取決于函數是怎樣被調用的, 而不是怎樣被定義的。
在第一個 console.log(),getFullname()被作為 obj.prop 對象被調用。因此,當前的上下文指代后者,函數返回這個對象的 fullname 屬性。相反,當 getFullname()被賦予 test 變量,當前的上下文指代全局對象 window,這是因為 test 被隱式地作為全局對象的屬性。基于這一點,函數返回window 的 fullname,在本例中即為代碼的第一行。
?
398.
?
[問答題]
考察知識點:call()和 apply()
修復前一個問題,讓最后一個 console.log() 打印輸出 Aurelio De Rosa.
?
----------------------------------------------------------------------------------------------------------------------------
來自:Javascript 開發者面試典型題集參考:
這個問題可以通過運用 call()或者 apply()方法強制轉換上下文環境。下面的代碼中用了 call(),但 apply()也能產生同樣的結果:
console.log(test.call(obj.prop));
?
399.
?
[問答題]
真假判斷
var aLinks=document.getElementsByTagName('a'); for(i=0;i<aLinks.length;i++)
{
?
}
?
----------------------------------------------------------------------------------------------------------------------------
來自:百度 2011 年 6 月前端開發面試題參考:
?
復制代碼修改后:
var aLinks=document.getElementsByTagName('a'); for(var i=0,l= aLinks.length;i<l;i++)
{
?
}
?
400.
?
[問答題]
參照上題代碼,給 a 添加事件,要求點擊彈出提示相應的 index 值。
?
----------------------------------------------------------------------------------------------------------------------------
來自:百度 2011 年 6 月前端開發面試題參考:
(1)、第一種方法(加索引)
var aLinks=document.getElementsByTagName('a'); for(var i=0,l= aLinks.length;i<l;i++)
{
aLinks[i].Index=I; aLinks[i].οnclick=function(){alert(this.Index)};
}
(2)、第二種方法(閉包)
var aLinks=document.getElementsByTagName('a'); for(var i=0,l= aLinks.length;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 Object.prototype.cloneObj()
{
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 = oldArr.length-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 = newArr.push(oldArr)-1;
}
return newArr;
}
?
404.
?
[問答題]
你玩微博嗎? 現有這樣的字符串: @ 小甜甜(xiaotiantian) 或者 @ 小王的后宮(hougong123) ..這樣的字符串如何在計算字數的時候,省略括號里面的內容?比如 @小甜甜(xiaotiantian) 他的長度應該是省略 (xiaotiantian) 這個字符串后的長度,就是 3. 你有多少種方法來實現,請寫下代碼。
?
----------------------------------------------------------------------------------------------------------------------------
來自:搜道網前端開發面試題參考:
a:使用正則替換掉 (XXX),然后使用 string.length? 返回長度,代碼:
function getStrLen(str){return (str.replace(/[\(\w\)]/g, "")).lenght;}
b:使用 indexOf 查找"("與")",記錄相關位置,然后使用 str.subString()函數截取,得到新串,再.length 得到長度,代碼:
function getStrLen(str){
return (str.substring(0, str.indexOf("("))+str.substring(str.indexOf(")")+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 < NEWS.length; i++) { htmlString += ‘<li><a href=”’ +
NEWS*i+.LINK + ‘”> +
NEWS*i+.TITLE? + ‘</a></li>’;
}
htmlString += ‘</ul></div>’;
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
?
409.
?
[問答題]
嘗試實現注釋部分的 Javascript 代碼,可在其他任何地方添加更多代碼(如不能實現, 說明一下不能實現的原因):
var Obj = function(msg){ this.msg = msg; this.shout = function(){
alert(this.msg);
}
this.waitAndShout = function(){
?
//隔五秒鐘后執行上面的 shout 方法
}
}
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
?
410.
?
[問答題]
請編寫一個 JavaScript 函數 toRGB,它的作用是轉換 CSS 中常用的顏色編碼。 要求:
alert(toRGB("#0000FF"));?????????????????????? // 輸出 rgb(0, 0, 255)
alert(toRGB("invalid"));???????????????????????? // 輸出 invalid
alert(toRGB("#G00"));?????????????????????????? // 輸出 #G00
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
?
411.
?
[問答題]
javascript 有哪幾種方法定義函數
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions)
?
412.
?
[問答題]
應用程序存儲和離線 web 應用
?
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
HTML5 新增應用程序緩存,允許 web 應用將應用程序自身保存到用戶瀏覽器中,用戶離線狀態也能訪問。
CACHE MANIFEST CACHE:
myapp.html myapp.css myapp.js 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
localStorage.setItem('x', 1); // storge x->1 localStorage.getItem('x); // return value of x
// 枚舉所有存儲的鍵值對
for (var i = 0, len = localStorage.length; i < len; ++i ) { var name = localStorage.key(i);
var value = localStorage.getItem(name);
}
localStorage.removeItem('x'); // remove x localStorage.clear();? // remove all data
?
413.
?
[問答題]
?
cookie 及其操作
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
cookie 是 web 瀏覽器存儲的少量數據,最早設計為服務器端使用,作為 HTTP 協議的擴展實現。cookie 數據會自動在瀏覽器和服務器之間傳輸。
通過讀寫 cookie 檢測是否支持
cookie 屬性有名,值,有效期,作用域,secure;
cookie 默認有效期為瀏覽器會話,一旦用戶關閉瀏覽器,數據就丟失,通過設置
max-age=seconds 屬性告訴瀏覽器 cookie 有效期
cookie 作用域通過文檔源和文檔路徑來確定,通過 path 和 domain 進行配置,web 頁面同目錄或子目錄文檔都可訪問
通過 cookie 保存數據的方法為:為 document.cookie 設置一個符合目標的字符串如下讀取 document.cookie 獲得'; '分隔的字符串,key=value,解析得到結果document.cookie = 'name=qiu; max-age=9999; path=/; domain=domain; secure'; document.cookie = 'name=aaa; path=/; domain=domain; secure';
// 要改變 cookie 的值,需要使用相同的名字、路徑和域,新的值
// 來設置 cookie,同樣的方法可以用來改變有效期
// 設置 max-age 為 0 可以刪除指定cookie
//讀取 cookie,訪問 document.cookie 返回鍵值對組成的字符串,
//不同鍵值對之間用'; '分隔。通過解析獲得需要的值cookieUtil.js:自己寫的 cookie 操作工具
?
414.
?
[問答題]
javascript 有哪些方法定義對象
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
對象字面量: var obj = {};
構造函數: var obj = new Object();
Object.create(): var obj = Object.create(Object.prototype);
?
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
對象到數字的轉換步驟
?
<,>,<=,>=的比較規則
所有比較運算符都支持任意類型,但是比較只支持數字和字符串,所以需要執行必要的轉換然后進行比較,轉換規則如下: 1. 如果操作數是對象,轉換為原始值:如果valueOf 方法返回原始值,則使用這個值,否則使用 toString 方法的結果,如果轉換失敗則報錯 2. 經過必要的對象到原始值的轉換后,如果兩個操作數都是字符串,按照字母順序進行比較(他們的 16 位 unicode 值的大小) 3. 否則,如果有一個操作數不是字符串,將兩個操作數轉換為數字進行比較
?
418.
?
[問答題]
+運算符工作流程
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
?
419.
?
[問答題]
函數內部 arguments 變量有哪些特性,有哪些屬性,如何將它轉換為數組
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
arguments 所有函數中都包含的一個局部變量,是一個類數組對象,對應函數調用時的實參。如果函數定義同名參數會在調用時覆蓋默認對象
arguments[index]分別對應函數調用時的實參,并且通過 arguments 修改實參時會同時修改實參
arguments.length 為實參的個數(Function.length 表示形參長度)
arguments.callee 為當前正在執行的函數本身,使用這個屬性進行遞歸調用時需注意 this
的變化
arguments.caller 為調用當前函數的函數(已被遺棄)
轉換為數組:var args = Array.prototype.slice.call(arguments, 0);
?
420.
?
[問答題]
DOM 事件模型是如何的,編寫一個 EventUtil 工具類實現事件管理兼容
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
DOM 事件包含捕獲(capture)和冒泡(bubble)兩個階段:捕獲階段事件從 window 開始觸發事件然后通過祖先節點一次傳遞到觸發事件的 DOM 元素上;冒泡階段事件從初始元素依次向祖先節點傳遞直到window
標???? 準???? 事???? 件???? 監 ?聽??? ?elem.addEventListener(type,??????????? handler, capture)/elem.removeEventListener(type, handler, capture):handler 接收保存事件信息的event對象作為參數,event.target 為觸發事件的對象,handler 調用上下文this 為綁定監聽器的對象 , event.preventDefault() 取 消 事 件 默 認 行 為 , event.stopPropagation()/event.stopImmediatePropagation()取消事件傳遞
老版本 IE 事件監聽 elem.attachEvent('on'+type, handler)/elem.detachEvent('on'+type, handler):handler 不接收event 作為參數,事件信息保存在 window.event 中,觸發事件的對象為event.srcElement,handler 執行上下文 this 為 window 使用閉包中調用 handler.call(elem, event)可模仿標準模型,然后返回閉包,保證了監聽器的移除。event.returnValue 為 false 時取消事件默認行為,event.cancleBubble 為 true 時取消時間傳播
通常利用事件冒泡機制托管事件處理程序提高程序性能。
/**
- 跨瀏覽器事件處理工具。只支持冒泡。不支持捕獲
- @author???? (qiu_deqing@126.com)
*/
?
var EventUtil = {
getEvent: function (event) {
return event || window.event;
},
getTarget: function (event) {
return event.target || event.srcElement;
},
// 返回注冊成功的監聽器,IE 中需要使用返回值來移除監聽器
on: function (elem, type, handler) { if (elem.addEventListener) {
elem.addEventListener(type, handler, false); return handler;
} else if (elem.attachEvent) { var wrapper = function () {
var event = window.event; event.target = event.srcElement;
?
handler.call(elem, event);
};
elem.attachEvent('on' + type, wrapper); return wrapper;
}
},
off: function (elem, type, handler) { if (elem.removeEventListener) {
elem.removeEventListener(type, handler, false);
} else if (elem.detachEvent) { elem.detachEvent('on' + type, handler);
}
},
preventDefault: function (event) { if (event.preventDefault) {
event.preventDefault();
} else if ('returnValue' in event) { event.returnValue = false;
}
},
stopPropagation: function (event) { if (event.stopPropagation) {
event.stopPropagation();
} else if ('cancelBubble' in event) { event.cancelBubble = true;
}
}
};
?
421.
?
[問答題]
評價一下三種方法實現繼承的優缺點,并改進
function Shape() {} function Rect() {}
// 方法 1
Rect.prototype = new Shape();
// 方法 2
Rect.prototype = Shape.prototype;
// 方法 3
Rect.prototype = Object.create(Shape.prototype); Rect.prototype.area = function () {
// do something
};
?
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
方法 1:
優點:正確設置原型鏈實現繼承
優點:父類實例屬性得到繼承,原型鏈查找效率提高,也能為一些屬性提供合理的默認
值
缺點:父類實例屬性為引用類型時,不恰當地修改會導致所有子類被修改
缺點:創建父類實例作為子類原型時,可能無法確定構造函數需要的合理參數,這樣提
供的參數繼承給子類沒有實際意義,當子類需要這些參數時應該在構造函數中進行初始化和設置
總結:繼承應該是繼承方法而不是屬性,為子類設置父類實例屬性應該是通過在子類構造函數中調用父類構造函數進行初始化
方法 2:
優點:正確設置原型鏈實現繼承
缺點:父類構造函數原型與子類相同。修改子類原型添加方法會修改父類方法 3:
優點:正確設置原型鏈且避免方法 1.2 中的缺點缺點:ES5 方法需要注意兼容性
改進:
所有三種方法應該在子類構造函數中調用父類構造函數實現實例屬性初始化
function Rect() {
Shape.call(this);
}
用新創建的對象替代子類默認原型,設置 Rect.prototype.constructor = Rect;保證一致性第三種方法的 polyfill:
function create(obj) {
if (Object.create) {
return Object.create(obj);
?
?
?
?
?
?
}
?
422.
?
}
function f() {}; f.prototype = 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 = data.length; i < len; ++i) { d = data[i];
if (typeof d === 'number') { result.push(d);
} else {
flat(d, result);
}
}
}
var result = []; flat(data, result); console.log(result);
?
423.
?
[問答題]
如何判斷一個對象是否為數組
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
如果瀏覽器支持 Array.isArray()可以直接判斷否則需進行必要判斷
/**
- 判斷一個對象是否是數組,參數不是對象或者不是數組,返回 false
*
- @param {Object} arg 需要測試是否為數組的對象
- @return {Boolean} 傳入參數是數組返回 true,否則返回 false
*/
function isArray(arg) {
if (typeof arg === 'object') {
return Object.prototype.toString.call(arg) === '[object Array]';
?
?
?
?
}
?
424.
?
}
return false;
?
?
[問答題]
?
請評價以下代碼并給出改進意見
if (window.addEventListener) {
var addListener = function (el, type, listener, useCapture) { el.addEventListener(type, listener, useCapture);
};
}
else if (document.all) {
addListener = function (el, type, listener) { el.attachEvent('on' + type, function () {
listener.apply(el);
});
};
}
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
作用:瀏覽器功能檢測實現跨瀏覽器 DOM 事件綁定優點:
測試代碼只運行一次,根據瀏覽器確定綁定方法
通過 listener.apply(el)解決 IE 下監聽器 this 與標準不一致的地方
在瀏覽器不支持的情況下提供簡單的功能,在標準瀏覽器中提供捕獲功能缺點:
document.all 作為 IE 檢測不可靠,應該使用 if(el.attachEvent) addListener 在不同瀏覽器下 API 不一樣
listener.apply 使 this 與標準一致但監聽器無法移除未解決 IE 下 listener 參數event。 target 問題
改進:
var addListener;
if (window.addEventListener) {
addListener = function (el, type, listener, useCapture) { el.addEventListener(type, listener, useCapture); return listener;
};
}
else if (window.attachEvent) {
addListener = function (el, type, listener) {
// 標準化 this,event,target var wrapper = function () {
var event = window.event; event.target = event.srcElement; listener.call(el, event);
};
?
?
?
?
?
};
}
?
425.
?
el.attachEvent('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 Object.prototype.toString.call(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 (query.charAt(0) === '?') {
query = query.substring(1);
}
var pairs = query.split('&'); var pair;
var key, value; var i, len;
for (i = 0, len = pairs.length; 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]]; arr.push(value); result[key] = arr;
} // end if-else
} // end for return result;
}
function isArray(arg) {
if (arg && typeof arg === 'object') {
return Object.prototype.toString.call(arg) === '[object Array]';
?
}
return false;
}
/**
console.log(parseQuery('sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8'));
*/
?
427.
?
[問答題]
解析一個完整的 url,返回 Object 包含域與 window.location 相同
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
/**
- 解析一個 url 并生成window.location 對象中包含的域
- 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 = regexp.exec(url);
if (match) {
for (i = keys.length - 1; i >= 0; --i) {
?
result[keys[i]] = match[i] ? match[i] : '';
}
}
return result;
}
?
428.
?
[問答題]
完成函數 getScrollOffset 返回窗口滾動條偏移量
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
/**
- 獲取指定 window 中滾動條的偏移量,如未指定則獲取當前window
- 滾動條偏移量
*
- @param {window} w 需要獲取滾動條偏移量的窗口
- @return {Object} obj.x 為水平滾動條偏移量,obj.y 為豎直滾動條偏移量
*/
function getScrollOffset(w) { w =?? w || window;
// 如果是標準瀏覽器
if (w.pageXOffset != null) { return {
x: w.pageXOffset, y: w.pageYOffset
};
}
// 老版本 IE,根據兼容性不同訪問不同元素var d = w.document;
if (d.compatMode === 'CSS1Compat') { return {
x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop
}
}
return {
x: d.body.scrollLeft, y: d.body.scrollTop
};
}
?
429.
?
[問答題]
現有一個字符串 richText,是一段富文本,需要顯示在頁面上。有個要求,需要給其中只包含一個 img 元素的 p 標簽增加一個叫 pic 的 class。請編寫代碼實現??梢允褂?jQuery 或 KISSY。
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
function richText(text) {
var div = document.createElement('div'); div.innerHTML = text;
var p = div.getElementsByTagName('p'); var i, len;
for (i = 0, len = p.length; i < len; ++i) {
if (p[i].getElementsByTagName('img').length === 1) { p[i].classList.add('pic');
}
}
return div.innerHTML;
}
?
430.
?
[問答題]
請實現一個 Event 類,繼承自此類的對象都會擁有兩個方法 on 和 trigger
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
?
431.
?
[問答題]
編寫一個函數將列表子元素順序反轉
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
<ul id="target">
<li>1</li>
?
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
?
<script>
var target = document.getElementById('target'); var i;
var frag = document.createDocumentFragment();
?
for (i = target.children.length - 1; i >= 0; --i) { frag.appendChild(target.children[i]);
}
target.appendChild(frag);
</script>
?
432.
?
[問答題]
以下函數的作用是?空白區域應該填寫什么
// define
(function (window) { function fn(str) {
this.str = str;
}
fn.prototype.format = function () { var arg = 1 ;
return this.str.replace( 2 , function (a, b) { return arg[b] || '';
});
};
window.fn = fn;
})(window);
// use (function () {
var t = new fn('<p><a href="{0}">{1}</a><span>{2}</span></p>'); console.log(t.format('http://www.alibaba.com', 'Alibaba', 'Welcome'));
})();
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
define 部分定義一個簡單的模板類,使用{}作為轉義標記,中間的數字表示替換目標,
format 實參用來替換模板內標記
?
橫線處填:
Array.prototype.slice.call(arguments, 0)
/\{\s*(\d+)\s*\}/g
?
433.
?
[問答題]
編寫一個函數實現 form 的序列化(即將一個表單中的鍵值序列化為可提交的字符串)
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
/**
- 將一個表單元素序列化為可提交的字符串
*
- @param {FormElement} form 需要序列化的表單元素
- @return {string} 表單序列化后的字符串
*/
function serializeForm(form) {
if (!form || form.nodeName.toUpperCase() !== 'FORM') { return;
}
var result = []; var i, len;
var field, fieldName, fieldType;
?
for (i = 0, len = form.length; i < len; ++i) { field = form.elements[i];
fieldName = field.name; fieldType = field.type;
?
if (field.disabled || !fieldName) { continue;
} // enf if
?
switch (fieldType) { case 'text':
case 'password':
case 'hidden':
case 'textarea': result.push(encodeURIComponent(fieldName) + '=' +
encodeURIComponent(field.value)); break;
?
case 'radio':
case 'checkbox':
if (field.checked) { result.push(encodeURIComponent(fieldName) + '=' +
encodeURIComponent(field.value));
}
break;
?
case 'select-one':
case 'select-multiple':
for (var j = 0, jLen = field.options.length; j < jLen; ++j) { if (field.options[j].selected) {
result.push(encodeURIComponent(fieldName) + '=' + encodeURIComponent(field.options[j].value || field.options[j].text));
}
} // end for break;
?
case 'file':
case 'submit':
break; // 是否處理?
?
default:
break;
} // end switch
} // end for
?
return result.join('&');
}
?
434.
?
[問答題]
使用原生javascript 給下面列表中的li 節點綁定點擊事件,點擊時創建一個Object 對象, 兼容 IE 和標準瀏覽器
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
<ul id="nav">
<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 || window.event;
},
getTarget: function (event) {
return event.target || event.srcElement;
},
// 返回注冊成功的監聽器,IE 中需要使用返回值來移除監聽器
on: function (elem, type, handler) { if (elem.addEventListener) {
elem.addEventListener(type, handler, false); return handler;
} else if (elem.attachEvent) { function wrapper(event) {
return handler.call(elem, event);
};
elem.attachEvent('on' + type, wrapper); return wrapper;
}
},
off: function (elem, type, handler) { if (elem.removeEventListener) {
elem.removeEventListener(type, handler, false);
} else if (elem.detachEvent) { elem.detachEvent('on' + type, handler);
}
},
preventDefault: function (event) { if (event.preventDefault) {
event.preventDefault();
} else if ('returnValue' in event) { event.returnValue = false;
}
},
?
stopPropagation: function (event) { if (event.stopPropagation) {
event.stopPropagation();
} else if ('cancelBubble' in event) { event.cancelBubble = true;
}
}
};
var DOMUtil = {
text: function (elem) {
if ('textContent' in elem) { return elem.textContent;
} else if ('innerText' in elem) { return elem.innerText;
}
},
prop: function (elem, propName) {
return elem.getAttribute(propName);
}
};
?
var nav = document.getElementById('nav');
?
EventUtil.on(nav, 'click', function (event) { var event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event);
?
var children = this.children; var i, len;
var anchor; var obj = {};
?
for (i = 0, len = children.length; i < len; ++i) { if (children[i] === target) {
obj.index = i + 1;
anchor = target.getElementsByTagName('a')[0]; obj.name = DOMUtil.text(anchor);
obj.link = DOMUtil.prop(anchor, 'href');
}
}
?
?
?
?
?
});
?
alert('index: ' + obj.index + ' name: ' + obj.name + ' link: ' + obj.link);
?
435.
?
[問答題]
有一個大數組,var a = ['1', '2', '3', ...]; a 的長度是 100,內容填充隨機整數的字符串。請先構造此數組a,然后設計一個算法將其內容去重
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:無
/**
* 數組去重
**/
function normalize(arr) {
if (arr && Array.isArray(arr)) { var i, len, map = {};
for (i = arr.length; i >= 0; --i) { if (arr[i] in map) {
arr.splice(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) {
arr.push('' + (Math.floor(Math.random() * width) + start));
}
return arr;
?
}
?
var input = []; fillArray(input, 1, 100); input.sort(function (a, b) {
return a - b;
});
console.log(input);
?
normalize(input); console.log(input);
?
436.
?
[談話題]
前端是龐大的,包括 HTML、CSS、Javascript、Image、Flash 等等各種各樣的資源。前端優化是復雜的,針對方方面面的資源都有不同的方式。隨便聊聊有關優化方面的技術話題。
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試題參考:
前端優化的目的是什么?
總之,恰當的優化不僅能夠改善站點的用戶體驗并且能夠節省相當的資源利用。前端優化的途徑有很多,按粒度大致可以分為兩類,第一類是頁面級別的優化,例
如 HTTP 請求數、腳本的無阻塞加載、內聯腳本的位置優化等;第二類則是代碼級別的優化, 例如 Javascript 中的 DOM 操作優化、CSS 選擇符優化、圖片優化以及 HTML 結構優化等等。另外,本著提高投入產出比的目的,后文提到的各種優化策略大致按照投入產出比從大到小的順序排列。
一、頁面級優化
這條策略基本上所有前端人都知道,而且也是最重要最有效的。都說要減少 HTTP 請求,那請求多了到底會怎么樣呢?首先,每個請求都是有成本的,既包含時間成本也包含 資源成本。一個完整的請求都需要經過 DNS? 尋址、與服務器建立連接、發送數據、等待服務器響應、接收數據這樣一個“漫長”而復雜的過程。時間成本就是用戶需要看到或者“感 受”到這個資源是必須要等待這個過程結束的,資源上由于每個請求都需要攜帶數據,因此 每個請求都需要占用帶寬。另外,由于瀏覽器進行并發請求的請求數是有上限的(具體參見 此處),因此請求數多了以后,瀏覽器需要分批進行請求,因此會增加用戶的等待時間,會 給用戶造成站點速度慢這樣一個印象,即使可能用戶能看到的第一屏的資源都已經請求完了, 但是瀏覽器的進度條會一直存在。
減少 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 圖片,減少請求數的又一個好辦法。
使用 data: URL scheme 的方式將圖片嵌入到頁面或 CSS 中,如果不考慮資源管理上的問題的話,不失為一個好辦法。如果是嵌入頁面的話換來的是增大了頁面的體積,而且無法利用瀏覽器緩存。使用在 CSS 中的圖片則更為理想一些。
這條策略實際上并不一定能減少 HTTP 請求數,但是卻能在某些條件下或者頁面剛加載時減少HTTP 請求數。對于圖片而言,在頁面剛加載的時候可以只加載第一屏,當用戶繼續往后滾屏的時候才加載后續的圖片。這樣一來,假如用戶只對第一屏的內容感興趣時, 那剩余的圖片請求就都節省了。有啊首頁曾經的做法是在加載的時候把第一屏之后的圖片地址緩存在 Textarea 標簽中,待用戶往下滾屏的時候才“惰性”加載。
前文有談到,瀏覽器是可以并發請求的,這一特點使得其能夠更快的加載資源,然而外鏈腳本在加載時卻會阻塞其他資源,例如在腳本加載完成之前,它后面的圖片、樣式以及其他腳本都處于阻塞狀態,直到腳本加載完成后才會開始加載。如果將腳本放在比較靠前的位置,則會影響整個頁面的加載速度從而影響用戶體驗。解決這一問題的方法有很多,在這里有比較詳細的介紹(這里是譯文和更詳細的例子),而最簡單可依賴的方法就是將腳本盡可能的往后挪,減少對并發下載的影響。
inline 腳本對性能的影響與外部腳本相比,是有過之而無不及。首頁,與外部腳本一樣,inline 腳本在執行的時候一樣會阻塞并發請求,除此之外,由于瀏覽器在頁面處理方面是單線程的,當inline 腳本在頁面渲染之前執行時,頁面的渲染工作則會被推遲。簡而言之,inline 腳本在執行的時候,頁面處于空白狀態。鑒于以上兩點原因,建議將執行時間較長的 inline 腳本異步執行,異步的方式有很多種,例如使用 script 元素的 defer 屬性(存在兼
?
容性問題和其他一些問題,例如不能使用 document.write)、使用 setTimeout,此外,在 HTML5
中引入了 Web Workers 的機制,恰恰可以解決此類問題。
隨著 Javascript 框架的流行,越來越多的站點也使用起了框架。不過,一個框架往往包括了很多的功能實現,這些功能并不是每一個頁面都需要的,如果下載了不需要的腳本則算得上是一種資源浪費-既浪費了帶寬又浪費了執行花費的時間。目前的做法大概有兩種, 一種是為那些流量特別大的頁面專門定制一個專用的 mini 版框架,另一種則是 Lazy Load。YUI 則使用了第二種方式,在 YUI 的實現中,最初只加載核心模塊,其他模塊可以等到需要使用的時候才加載。
如果將 CSS 放在其他地方比如BODY 中,則瀏覽器有可能還未下載和解析到 CSS 就已經開始渲染頁面了,這就導致頁面由無 CSS 狀態跳轉到 CSS 狀態,用戶體驗比較糟糕。除此之外,有些瀏覽器會在 CSS 下載完成后才開始渲染頁面,如果 CSS 放在靠下的位置則會導致瀏覽器將渲染時間推遲。
在某些頁面中可能存在這樣一種需求,需要使用 script 標簽來異步的請求數據。類
似:
Javascript:
/*Callback 函 數 */ function myCallback(info){
//do something here
}
HTML:
<script type="text/javascript" src="http://abc.com/cb"></script> cb 返回的內容:
myCallback('Hello world!');
像以上這種方式直接在頁面上寫<script>對頁面的性能也是有影響的,即增加了頁面首次加載的負擔,推遲了 DOMLoaded 和 window.onload 事件的觸發時機。如果時效性允許的話,可以考慮在 DOMLoaded 事件觸發的時候加載,或者使用 setTimeout 方式來靈活的控制加載的時機。
對于以目錄形式訪問的 HTTP 鏈接,很多人都會忽略鏈接最后是否帶’/',假如你的服務器對此是區別對待的話,那么你也需要注意,這其中很可能隱藏了 301 跳轉,增加了多余請求。具體參見下圖,其中第一個鏈接是以無’/'結尾的方式訪問的,于是服務器有了一次跳轉。
這種情況主要是由于疏忽或頁面由多個模塊拼接而成,然后每個模塊中請求了同樣的資源時,會導致資源的重復請求
二、代碼級優化
DOM 操作應該是腳本中最耗性能的一類操作,例如增加、修改、刪除 DOM 元素或者對 DOM 集合進行操作。如果腳本中包含了大量的 DOM 操作則需要注意以下幾點:
?
在腳本中 document.images、document.forms、getElementsByTagName()返回的都是HTMLCollection 類型的集合,在平時使用的時候大多將它作為數組來使用,因為它有 length 屬性,也可以使用索引訪問每一個元素。不過在訪問性能上則比數組要差很多,原因是這個集合并不是一個靜態的結果,它表示的僅僅是一個特定的查詢,每次訪問該集合時都會重新執行這個查詢從而更新查詢結果。所謂的“訪問集合”包括讀取集合的 length 屬性、訪問集合中的元素。
因此,當你需要遍歷 HTML Collection 的時候,盡量將它轉為數組后再訪問,以提高性能。即使不轉換為數組,也請盡可能少的訪問它,例如在遍歷的時候可以將 length 屬性、成員保存到局部變量后再使用局部變量。
除了上面一點之外,DOM 操作還需要考慮瀏覽器的 Reflow 和 Repaint,因為這些都是需要消耗資源的,具體的可以參加以下文章:
如 何 減 少 瀏 覽 器 的 repaint 和 reflow? Understanding Internet Explorer Rendering Behaviour Notes on HTML Reflow
with(obj){ p = 1}; 代碼塊的行為實際上是修改了代碼塊中的執行環境,將 obj 放在了其作用域鏈的最前端,在 with 代碼塊中訪問非局部變量是都是先從 obj 上開始查找, 如果沒有再依次按作用域鏈向上查找,因此使用 with 相當于增加了作用域鏈長度。而每次查找作用域鏈都是要消耗時間的,過長的作用域鏈會導致查找性能下降。
因此,除非你能肯定在 with 代碼中只訪問 obj 中的屬性,否則慎用 with,替代的可以使用局部變量緩存需要訪問的屬性。
每次 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 中的數據訪問包括直接量(字符串、正則表達式)、變量、對象屬性以及數
組,其中對直接量和局部變量的訪問是最快的,對對象屬性以及數組的訪問需要更大的開銷。當出現以下情況時,建議將數據放入局部變量:
另外,還應當盡可能的減少對對象以及數組深度查找。
在 Javascript 中使用"+"號來拼接字符串效率是比較低的,因為每次運行都會開辟新的內存并生成新的字符串變量,然后將拼接結果賦值給新變量。與之相比更為高效的做法是使用數組的 join 方法,即將需要拼接的字符串放在數組中最后調用其 join 方法得到結果。不過由于使用數組也有一定的開銷,因此當需要拼接的字符串較多的時候可以考慮用此方法。
關于 Javascript 優化的更詳細介紹請參考:
Write Efficient Javascript(PPT) Efficient JavaScript
在大多數人的觀念中,都覺得瀏覽器對 CSS 選擇符的解析式從左往右進行的,例如
#toc A { color: #444; }
這樣一個選擇符,如果是從右往左解析則效率會很高,因為第一個 ID 選擇基本上就把查找的范圍限定了,但實際上瀏覽器對選擇符的解析是從右往左進行的。如上面的選擇符,瀏覽器必須遍歷查找每一個 A 標簽的祖先節點,效率并不像之前想象的那樣高。根據瀏覽器的這一行為特點,在寫選擇符的時候需要注意很多事項,有人已經一一列舉了,詳情參考此處。
對 HTML 本身的優化現如今也越來越多的受人關注了,詳情可以參見這篇總結性文
章。
圖片壓縮是個技術活,不過現如今這方面的工具也非常多,壓縮之后往往能帶來不
?
錯的效果,具體的壓縮原理以及方法在《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 關鍵字來聲明的。(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(fNumber.toExponential(1));//保留的小數點數 1.2e+2 alert(fNumber.toExponential(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 = a.toString(); var d = "student" + a;
?
toString() var a=11;
document.write(a.toString(2) + "<br>");//轉成 2 進制document.write(a.toString(3) + "<br>");//轉成 3 進制如果不是數值,則轉換報錯
parseInt()
document.write(parseInt("1red6") + "<br>");//返回 1,后面非數值的將全部忽略document.write(parseInt("53.5") + "<br>");// 返 回 53 document.write(parseInt("0xC") + "<br>"); // 直 接 十 進 制 轉 換 12 document.write(parseInt("isaacshun@gmail.com") + "<br>");//NAN document.write(parseInt("011",8) + "<br>"); 返 回 9 document.write(parseInt("011",10) + "<br>");? //指定為十進制 返回 11 parseFloat()與 parseInt()類似
?
444.
?
[思考題]
數組
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點重點提示:
var aMap = new Array("China","USA","Britain"); aMap[20] = "Korea";
alert(aMap.length + " " + aMap[10] + " " + aMap[20]);//aMap[10]返回 undefined document.write(aMap.join("][") + "<br>");????????????? //用“][”來連接
var sFruit = "apple,pear,peach,orange";
?
var aFruit = sFruit.split(",");
?
var aFruit = ["apple","pear","peach","orange"]; alert(aFruit.reverse().toString());
?
var aFruit = ["pear","apple","peach","orange"]; aFruit.sort();
?
var stack = new Array(); stack.push("red"); stack.push("green"); stack.push("blue");
document.write(stack.toString() + "<br>"); var vItem = stack.pop(); // blue document.write(vItem + "<br>");
document.write(stack.toString()); // red green
?
445.
?
[思考題] if 語句
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點用法提示:
//首先獲取用戶的一個輸入,并用Number()強制轉換為數字
var iNumber = Number(prompt("輸入一個5 到100 之間的數字", ""));//第二個參數,用于顯示輸入框的默認值
if(isNaN(iNumber))?????????? //判斷輸入的是否是數字 NaN “Not a Number” document.write("請確認你的輸入正確");
else if(iNumber > 100 || iNumber < 5)????????????? //判斷輸入的數字范圍document.write("你輸入的數字范圍不在 5 和 100 之間");
?
else
?
?
document.write("你輸入的數字是:" + iNumber);
?
?
446.
?
[思考題] switch
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點用法提示:
?
iWeek = parseInt(prompt("輸入 1 到 7 之間的整數","")); switch(iWeek){
case 1:
document.write("Monday"); break;
case 2:
document.write("Tuesday"); break;
case 3:
document.write("Wednesday"); break;
case 4:
document.write("Thursday"); break;
case 5:
document.write("Friday"); break;
case 6:
document.write("Saturday"); break;
case 7:
document.write("Sunday"); break;
default:
document.write("Error");
}
?
447.
?
[思考題] while 語句
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點用法提示:
var i=iSum=0; while(i<=100){
iSum += i; i++;
}
alert(iSum);
do.while for break continue (與JAVA 語法一致)
?
448.
?
[思考題]
函數
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點用法提示:
function ArgsNum(){
return arguments.length;
}
document.write(ArgsNum("isaac",25) + "<br>"); document.write(ArgsNum() + "<br>"); document.write(ArgsNum(3) + "<br>");
從這個例子可以看出,方法可以沒有參數,也可以沒有返回值,但是照樣可以傳入參數和返回值。
?
449.
?
[思考題] Date 對象
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點重點提示:
var myDate1 = new Date();???? //運行代碼前的時間for(var i=0;i<3000000;i++);
var myDate2 = new Date();???? //運行代碼后的時間document.write(myDate2);
?
var oMyDate = new Date();
var iYear = oMyDate.getFullYear();
var iMonth = oMyDate.getMonth() + 1; //月份是從 0 開始的
var iDate = oMyDate.getDate();
var iDay = oMyDate.getDay(); //0 為 星期日 1 為 星期一
function disDate(oDate, iDate){
var ms = oDate.getTime();??????????????? //換成毫秒數
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 = navigator.userAgent;
//檢測 Opera、KHTML
var isOpera = sUserAgent.indexOf("Opera") > -1;
var isKHTML = sUserAgent.indexOf("KHTML") > -1 || sUserAgent.indexOf("Konqueror") > -1
|| sUserAgent.indexOf("AppleWebKit") > -1;
//檢測 IE、Mozilla
var isIE = sUserAgent.indexOf("compatible")? >? -1? &&? sUserAgent.indexOf("MSIE")? >? -1 && !isOpera;
var isMoz = sUserAgent.indexOf("Gecko") > -1 && !isKHTML;
//檢測操作系統
var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows");
var isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") || (navigator.platform == "Macintosh");
var isUnix = (navigator.platform == "X11") && !isWin && !isMac; if(isOpera) document.write("Opera ");
if(isKHTML) document.write("KHTML "); if(isIE) document.write("IE ");
if(isMoz) document.write("Mozilla "); if(isWin) document.write("Windows"); if(isMac) document.write("Mac"); if(isUnix) document.write("Unix");
?
451.
?
[思考題] Global 對象
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點重點提示:
其實 isNan,paraseInt 等都是 Global 對象的方法
EncodeURI.因為有效的 URI 不能包含某些字符,如空格。這個方法就是用于將這個字符轉換成 UTF-8 編碼,使瀏覽器可以接受他們。
Var suil = “www.oseschool.com/pro file/a.html”; Alert(encodeURI(suil));//www.oseschool.com/pro%20file/a.html
?
即將空格編碼成%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 的數據Math.floor(Math.random()*10+1) 2~9 的數據Math.floor(Math.random()*9+2);
?
453.
?
[ 思 考 題 ] getElementsByTagName
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點提示:
function searchDOM(){
//放在函數內,頁面加載完成后才用<body>的 onload 加載,這時如果把 alert 這句改成用 document.write 則會把原內容覆蓋掉,因為是后面才執行的
var oLi = document.getElementsByTagName("li");
//輸出長度、標簽名稱以及某項的文本節點值
alert(oLi.length + " " +oLi[0].tagName + " " + oLi[3].childNodes[0].nodeValue);
?
var oUl = document.getElementsByTagName("ul"); var oLi2 = oUl[1].getElementsByTagName("li");
alert(oLi2.length + " " +oLi2[0].tagName + " " + oLi2[1].childNodes[0].nodeValue);
}
<body οnlοad="searchDOM()">
?
<ul>客戶端語言
<li>HTML</li>
<li>JavaScript</li>
<li id="cssLi">CSS</li>
</ul>
<ul>服務器端語言
<li>ASP.NET</li>
<li>JSP</li>
<li>PHP</li>
</ul>
</body>
?
454.
?
[ 思 考 題 ] getElementById
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點提示:
var oLi = document.getElementById("cssLi"); oLi.style .backgroundColor="yellow"
//輸出標簽名稱以及文本節點值
alert(oLi.tagName + " " + oLi.childNodes[0].nodeValue);
?
455.
?
[ 思 考 題 ] getElementsByName
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點提示:
alert(document.getElementsByName("a").length);
?
456.
?
[技巧題]
訪問子節點
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點
?
參考:
function myDOMInspector(){
var oUl = document.getElementById("myList");???? //獲取<ul>標記var DOMString = "";
if(oUl.hasChildNodes()){???????????????????????????????????????????????? //判斷是否有子節點var oCh = oUl.childNodes;
for(var i=0;i<oCh.length;i++)?????????????????????????????? //逐一查找DOMString += oCh[i].nodeName + "\n";
?
?
?
}
?
457.
?
}
alert(DOMString);
?
?
[技巧題]
訪問父節點
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
nodeName 如果為文本節點,則返回#text tagName 如果為文本節點,則返回 undefined function myDOMInspector(){
var myItem = document.getElementById("myDearFood"); alert(myItem.parentNode.tagName);
}
?
function myDOMInspector(){
var myItem = document.getElementById("myDearFood"); var parentElm = myItem.parentNode;
while(parentElm.className != "colorful" && parentElm != document.body) parentElm = parentElm.parentNode;????????????????????????????? //一路往上找
alert(parentElm.tagName);
}
<body οnlοad="myDOMInspector()">
<div class="colorful">
<ul>
<li>糖醋排骨</li>
<li>圓籠粉蒸肉</li>
<li>泡菜魚</li>
<li id="myDearFood">板栗燒雞</li>
<li>麻婆豆腐</li>
</ul>
</div>
?
</body>
?
458.
?
[技巧題]
訪問兄弟節點
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
function myDOMInspector(){
var myItem = document.getElementById("myDearFood");
//訪問兄弟節點
var nextListItem = myItem.nextSibling; var preListItem = myItem.previousSibling;
alert(nextListItem.tagName +" "+ preListItem.tagName);
}
在 Firefox 中不支持,但是 IE 中卻是支持的。
?
459.
?
[技巧題]
第一個 最后一個 子節點
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
function nextSib(node){
var tempLast = node.parentNode.lastChild;
//判斷是否是最后一個節點,如果是則返回 null if(node == tempLast)
return null;
var tempObj = node.nextSibling;
//逐一搜索后面的兄弟節點,直到發現元素節點為止while(tempObj.nodeType!=1 && tempObj.nextSibling!=null)
tempObj = tempObj.nextSibling;
//三目運算符,如果是元素節點則返回節點本身,否則返回 null return (tempObj.nodeType==1)?tempObj:null;
}
function prevSib(node){
var tempFirst = node.parentNode.firstChild;
//判斷是否是第一個節點,如果是則返回 null if(node == tempFirst)
?
return null;
var tempObj = node.previousSibling;
//逐一搜索前面的兄弟節點,直到發現元素節點為止while(tempObj.nodeType!=1 && tempObj.previousSibling!=null)
tempObj = tempObj.previousSibling; return (tempObj.nodeType==1)?tempObj:null;
}
function myDOMInspector(){
var myItem = document.getElementById("myDearFood");
//獲取后一個元素兄弟節點
var nextListItem = nextSib(myItem);
//獲取前一個元素兄弟節點
var preListItem = prevSib(myItem);
alert("后一項:" + ((nextListItem!=null)?nextListItem.firstChild.nodeValue:null) + " 前一項:" + ((preListItem!=null)?preListItem.firstChild.nodeValue:null) );
}
?
460.
?
[思考題] nodeType
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
元素element 1
屬性 attr 2
文本 text 3
注釋 comments??????? 8
文檔 document???????? 9 function showAttr(){
var btnShowAttr=document.getElementById("btnShowAttr"); //演示按鈕,有很多屬性var attrs=btnShowAttr.attributes;
for(var i=0;i<attrs.length ;i++){ var attr=attrs[i];
alert('nodeType:'+attr.nodeType); //attribute 的 nodeType=2 alert('attr:'+attr);
alert('attr.name:'+attr.name+'='+attr.value);
?
}
?
function showDocument(){ alert('nodeType:'+document.nodeType); //9 alert('nodeName:'+document.nodeName);
?
alert(document);
}
?
461.
?
[技巧題]
getAttribute setAttribute
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
function myDOMInspector(){
//獲取圖片
var myImg = document.getElementsByTagName("img")[0];
//獲取圖片 title 屬性
alert(myImg.getAttribute("title"));
}
?
function changePic(){
//獲取圖片
var myImg = document.getElementsByTagName("img")[0];
//設置圖片 src 和 title 屬性myImg.setAttribute("src","02.jpg"); myImg.setAttribute("title","紫荊公寓");
}
?
462.
?
[技巧題]
創建新節點
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
function createP(){
var op = document.createElement("p");
var otext = document.createTextNode("HHHHH"); op.appendChild(otext); op.setAttribute("style","text-align:center"); document.body.appendChild(op);
?
//創建完節點,就馬上會影響到下面的操作,比如P 的數量就會多 1 個
}
?
463.
?
[技巧題]
刪除節點
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
需要注意的是標簽之間的父子關系!!!
function deleteP(){
var oP = document.getElementsByTagName("p")[0]; oP.parentNode.removeChild(oP);??????????? //刪除節點
}
?
464.
?
[技巧題]
替換節點
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
function replaceP(){
var oOldP = document.getElementsByTagName("p")[0];
var oNewP = document.createElement("p");????????? //新建節點
var oText = document.createTextNode("這是一個感人肺腑的故事"); oNewP.appendChild(oText); oOldP.parentNode.replaceChild(oNewP,oOldP);??? //替換節點
}
?
465.
?
[技巧題]
插入節點
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
function insertP(){
var oOldP = document.getElementsByTagName("p")[0];
var oNewP = document.createElement("p");????????? //新建節點
var oText = document.createTextNode("這是一個感人肺腑的故事");
?
oNewP.appendChild(oText); oOldP.parentNode.insertBefore(oNewP,oOldP);?? //插入節點
}
沒有 insertAfter,但是可以自己寫一個function insertAfter(newElement, targetElement){
var oParent = targetElement.parentNode;????? //首先找到目標元素的父元素if(oParent.lastChild == targetElement) //如果目標元素已經是最后一個子元素了
oParent.appendChild(newElement);?????? //則直接用 appendChild()加到子元素列
表的最后
else?????????????????????????????????????????????????????????????????? //否則用insertBefore()插入到目標元素的下一個兄弟元素之前
oParent.insertBefore(newElement,targetElement.nextSibling);
}
function insertP(){
var oOldP = document.getElementById("myTarget");
var oNewP = document.createElement("p");????????? //新建節點
var oText = document.createTextNode("這是一個感人肺腑的故事"); oNewP.appendChild(oText);
insertAfter(oNewP,oOldP);?????????????? //插入節點
}
其實這個也是通過 insertBefore 原理來實現的
?
466.
?
[ 技 巧 題 ] cloneNode(deepBoolean)
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
復制并返回當前節點的復制節點,這個復制得到的節點是一個孤立的節點,不在document 樹中。復制原來節點的屬性值,包括 ID 屬性,所以在把這個新節點加到 document之前,一定要修改 ID 屬性,以便使它保持唯一。當然如果 ID 的唯一性不重要可以不做處理。這個方法支持一個布爾參數,當 deepBoolean 設置 true 時,復制 當前節點的所有子節
點,包括該節點內的文本。
<p id=”mypara”>11111</p> p=document.getElementById("mypara") pclone = p.cloneNode(true); p.parentNode.appendChild(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 = document.createDocumentFragment();????? //創建文檔碎片for(var i=0;i<aColors.length;i++){
var oP = document.createElement("p");
var oText = document.createTextNode(aColors[i]); oP.appendChild(oText);
oFragment.appendChild(oP);?????????? //將節點先添加到碎片中
?
?
?
}
?
468.
?
}
document.body.appendChild(oFragment);???? //最后一次性添加到頁面
?
?
[技巧題] innerHTML
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
function myDOMInnerHTML(){
var myDiv = document.getElementById("myTest"); alert(myDiv.innerHTML);?? //直接顯示 innerHTML 的內容
//修改 innerHTML,可直接添加代碼myDiv.innerHTML = "<img src='01.jpg' 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 = document.getElementsByTagName("ul")[0];
oMy.className =(oMy.className=="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 = document.getElementById("member").insertRow(2); //插入一行var aText = new Array();
aText[0] = document.createTextNode("fresheggs"); aText[1] = document.createTextNode("W610"); aText[2] = document.createTextNode("Nov 5th"); aText[3] = document.createTextNode("Scorpio");
?
aText[4] = document.createTextNode("1038818"); for(var i=0;i<aText.length;i++){
var oTd = oTr.insertCell(i); oTd.appendChild(aText[i]);
}
}
</script>
?
471.
?
[技巧題]
修改單元格內容
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
<script language="javascript"> window.οnlοad=function(){
var oTable = document.getElementById("member"); oTable.rows[3].cells[4].innerHTML = "lost";???????????????????????????????????????????????????????????????????????????????? //修改單元格內容
}
</script>
?
472.
?
[技巧題]
動態刪除
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
parentElement 是 IE dom, parentNode 是標準 DOM
?
<script language="javascript"> window.οnlοad=function(){
var oTable = document.getElementById("member");
oTable.deleteRow(2);?????????????? //刪除一行,后面的行號自動補齊//指從 table 中的第 2
行開始進行刪除
oTable.rows[2].deleteCell(1); //刪除一個單元格,后面的也自動補齊
}
</script>
?
<script language="javascript"> function myDelete(){
var oTable = document.getElementById("member");
//刪除該行this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
}
window.οnlοad=function(){
var oTable = document.getElementById("member"); var oTd;
//動態添加 delete 鏈接
for(var i=1;i<oTable.rows.length;i++){ oTd = oTable.rows[i].insertCell(5);
oTd.innerHTML = "<a href='#'>delete</a>"; oTd.firstChild.onclick = myDelete; //添加刪除事件
}
}
</script>
?
473.
?
[技巧題]
動態刪除列
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
<script language="javascript"> function deleteColumn(oTable,iNum){
//自定義刪除列函數,即每行刪除相應單元格for(var i=0;i<oTable.rows.length;i++)
oTable.rows[i].deleteCell(iNum);
}
window.οnlοad=function(){
var oTable = document.getElementById("member"); deleteColumn(oTable,2);
}
</script>
?
474.
?
[技巧題]
控制 textarea 的字符個數
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
<script language="javascript"> function LessThan(oTextArea){
//返回文本框字符個數是否符號要求的 boolean 值
return oTextArea.value.length < oTextArea.getAttribute("maxlength");
}
</script>
?
475.
?
[思考題] BOM 模型
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
瀏覽器對象模型,可以對瀏覽器窗口進行訪問和操作,使用 BOM,開發者可以移動窗口, 改變狀態欄中的文本等與頁面內容不相關的操作
Window 對象
這里可以用 window.frames[0]或者用 windows.frames[“topFrame”]來引用框架,也可以用 topl 來代替 window 屬性。Top.frames[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
向后一頁window.history.go(-1); 等于 history.back();
向前一頁window.history.go(1); 等于 history.forword(); Document
LastModified,title,URL 屬性都是比較常用
Location 對象
Navigator 對象
?
Screen 對象
?
476.
?
[思考題]
冒泡型事件
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
<script language="javascript"> function add(sText){
var oDiv = document.getElementById("display"); oDiv.innerHTML += sText;??????????????????????????????????????????????????????? //輸出點擊順序
}
</script>
</head>
<body οnclick="add('body<br>');">
<div οnclick="add('div<br>');">
<p οnclick="add('p<br>');">Click Me</p>
</div>
<div id="display"></div>
</body>
先執行最里面的 p,再往外執行
?
477.
?
[思考題]
監聽函數
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
<script language="javascript"> window.onload = function(){
var oP = document.getElementById("myP"); //找到對象oP.onclick = function(){??????? //設置事件監聽函數
alert('我被點擊了');
}
}
</script>
</head>
?
<body>
<div>
<p id="myP">Click Me</p>
</div>
</body>
?
Function a(){} oP.onclick = a
這樣會先把 a 函數加載到緩存,不是最佳方案
Var A = Function(){} oP.onclick = a
這樣只有在 onclick 事件發生的時候,加載該函數
若以上的監聽函數,在 onclick 的時候,需要執行多個函數,那就只能用以下的方法:
IE 標準:
<script language="javascript"> function fnClick(){
alert("我被點擊了");
oP.detachEvent("onclick",fnClick);?????????? //點擊了一次后刪除監聽函數
}
var oP;//聲明在函數外,這樣就可以兩個函數一起使用window.onload = function(){
oP = document.getElementById("myP");??????? //找到對象oP.attachEvent("onclick",fnClick);?????????? //添加監聽函數
}
</script>
</head>
?
<body>
<div>
<p id="myP">Click Me</p>
</div>
</body>
?
也可以添加多個監聽器
oP.attachEvent("onclick",fnClick1);???????? //添加監聽函數 1
oP.attachEvent("onclick",fnClick2);???????? //添加監聽函數 2
執行順序為 fnClick2-> fnClick1
但是以上的監聽器均為 IE 中的標準,而符合標準 DOM(firefox)的監聽器如下oP.addEventListener("click",fnClick1,false);??????????? //添加監聽函數 1
oP.addEventListener("click",fnClick2,false);??????????? //添加監聽函數 2
因此這種方式在 Firefox 中支持,而在 IE 中不支持為了兼容性,可這樣寫
if (el.addEventListener){
el.addEventListener('click', KindDisableMenu, false);
?
} else if (el.attachEvent){ el.attachEvent('onclick', KindDisableMenu);
}
第三個參數為 useCapture
而 useCapture 這個參數就是在控制這時候兩個 click 事件的先后順序。如果是 false,那就會使用 bubbling,他是從內而外的流程,所以會先執行藍色元素的 click 事件再執行紅色元素的 click 事件,如果是true,那就是 capture,和 bubbling 相反是由外而內
?
478.
?
[思考題]
事件的類型 event.type
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
IE 瀏覽器中事件對象是 window 對象的一個屬性event Op.onlick=function(){ var o = window.event}
而標準 DOM 中規定event 對象必須作為唯一的參數傳給事件處理函數
Op.οnclick=function(oevent){
}
因此為了兼容兩種瀏覽器,通常采用下面的方法
Op.οnclick=function(o){
If(window.event)//假如不等于空,則為 IE 瀏覽器
O = window.event;
}
?
<script language="javascript"> function handle(oEvent){
var oDiv = document.getElementById("display");
if(window.event) oEvent = window.event;?????????????? //處理兼容性,獲得事件對象if(oEvent.type == "click")??????????????????????????????????????????????????????????????????????????????????? //檢測事件名稱
oDiv.innerHTML += "你點擊了我  "; else if( oEvent.type == "mouseover")
oDiv.innerHTML += "你移動到我上方了  ";
}
window.onload = function(){
var oImg = document.getElementsByTagName("img")[0]; oImg.onclick = handle;
oImg.onmouseover = handle;
}
</script>
還有很多鼠標事件
window.onload = function(){
?
?
?
?
?
?
?
?
?
?
}
?
479.
?
var oImg = document.getElementsByTagName("img")[0]; oImg.onmousedown = handle;??????? //將鼠標事件除了 mousemove 外都監聽oImg.onmouseup = handle;
oImg.onmouseover = handle; oImg.onmouseout = handle; oImg.onclick = handle; oImg.ondblclick = handle;
?
?
[思考題]
事件的激活元素 event.srcElement 或者 target
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
<script language="javascript"> function handle(oEvent){
if(window.event) oEvent = window.event;?????????????? //處理兼容性,獲得事件對象var oTarget;
if(oEvent.srcElement)????????????????????????????????? //處理兼容性,獲取事件目標oTarget = oEvent.srcElement;?????????????????????????? //IE 支持的寫法
?
else
?
?
oTarget = oEvent.target;???????????????? //Firefox 支持的寫法
?
alert(oTarget.tagName);??????????????????????????? //彈出目標的標記名稱
}
window.onload = function(){
var oImg = document.getElementsByTagName("img")[0]; oImg.onclick = handle;
}
</script> event.button
<script language="javascript"> function TestClick(oEvent){
var oDiv = document.getElementById("display"); if(window.event)
oEvent = window.event;
oDiv.innerHTML += oEvent.button;???????? //輸出 button 的值
}
document.onmousedown = TestClick; window.onload = TestClick;???? //測試未按下任何鍵
</script>
</head>
?
?
<body>
<div id="display"></div>
</body>
?
在 IE/Opera 中,是 window.event,而在 Firefox 中,是event
而事件的對象,在 IE 中是 window.event.srcElement,在 Firefox 中是 event.target,而在Opera 中則兩者都支持。
在 IE 里面
左鍵是 window.event.button = 1 右鍵是 window.event.button = 2 中鍵是 window.event.button = 4
沒有按鍵動作的時候 window.event.button = 0
在 Firefox 里面
左鍵是 event.button = 0 右鍵是 event.button = 2 中鍵是 event.button = 1
沒有按鍵動作的時候 event.button = 0
在 Opera 7.23/7.54 里面
鼠標左鍵是 window.event.button = 1
沒有按鍵動作的時候 window.event.button = 1
右鍵和中鍵無法獲取鍵盤事件
window.onload = function(){
var oTextArea = document.getElementsByTagName("textarea")[0]; oTextArea.onkeydown = handle;?????????????????????????????????????????????????? //監聽所有鍵盤事件oTextArea.onkeyup = handle;
oTextArea.onkeypress = handle;
}
e.keyCode;
onkeypress 是在用戶按下并放開任何字母數字鍵時發生。系統按鈕(例如,箭頭鍵和功能鍵, Shift、Ctrl、Alt、F1、F2)無法得到識別。
onkeyup 是在用戶放開任何先前按下的鍵盤鍵時發生。
onkeydown 是在用戶按下任何鍵盤鍵(包括系統按鈕,如箭頭鍵和功能鍵)時發生屏蔽鼠標右鍵
第一種方式:
<script language="javascript"> function block(oEvent){
if(window.event)
oEvent = window.event; if(oEvent.button == 2)
alert("鼠標右鍵不可用");
}
document.onmousedown = block;
?
</script>
第二種方式:
<script language="javascript"> function block(oEvent){
if(window.event){
oEvent = window.event;
oEvent.returnValue = false;??? //取消默認事件 支持 IE
?
}else
?
}
?
?
oEvent.preventDefault();???????? //取消默認事件 支持 Firefox
?
document.oncontextmenu = block;
</script>
?
480.
?
[技巧題]
伸縮的菜單
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考題參考:
<script language="javascript"> function change(){
//通過父元素 li,找到兄弟元素 ul
var oSecondDiv = this.parentNode.getElementsByTagName("ul")[0];//這里的 this 就是下面的 OA
//CSS 交替更換來實現顯、隱
if(oSecondDiv.className == "myHide") oSecondDiv.className = "myShow";
?
else
?
}
?
?
oSecondDiv.className = "myHide";
?
window.onload = function(){
var oUl = document.getElementById("listUL"); var aLi = oUl.childNodes;??????????????????????????????????????????????????????? //子元素
var oA;
for(var i=0;i<aLi.length;i++){
//如果子元素為 li,且這個 li 有子菜單 ul
if(aLi[i].tagName == "LI" && aLi[i].getElementsByTagName("ul").length){ oA = aLi[i].firstChild;?????????????????????????????????????????????? //找到超鏈接
oA.onclick = 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"> window.onerror = 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 優化
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考知識點參考:
.實例
1 圖片查看器
<html>
<head>
<title></title>
<script>
?
function showPic(obj){
var h = obj.getAttribute("href"); document.getElementById("image").setAttribute("src",h);
}
</script>
</head>
<body>
<h1>Snapshots</h1>
<ul>
<li><a href="photo/01.jpg" title="a" οnclick="showPic(this);return false;">01</a></li>
<li><a href="photo/02.jpg" title="b" οnclick="showPic(this);return false;">02</a></li>
<li><a href="photo/03.jpg" title="c" οnclick="showPic(this);return false;">03</a></li>
<li><a href="photo/04.jpg" title="d" οnclick="showPic(this);return false;">04</a></li>
?
<li><a href="photo/05.jpg" title="e" οnclick="showPic(this);return false;">05</a></li>
</ul>
<img id="image" src="photo/01.jpg" 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”>
window.onload = prepareGalley;
function prepareGalley(){
var img_ul = document.getElementById("img_ul"); var links = img_ul.getElementsByTagName("a");
?
for(var i=0;i<links.length;i++){ links[i].onclick = function(){
showPic(this); return false;
}
}
}
有一個問題,如果 onload 的函數有多個怎么辦?
window.onload = prepareGalley1; window.onload = prepareGalley2;
顯然,這樣第一個函數就會被第二個函數覆蓋??梢赃@樣寫
Window.onload = function(){ prepareGalley1(); prepareGalley2();
}
還有一個比這個更NB 的寫法,由 Simon Willison 寫的
function addLoadEvent(func){
var oldonload = window.onload; if(typeof window.onload !='function'){
window.onload = func;
}else{
window.onload = function(){ oldonload();
func();
}
}
}
?
addLoadEvent(prepareGalley1); addLoadEvent(prepareGalley2);
?
486.
?
[問答題]
編寫一個方法 求一個字符串的字節長度
?
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考題參考:
new function(s){
if(!arguments.length||!s) return null; if(""==s) return 0;
var l=0;
for(var i=0;i<s.length;i++){ if(s.charCodeAt(i)>255) l+=2; else l++;
}
alert(l);
}("hello world!");
?
487.
?
[問答題]
如何控制 alert 中的換行
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考題參 考 : alert("hello\nworld");
?
488.
?
[問答題]
解釋 document.getElementById("ElementID").style.fontSize="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;}
Clock.innerHTML=d.getFullYear()+" 年"+t(d.getMonth()+1)+" 月"+t(d.getDate())+"
日"+t(d.getHours())+"時"
+t(d.getMinutes())+"分"+t(d.getSeconds())+"秒"; window.setTimeout("tick()",1000);
}
window.οnlοad=tick;
</script>
?
<body>
<div id="Clock"></div>
</body>
?
490.
?
[問答題]
編寫一個方法 去掉一個數組的重復元素
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考題參考:
Array.prototype.strip=function(){ if(this.length<2) return [this[0]]||[]; var arr=[];
for(var i=0;i<this.length;i++){
arr.push(this.splice(i--,1));//將本數組中第一個元素取出放入到數組 arr 中
?
?
?
?
?
?
的元素
?
for(var j=0;j<this.length;j++){ if(this[j]==arr[arr.length-1]){
this.splice(j--,1);//刪除本數組中與數組 arr 中最后一個元素相同
?
}
}
}
return arr;
}
?
var arr=["abc",85,"abc",85,8,8,1,2,5,4,7,8];
?
alert(arr.strip());
?
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 方法
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考題參考:
Array.prototype.indexOf = function(e){ for(var i=0,j; j=this[i]; i++){
if(j==e){return i;}
?
}
return -1;
}
?
Array.prototype.lastIndexOf = function(e){ for(var i=this.length-1,j; j=this[i]; i--){
if(j==e){return i;}
}
return -1;
}
?
var arr=[1,2,3,4,5]; alert(arr.indexOf(5));
?
494.
?
[問答題]
說說元素克隆
?
----------------------------------------------------------------------------------------------------------------------------
來自:前端開發面試易考題參考:
淺復制(影子克隆):只復制對象的基本類型,對象類型,仍屬于原來的引用
深復制(深度克隆):不緊復制對象的基本類,同時也復制原對象中的對象.就是說完全是新對象產生的
Object.prototype.Clone = function(){ var objClone;
if( this.constructor == Object ) objClone = new this.constructor();
else
objClone = new this.constructor(this.valueOf()); 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];
}
}
}
objClone.toString = this.toString; objClone.valueOf = this.valueOf; return objClone;
}
?
?
總結
以上是生活随笔為你收集整理的JavaScript 习题及面试题 3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言入门自学课件ppt,C语言从初学到
- 下一篇: SpringBoot——springbo