前端开发面试基础题

发布于 2022-11-23 23:24:43 字数 25529 浏览 9 评论 0

添加多个 onload 事件

functionaddLoadEvent(func){
   var oldonload=window.onload;
   if(typeofwindow.onload!= 'function'){
       window.onload=func;
   }
   else{
       window.onload=function(){
           oldonload();
           func();
       }
   }

}

处理 ActiveXObject/XMLHttpRequest 问题

//第一种写法,《js高级程序设计》的写法  惰性载入技巧
function createXHR(){ if(typeof XMLHttpRequest!="undefined"){ // XMLHttpRequest createXHR=function(){ returnnew XMLHttpRequest(); }; }elseif(typeof ActiveXObject!="undefined"){//IE ActiveXObject createXHR=function(){ if(typeofarguments.callee.activeXString!="string"){ var versions=["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],//IE i,len; for(i=0,len=versions.length;i<len;i++){ try{ new ActiveXObject(versions[i]); arguments.callee.activeXString=version[i]; break; }catch(ex){} } } returnnew ActiveXObject(arguments.callee.activeXString); }; }else{ createXHR=function(){ thrownewError("fail"); } } return createXHR(); } // 第二种写法
function createXHR(){ if(typeof XMLHttpRequest=="undefined"){ XMLHttpRequest= function () { try{ returnnew ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e){} try{ returnnew ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e){} try{ returnnew ActiveXObject("Msxml2.XMLHTTP"); } catch (e){} returnfalse; } } returnnew XMLHttpRequest(); }

请求对象的属性和方法设置

var xhr=createXHR();
xhr.onreadystatechange=function(){//firfox引入onlaod,readyState==4时触发,代替onreadystatechangeif(xhr.readyState==4){
        try{
            if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
                alert(xhr.responseText);
            }else {
                alert("unsuccessful");
            }
        }catch(ex){}
    }
}
xhr.onload=function(){
    if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
                alert(xhr.responseText);
            }else {
                alert("unsuccessful");
            }
}
xhr.onprogress=function(event){
    if(event.lengthComputable){//进度信息是否可用console.log("Received"+event.position+"of"+event.totalSize);
    }
}
xhr.onerror=function(){
    alert("error");
}
xhr.timeout=1000;
xhr.ontimeout=function(){
    alert("timeout");
}
xhr.open("get","example.php",true);
xhr.overrideMimeType("text/xml");
xhr.send(null);//GET

发送表单数据

var form=document.getElementById("info");
xhr.send(serialize(form));//第一种写法
xhr.send(new FormData(form));//第二种写法

跨浏览器的 CORS

functioncreateCORSRequest(method,url){
    var xhr=new XMLHttpRequest();
    if("withCredentials"in xhr){
        xhr.open(method,url,true);
    }elseif(typeof XDomainRequest !="undefined"){
        xhr=new XDomainRequest();
        xhr.open(method,url);
    }else {
        xhr=null;
    }
    return xhr;
}
var request=createCORSRequest("get","http://www.somewhere");
if(request){
    request.onload=function(){};
    request.send();
}

跨浏览器事件处理程序

var eventUtil={
   // 页面加载完成后
   readyEvent : function(fn) {
       if (fn==null) {
           fn=document;
       }
       var oldonload = window.onload;
       if (typeofwindow.onload != 'function') {
           window.onload = fn;
       } else {
           window.onload = function() {
               oldonload();
               fn();
           };
       }
   },

   addEventHandler: function (obj, eventName, handler) {
       if (document.attachEvent) {//IE
           obj.attachEvent("on" + eventName, handler);
       } elseif (document.addEventListener) {//DOM2级
           obj.addEventListener(eventName, handler, false);//false- 默认。事件句柄在冒泡阶段执行
       }
       else{//https://github.com/libin1991/libin_Blog/issues/DOM0级
           obj['on'+eventName]=handler;
       }
   },

   removeEventHandler:function(obj, eventName, handler){
       if (document.attachEvent) {//IE
           obj.detachEvent("on" + eventName, handler);
       } elseif (document.addEventListener) {//DOM2级
           obj.removeEventListener(eventName, handler, false);
       }
       else{//https://github.com/libin1991/libin_Blog/issues/DOM0级
           obj['on'+eventName]=null;
       }
   },
  //获取event对象的引用,取到事件的所有信息,确保随时能使用event;
   getEvent: function (e) {
       var ev = e || window.event;
       if (!ev) {
           var c = this.getEvent.caller;
           while (c) {
               ev = c.arguments[0];
               if (ev && Event == ev.constructor) {
                   break;
               }
               c = c.caller;
           }
       }
       return ev;
   },
   //事件类型
   getType: function (e) {
       return e.type;

   },
   //调用事件的元素
   getElement: function (e) {
       return e.target|| e.srcElement;
   },
   //阻止默认事件
   preventDefault: function (e) {
       e= this.getEvent(e);
       if(e.preventDefault){
           e.preventDefault();
       }
       else {
           return e.returnValue=false;//IE
       }
   },
   //阻止冒泡
   stopPropagation:function(e) {
     if(e.stopPropagation){
         e.stopPropagation();
     }
       else {
         e.cancelBubble=true;//IE
     }

   },
   //键盘事件键盘的编号
   getCharCode:function (e){
       if(typeof e.charCode=="number")return e.charCode;
       elsereturn e.keyCode;
   },
   //获取剪贴板的文本
   getClipbordText:function(e){
       var clipboardData=(e.clipboardData||window.clipboardData);
       return clipboardData.getData("text");
   },
   //设置剪贴板文本
   setClipboardText:function(e,value){
       if(e.clipboardData){
           return e.clipboardData.setData("text/plain",value);
       }elseif(window.clipboardData){
           returnwindow.clipboardData.setData("text",value);
       }
   },

}

处理 target/srcelemnt 问题 代替this

functiongetActivatedObject(e) {
   var obj;
   if (!e) {
       // early version of IE
       obj = window.event.srcElement;
   } elseif (e.srcElement) {
       // IE 7 or later
       obj = e.srcElement;
   } else {
       // DOM Level 2 browser
       obj = e.target;
   }
   return obj;
}

实现 insertAfter

/**
* 把 newElement 插在 targetElement 后面 ,js 的 API 只有 insertBefore,没有 insertAfter
*/
function insertAfter(newElement,targetElement) { var parent = targetElement.parentNode; if (parent.lastChild == targetElement) { parent.appendChild(newElement); } else { parent.insertBefore(newElement,targetElement.nextSibling); } }

给 element 加上类名

function addClass(element,value) {
   if (!element.className) {
       element.className = value;
   } else {
       newClassName = element.className;
       newClassName+= " ";
       newClassName+= value;
       element.className = newClassName;
   }
}

判断是不是数组

functionisArray(arg) {
   // return Object.prototype.toString.call(arr)=='[Object Array]';这种方法也可以
if (typeof arg == 'object') { // 所有数组都有一个包含单词'arry'的constructor,最后的i表示不区分大小写
var criteria = arg.constructor.toString().match(/array/i); return (criteria != null); } returnfalse; }

IE10 之前不支持 docunment.getElementByClassName

function getByClass(clsName,parent){
   if(docunment.getElementByClassName) return docunment.getElementByClassName(clsName);
   //IE10之前var oParent=parent?document.getElementById(parent):document,
       eles=[],
       elements=oParent.getElementsByTagName('*');

   for(var i=0,l=elements.length;i<l;i++){
       if(elements[i].className==clsName){
           eles.push(elements[i]);
       }
   }
   return eles;
}

获取 css 样式

function getStyle(obj,attr){
   if(obj.currentStyle) {//IE 浏览器return obj.currentStyle[attr];
   }else{//Firefox浏览器return getComputedStyle(obj,false)[attr];
   }
}

手写动画

// 动画
startMove(oLi,{width:400,height:200,opacity:100})
function startMove(obj,json,fn){ clearInterval(obj.timer); obj.timer=setInterval(function () { for(var attr in json){ var cur=0; if(attr=='opacity'){ cur=Math.round(parseFloat(getStyle(obj,attr))*100); } else { cur=parseInt(getStyle(obj,attr)); } var speed=(json[attr]-cur)/8; speed=speed>0?Math.ceil(speed):Math.floor(speed); var flag=true; if(cur!=json[attr]){//使得所有属性做完运动才结束 flag=false; } if(attr=='opacity'){ obj.style.filter='alpha(opacity:'+(cur+speec)+')'; obj.style.opacity=(cur+speed)/100; } else{ obj.style[attr]=(cur+speed)+'px'; } } if(flag){ clearInterval(obj.timer); if(fn){ fn(); } } }) }

取得窗口左边和上边的位置

var leftPos=(type of window.screenLeft =="number")?window.screenLeft:window.screenX;

取得页面视口大小

var pageWidth=window.innerWidth,
   pageHeight=window.innerHeight;
   if(typeof pageHeight!="number"){
       if(document.compatMode=="CSS1Compat"){//标准模式
           pageHeight=window.documentElement.clientHeight;
           pageWidth=window.documentElement.clientWidth;
       }
       else {//BackCompat
           pageHeight=window.body.clientHeight;
           pageWidth=window.body.clientWidth;
       }
   }

检测插件方法

/**
*
* 检测插件方法一,IE下无效
*/functionhasPlugin(name){
   name=name.toLowerCase();
   for(var i=0;i<navigator.plugins.length;i++){
       if(navigator.plugins[i].toLowerCase().indexOf(name)!=-1)
       returntrue;
   }
   returnfalse;
}

/**
* 检测IE插件方法二 ,name是COM对象唯一标识符
*/functionhasIEPlugin(name){
   try{
       new ActiveXObject(name);
       returntrue;
   }catch(ex){
       returnfalse;
   }
}

获取元素

function getElement(id){
   if(document.getElementById){
       returndocument.getElementById(id);
   }elseif(document.all){//IE5前returndocument.all[id];
   }else {
       thrownewError("no way to retrieve element!");
   }
}

检查对象的某个特性是否存在

function isHostMethod(object,property){
   var t =typeof object[property];
   return t=="function"||
          (!!(t=="object")&&object[property])||
          t=="unknown";//不懂
}

对象转换成数组

function convertToArray(nodes){
   var array=null;
   try{
       array=Array.propotype.slice.call(nodes,0);//IE8前无效
   }catch(ex){
       for(var i=0,len=nodes.length;i<len;i++){
           array.push(nodes[i]);
       }
   }
}

返回指定的属性

/**
* 返回指定的属性 IE ele.attribute[]
* Element.getAttribute()
*/
function outputAttribute(ele){ var pairs=newArray(), attrname,attrvalue,u,len; for(i=0,len=ele.attribute.length;i<len;i++){ attrname=ele.attributes[i].nodeName; attrvalue=ele.attributes[i].nodeValue; if(ele.attributes[i].specified){//IE pairs.push(attrname+'=\"'+attrvalue+'\"'); } } }

ele 是否存在指定属性

/**
* 
* ele是否存在指定属性 attr
*/
function hasattribute(ele,attr){ if(ele.hasAttribute){ return ele.hasAttribute(attr); }else {//IEreturn ele.attributes[attr].specified; } }

ele 是否符合选择器 selector

/**
* ele是否符合选择器selector
*/
function matchesSelector(ele,selector){ if(ele.matchesSelector){ return ele.matchesSelector(selector); }elseif(ele.msmatchesSelector){ return ele.msmatchesSelector(selector); }elseif(ele.mozmatchesSelector){ return ele.mozmatchesSelector(selector); }elseif(ele.webkitmatchesSelector){ return ele.webkitmatchesSelector(selector); }else{ thrownewError("not support"); } }

获取内文本

//innerText/textContent
function getInnerText(ele){ return (typeof ele.innerText=="string")? ele.innerText:ele.textContent; }

获取鼠标事件的父元素

function getRelatedTarget(e){
       if(e.relatedTarget) return e.relatedTarget;
       elseif(e.fromElement) return e.fromElement;//mouseoverelseif(e.toElement) return e.toElement;//mouseoutelsereturnnull;
   }

探测按的是鼠标的哪个键

function getButton(e){
       if(document.implementation.hasFeature("MouseEvents","2.0")){
           return e.button;
       }else {
           switch(e.button){
               case0 :
               case1:
               case3:
               case5:
               case7: return0;
               case2:
               case6:return2;
               case4:return1;
           }
       }
   }

鼠标滚动事件

// 鼠标滚动,正数表示向上滚动
function getWheelDelta(e){ if(e.wheelData){ return (client.engine.opera&&client.engine.opera<9.5)? -e.wheelData:e.wheelData; }else { return -e.detail*40;//firefox } }

提取选中的文本

function getSelectedText(textbox){
   if(typeof selectionStart=="number"){
       return textbox.value.subString(textbox.selectionStart,textbox.selectionEnd);
   }elseif(document.selection){//IE8之前没有selectionStart,selectionEnd属性returndocument.selection.createRange().text;
   }
}

设置文本选中

function selectText(textbox,startIndex,stopIndex){
    if(textbox.setSelectionRange){
        textbox.setSelectionRange(startIndex,stopIndex);
    }elseif(textbox.createTextRange){//IEvar range=textbox.createTextRange();
        range.collapse(true);
        range.moveStart("character",0);
        range.moveEnd("character",stopIndex-startIndex);
        range.select();
    }
}

bind方法对老版本的浏览器不起作用

Function.prototype.bind = Function.prototype.bind || function(context){
     var self = this;

     returnfunction(){
       return self.apply(context, arguments);
     };
   }

包装 cookie

//cookievar
cookieUtil={ // 创建cookie setcookie:function (name, value, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value); if (expires instanceofDate) { cookieText += '; expires=' + expires.toGMTString(); } if (path) { cookieText += '; path=' + path; } if (domain) { cookieText += '; domain=' + domain; } if (secure) { cookieText += '; secure'; } document.cookie = cookieText; }, // 获取cookie getcookie:function (name) { var cookieName = encodeURIComponent(name) + '='; var cookieStart = document.cookie.indexOf(cookieName); var cookieValue = null; if (cookieStart > -1) { var cookieEnd = document.cookie.indexOf(';', cookieStart); if (cookieEnd == -1) { cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd)); } return cookieValue; }, // 删除cookie unsetcookie:function (name,path,domain,secure) { this.setcookie(name,"",newDate(0),path,domain,secure); } }

包装子cookie

//子cookievar subcookieUtil={
   get:function(name,subname){
       var subcookie=getAll(name);
       if(subcookie){
           return subcookie[subname];
       }else {
           returnnull;
       }
   },
   getAll:function(name){
       var cookieName = encodeURIComponent(name) + '=';
       var cookieStart = document.cookie.indexOf(cookieName);
       var cookieValue = null;
       var subcookie,result={};
       var len,i,parts;
       if (cookieStart > -1) {
           var cookieEnd = document.cookie.indexOf(';', cookieStart);
           if (cookieEnd == -1) {
           cookieEnd = document.cookie.length;
          }
       cookieValue = document.cookie.substring(cookieStart + cookieName.length, cookieEnd);
       if(cookieValue.length>0){
           subcookie=cookieValue.split('&');
           len=subcookie.length;
           for(i=0;i<llen;i++){
               parts=subcookie[i].split('=');
               result[parts[0]]=parts[1];
           }
           return result;
       }
      }
   returnnull;
   },
   
   set:function (name, subname,value, expires, path, domain, secure) {
       var subcookies=this.getAll(name)||{};
       subcookies[subname]=value;
       this.setAll(name,subcookies,expires,path,domain,secure);
   },
   
   setAll:function(name,subcookies,expires,path,domain,secure){
       var cookieText = encodeURIComponent(name) + '=';
       var subcookiesParts=newArray();
       var subname;
       for(subname in subcookies){
           if(subname.length>0&&subcookies.hasOwnProperty(subname)){
               subcookiesParts.push(encodeURIComponent(subname)+'='+encodeURIComponent(subcookies[subname]));
           }
       }
       if(subcookiesParts.length>0){
           cookieText+=subcookiesParts.join('&');
           if (expires instanceofDate) {
               cookieText += '; expires=' + expires.toGMTString();
           }
           if (path) {
               cookieText += '; expires=' + expires;
            }
           if (domain) {
               cookieText += '; domain=' + domain;
           }
           if (secure) {
               cookieText += '; secure';
           }
       }
   
       document.cookie = cookieText;
   },
   unset:function(name,subname,path,domain,secure){
         var subcookies=this.getAll(name);
       if(subcookies){
             delete subcookies[subname];
             this.setAll(name,subcookies,null,path,domain,secure);
         }
       },
   unsetAll:function(name,path,domain,secure){
         this.setAll(name,null,newDate(0),path,domain,secure);
   }
}

indexedDB

var indexedDB=window.indexedDB||window.mozIndexedDB||window.msIndexedDB||window.webkitIndexedDB;
var idbRequest=indexedDB.open('vvv');
idbRequest.onsuccess=function(event){
   database=event.target.result;
}
idbRequest.onerror=function(event){
   alert(event.target.errorCode);
}

手写 typeof

functiontype(obj) {
   var toString = Object.prototype.toString;
   var map = {
       '[object Boolean]'  : 'boolean', 
       '[object Number]'   : 'number', 
       '[object String]'   : 'string', 
       '[object Function]' : 'function', 
       '[object Array]'    : 'array', 
       '[object Date]'     : 'date', 
       '[object RegExp]'   : 'regExp', 
       '[object Undefined]': 'undefined',
       '[object Null]'     : 'null', 
       '[object Object]'   : 'object'
   };
   if(obj instanceof Element) {//因为对不同标签,toString会返回对应不同标签的构造函数return'element';
   }
   return map[toString.call(obj)];
}

深度克隆

/**
* 深度克隆方法一,用的是 instanceof
*/
function clone(Obj) { var buf; if (Obj instanceofArray) { buf = []; // 创建一个空的数组var i = Obj.length; while (i--) { buf[i] = clone(Obj[i]); } return buf; } elseif (Obj instanceofObject){ buf = {}; // 创建一个空对象for (var k in Obj) { // 为这个对象添加新的属性 buf[k] = clone(Obj[k]); } return buf; }else{ return Obj; } } /** * 深度拷贝方法二,用的是 toString */
function deepClone(data) { var t = type(data), o, i, ni; if(t === 'array') { o = []; }elseif( t === 'object') { o = {}; }else { return data; } if(t === 'array') { for (i = 0, ni = data.length; i < ni; i++) { o.push(deepClone(data[i])); } return o; }elseif( t === 'object') { for( i in data) { o[i] = deepClone(data[i]); } return o; } } //通过JSON.stringify一下,然后再JSON.parse一下,就能实现深拷贝。但是数据类型只支持基本数值类型。var obj = { a: 'a', b: function(){console.log('b')} } JSON.stringify(obj);// "{"a":"a"}"

组合使用构造函数模式和原型模式创建对象

//组合使用构造函数模式和原型模式创建对象functionPerson(name,age){
   this.name=name;
   this.age=age;
   this.friends=["may","john"];
}
Person.prototype={
   constructor:Person,//字面量形式的原型默认构造函数是object,所以在这里要指定constructor
   sayName=function(){
       alert(this.name);
   }
}

组合继承

//组合继承
funcion super(name){
   this.name=name;
   this.color=["red","blue"];
   
}
Super.prototype.sayname=function(){
   alert(this.name);
}
functionSub(age){
   Super.call(this);
   this.age=age;
}
Sub.prototype=new Super();//
Sub.prototype.constructor=Sub;//这个很重要!!
Sub.prototype.sayage=function(){
   alert(this.age);
}

观察者模式

//观察者模式functionEventTarget(){     
   this.handlers = {}; 
} 
EventTarget.prototype = {     
   constructor: EventTarget,
   addHandler: function(type, handler){
        if (typeofthis.handlers[type] == "undefined"){
             this.handlers[type] = [];
        }
        this.handlers[type].push(handler);
    }, 
   fire: function(event){//执行if (!event.target){
            event.target = this;
        }
        if (this.handlers[event.type] instanceofArray){
            var handlers = this.handlers[event.type];
            for (var i=0, len=handlers.length; i < len; i++){
                handlers[i](event); 
           }
        }
    },
    removeHandler: function(type, handler){ 
       if (this.handlers[type] instanceofArray){ 
           var handlers = this.handlers[type]; 
           for (var i=0, len=handlers.length; i < len; i++){ 
               if (handlers[i] === handler){ 
                   break;
                }
            }
            handlers.splice(i, 1); 
         }
     }
};

分享一个题目

//[附加题] 请实现下面的自定义事件 Event 对象的接口,功能见注释(测试1)//该 Event 对象的接口需要能被其他对象拓展复用(测试2)//测试1
Event.on('test', function (result) {
   console.log(result);
});
Event.on('test', function () {
   console.log('test');
});
Event.emit('test', 'hello world'); // 输出 'hello world' 和 'test'// 测试2var person1 = {};
var person2 = {};
Object.assign(person1, Event);
Object.assign(person2, Event);
person1.on('call1', function () {
   console.log('person1');
});
person2.on('call2', function () {
   console.log('person2');
});
person1.emit('call1'); //输出 'person1'
person1.emit('call2'); // 没有输出
person2.emit('call1'); // 没有输出
person2.emit('call2'); // 输出 'person2'var Event = {
   // 通过on接口监听事件eventName// 如果事件eventName被触发,则执行callback回调函数
   on: function (eventName, callback) {
       //你的代码if(!this.handles){
           //Object.assign(target, source);//这个是ES6的新对象方法,用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
Object.defineProperty(this, "handles", { value: {}, enumerable: false,//关键! configurable: true, writable: true }) } if(!this.handles[eventName]){ this.handles[eventName]=[]; } this.handles[eventName].push(callback); }, // 触发事件 eventName emit: function (eventName) { //你的代码if(this.handles[arguments[0]]){ for(var i=0;i<this.handles[arguments[0]].length;i++){ this.handles[arguments[0]][i](arguments[1]); } } } }; //输出所有页面宽度和高度大于50像素的节点。functiontraverse(oNode) { var aResult = []; oNode = oNode || document.body; if (oNode.style) { var nWidth = window.parseInt(oNode.style.width, 10) || 0; var nHeight = window.parseInt(oNode.style.height, 10) || 0; if (nWidth > 50 && nHeight > 50) { aResult.push(oNode); } } var aChildNodes = oNode.childNodes; if (aChildNodes.length > 0) { for (var i = 0, l = aChildNodes.length; i < l; i++) { var oTmp = aChildNodes[i]; aResult = aResult.concat(traverse(oTmp)); } } return aResult; }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

列表为空,暂无数据

关于作者

征棹

暂无简介

0 文章
0 评论
0 人气
更多

推荐作者

深爱成瘾

文章 0 评论 0

甜点

文章 0 评论 0

Ss Yy

文章 0 评论 0

dgmis009

文章 0 评论 0

花想c

文章 0 评论 0

樱花落人离去

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击“接受”或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。