前端常见面试题

4 篇文章 0 订阅
4 篇文章 0 订阅

1.CSS实现垂直水平居

CSS实现垂直水平居中

一道经典的问题,实现方法有很多种,以下是其中一种实现:

HTML结构:

<div class="wrapper">

     <div class="content"></div>

</div>

CSS:

.wrapper {

    position: relative;

    width: 500px;

    height: 500px;

    border: 1px solid red; 

 }

.content{

    position: absolute;

    width: 200px;

    height: 200px;

    /top、bottom、left和right 均设置为0/

    top: 0;

    bottom: 0;

    left: 0;

    right: 0;

    /margin设置为auto/

    margin:auto;

    border: 1px solid green;    

} 

2.三个盒子,左右定宽,中间自适应有几种方法

三个盒子,左右定宽,中间自适应有几种方法

第一种:左右侧采用浮动 中间采用margin-left 和 margin-right 方法。

代码如下:

<div style="width:100%; margin:0 auto;"> 

 

       <div style="width:200px; float:right; background-color:#960">这是右侧的内容 固定宽度</div>

 

       <div style="width:150px; float:left; background:#6FF">这是左侧的内容 固定宽度</div>

 

       <div style="margin-left:150px;margin-right:200px; background-color:#9F3">中间内容,自适应宽度</div>

 

    </div>

3.数组的常用方法

Array 数组的常用方法
concat() 连接两个或更多的数组,并返回结果。
join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
pop() 删除并返回数组的最后一个元素。  
shift() 删除并返回数组的第一个元素
push() 向数组的末尾添加一个或更多元素,并返回新的长度。
unshift() 向数组的开头添加一个或更多元素,并返回新的长度。
reverse() 颠倒数组中元素的顺序。
slice() 从某个已有的数组返回选定的元素
sort() 对数组的元素进行排序
splice() 删除元素,并向数组添加新元素。
toString() 把数组转换为字符串,并返回结果。

4.编写一个方法 去掉一个数组的重复元素

编写一个方法 去掉一个数组的重复元素

方法一:

var arr = [0,2,3,4,4,0,2];

var obj = {};

var tmp = [];

for(var i = 0 ;i< arr.length;i++){

   if( !obj[arr[i]] ){

      obj[arr[i]] = 1;

      tmp.push(arr[i]);

   }

}

console.log(tmp);



5.怎样添加、移除、移动、复制、创建和查找节点?

怎样添加、移除、移动、复制、创建和查找节点?

 1)创建新节点

  createDocumentFragment() //创建一个DOM片段

  createElement() //创建一个具体的元素

  createTextNode() //创建一个文本节点

2)添加、移除、替换、插入

  appendChild() //添加

  removeChild() //移除

  replaceChild() //替换

  insertBefore() //插入

3)查找

  getElementsByTagName() //通过标签名称

  getElementsByName() //通过元素的Name属性的值

        getElementById() //通过元素Id,唯一性



写出3个使用this的典型应用

(1)、在html元素事件属性中使用,如:

<input type=”button” onclick=”showInfo(this);” value=”点击一下”/>2)、构造函数

function Animal(name, color) {

  this.name = name;

  this.color = color;

}3)、input点击,获取值

<input type="button" id="text" value="点击一下" />

<script type="text/javascript">

    var btn = document.getElementById("text");

    btn.onclick = function() {

        alert(this.value);    //此处的this是按钮元素

    }

</script>

(4)、apply()/call()求数组最值

var  numbers = [5, 458 , 120 , -215 ]; 

var  maxInNumbers = Math.max.apply(this, numbers);  

console.log(maxInNumbers);  // 458

var maxInNumbers = Math.max.call(this,5, 458 , 120 , -215); 

console.log(maxInNumbers);  // 458



6.new操作符到底到了什么?


new操作符到底到了什么?

先看代码

[javascript] view plain copy

1. var Func=function(){  
2. };  
3. var func=new Func ();  

new共经过了4几个阶段

1、创建一个空对象

[javascript] view plain copy

1. varobj=new Object();  

2、设置原型链

[javascript] view plain copy

1. obj.proto= Func.prototype;  

3、让Func中的this指向obj,并执行Func的函数体。

[javascript] view plain copy

1. var result =Func.call(obj);  

4、判断Func的返回值类型:

如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象。

[javascript] view plain copy

1. if (typeof(result) == "object"){  
2. func=result;  
3. }  
4. else{  
5. func=obj;;  
6. }  

7 js 定义函数的几种方法 以及如何调用

/*1.方法调用模式:
    先定义一个对象,然后在对象的属性中定义方法,通过myobject.property来执行方法,this即指当前的myobject 
    对象。*/
        var car = {
            carId:123,
            carName:"奥迪",
            carColor:"red",
            say:function(){
                console.log(this.carName+" color is "+this.carColor);
            }
        };
        car.say();

    /*2.函数调用模式
    定义一个函数,设置一个变量名保存函数,这时this指向到window对象。*/
        var mycar = function(name,color){
          return "my car is " +color+" and "+name ;
        }
        console.log(mycar("奥迪","红色"));

    /*3.构造器调用模式
    定义一个函数对象,在对象中定义属性,在其原型对象中定义方法。在使用prototype的方法时,必须实例化该对象才能调用其方法。*/
        var yourcar = function(name,color){
            this.name = name;
            this.color = color;
        };
        yourcar.prototype ={
            say:function(){
                console.log("your car is " +this.name + " and " +this.color);
            }
        };
        var yourcar = new yourcar("奔驰","蓝色");
        yourcar.say();

    /*4.apply,call调用模式*/
        function count(num1, num2) { 
            return num1 + num2; 
        } 
        console.log(count.call(window, 10, 10)); //20 
        console.log(count.apply(window,[10,20])); //30

        window.a=100;
        window.b=300;
        var myobject={a:40,b:50};
        var sum = function(){
          return this.a+this.b;
        };
        var sum1 = sum.call(window); 
        // var sum2 = sum.call(myobject);
        var sum2 = sum.apply(myobject); 
        console.log(sum1+"========="+sum2);

        // 发现apply()和call()的真正用武之地是能够扩充函数赖以运行的作用域,如果我们想用传统的方法实现
        window.a=100;
        window.b=300;
        var myobject={a:40,b:50};
        function sum(){
            console.log(this.a+this.b);
        }
        console.log(sum());
        myobject.sumnumber = sum;
        console.log(myobject.sumnumber());

        window.color = "red"; 
        var o = { color: "blue" }; 
        function sayColor(){ 
            console.log(this.color); 
        } 
        sayColor();
        var OSayColor = sayColor.bind(o); 
        OSayColor(); //blue

8 JS对象创建的几种方式整理

#第一种:Object构造函数创建

var Person = new Object();
Person.name = 'Nike';
Person.age = 29;

这行代码创建了Object引用类型的一个新实例,然后把实例保存在变量Person中。

#第二种:使用对象字面量表示法

var Person = {};//相当于var Person = new Object();
var Person = {
 name:'Nike';
 age:29;  
}

对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。也就是说,第一种和第二种方式创建对象的方法其实都是一样的,只是写法上的区别不同

在介绍第三种的创建方法之前,我们应该要明白为什么还要用别的方法来创建对象,也就是第一种,第二种方法的缺点所在:它们都是用了同一个接口创建很多对象,会产生大量的重复代码,就是如果你有100个对象,那你要输入100次很多相同的代码。那我们有什么方法来避免过多的重复代码呢,就是把创建对象的过程封装在函数体内,通过函数的调用直接生成对象。

#第三种:使用工厂模式创建对象

function createPerson(name,age,job){
 var o = new Object();
 o.name = name;
 o.age = age;
 o.job = job;
 o.sayName = function(){
  alert(this.name); 
 };
 return o; 
}
var person1 = createPerson('Nike',29,'teacher');
var person2 = createPerson('Arvin',20,'student');

在使用工厂模式创建对象的时候,我们都可以注意到,在createPerson函数中,返回的是一个对象。那么我们就无法判断返回的对象究竟是一个什么样的类型。于是就出现了第四种创建对象的模式。

#第四种:使用构造函数创建对象

function Person(name,age,job){
 this.name = name;
 this.age = age;
 this.job = job;
 this.sayName = function(){
 alert(this.name);
 }; 
}
var person1 = new Person('Nike',29,'teacher');
var person2 = new Person('Arvin',20,'student');


对比工厂模式,我们可以发现以下区别:

1.没有显示地创建对象

2.直接将属性和方法赋给了this对象

3.没有return语句

4.终于可以识别的对象的类型。对于检测对象类型,我们应该使用instanceof操作符,我们来进行自主检测:

?

同时我们也应该明白,按照惯例,构造函数始终要应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。



9 对象的几种常用操作方法?

#for-in循环遍历对象属性语法:

for (variable in object) {
    code to be executed
}
 #添加属性

person.nationality = "English";
  但你不能用保留字作为属性名,利用js命名规则。

#删除属性



var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
delete person.age;   // or delete person["age"]

#给对象添加属性和方法

有时你想添加新属性或方法给一个存在的对象,给所有给定类型的存在对象,或者给一个对象原型。

myFather.nationality = "English";//给一个存在的对象,仅仅对此对象
 
myFather.name = function () {
    return this.firstName + " " + this.lastName;
};//添加一个方法,仅仅对此对象

10.ajax过程

(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.

(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.

(3)设置响应HTTP请求状态变化的函数.

(4)发送HTTP请求.

(5)获取异步调用返回的数据.

(6)使用JavaScript和DOM实现局部刷新.

11.写出一个简单的$.ajax()的请求方式?


写出一个简单的$.ajax()的请求方式?

$.ajax({

    url:'http://www.baidu.com',

    type:'POST',

    data:data,

    cache:true,

    headers:{},

    beforeSend:function(){},

    success:function(){},

    error:function(){},

    complete:function(){}

}); 



12.jquery中.get()提交和.post()提交有区别吗?

 jquery中.get()提交和.post()提交有区别吗?

相同点:都是异步请求的方式来获取服务端的数据;

异同点:

1、请求方式不同:.get() 方法使用GET方法来进行异步请求的。.post() 方法使用POST方法来进行异步请求的。

2、参数传递方式不同:get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。

3、数据传输大小不同:get方式传输的数据大小不能超过2KB 而POST要大的多

4、安全问题: GET 方式请求的数据会被浏览器缓存起来,因此有安全问题。

13.什么是跨域?跨域请求资源的方法有哪些?

什么是跨域?跨域请求资源的方法有哪些?

1、什么是跨域?

由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。存在跨域的情况:

网络协议不同,如http协议访问https协议。

端口不同,如80端口访问8080端口。

域名不同,如qianduanblog.com访问baidu.com。

子域名不同,如abc.qianduanblog.com访问def.qianduanblog.com。

域名和域名对应ip,如www.a.com访问20.205.28.90.

2、跨域请求资源的方法:

(1)、porxy代理

定义和用法:proxy代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。

实现方法:通过nginx代理;

注意点:1、如果你代理的是https协议的请求,那么你的proxy首先需要信任该证书(尤其是自定义证书)或者忽略证书检查,否则你的请求无法成功。

(2)CORS 【Cross-Origin Resource Sharing】

定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。

使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。如下:

res.writeHead(200, {

    "Content-Type": "text/html; charset=UTF-8",

    "Access-Control-Allow-Origin":'http://localhost',

    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',

    'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type'

});

(3)、jsonp

定义和用法:通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。

特点:通过情况下,通过动态创建script来读取他域的动态资源,获取的数据一般为json格式。

实例如下:

<script>

    function testjsonp(data) {

       console.log(data.name); // 获取返回的结果

    }

</script>

<script>

    var _script = document.createElement('script');

    _script.type = "text/javascript";

    _script.src = "http://localhost:8888/jsonp?callback=testjsonp";

    document.head.appendChild(_script);

</script>

缺点:

  1、这种方式无法发送post请求(这里)

    2、另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。


14.Ajax的优缺点及工作原理?

Ajax的优缺点及工作原理?

定义和用法:

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。Ajax 是一种用于创建快速动态网页的技术。Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

优点:

1.减轻服务器的负担,按需取数据,最大程度的减少冗余请求

2.局部刷新页面,减少用户心理和实际的等待时间,带来更好的用户体验

3.基于xml标准化,并被广泛支持,不需安装插件等,进一步促进页面和数据的分离

缺点:

1.AJAX大量的使用了javascript和ajax引擎,这些取决于浏览器的支持.在编写的时候考虑对浏览器的兼容性.

2.AJAX只是局部刷新,所以页面的后退按钮是没有用的.

3.对流媒体还有移动设备的支持不是太好等

AJAX的工作原理:

1.创建ajax对象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp)2.判断数据传输方式(GET/POST)

3.打开链接 open()

4.发送 send()

5.当ajax对象完成第四步(onreadystatechange)数据接收完成,判断http响应状态(status)200-300之间或者304(缓存)执行回调函数

15.如何理解闭包?

如何理解闭包?

1、定义和用法:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。

2、表现形式:使函数外部能够调用函数内部定义的变量。

3、实例如下:

(1)、根据作用域链的规则,底层作用域没有声明的变量,会向上一级找,找到就返回,没找到就一直找,直到window的变量,没有就返回undefined。这里明显count 是函数内部的flag2 的那个count 。

var count=10;   //全局作用域 标记为flag1

function add(){

    var count=0;    //函数全局作用域 标记为flag2

    return function(){

        count+=1;   //函数的内部作用域

        alert(count);

    }

}

var s = add()

s();//输出1

s();//输出2

4、变量的作用域

要理解闭包,首先必须理解Javascript特殊的变量作用域。

变量的作用域分类:全局变量和局部变量。

特点:

1、函数内部可以读取函数外部的全局变量;在函数外部无法读取函数内的局部变量。

2、函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

 5、使用闭包的注意点

1)滥用闭包,会造成内存泄漏:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)会改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

 
 

16.sessionStorage 、localStorage 和 cookie 之间的区别

 9、sessionStorage 、localStorage 和 cookie 之间的区别

 共同点:用于浏览器端存储的缓存数据

不同点:

(1)、存储内容是否发送到服务器端:当设置了Cookie后,数据会发送到服务器端,造成一定的宽带浪费;

        web storage,会将数据保存到本地,不会造成宽带浪费;

(2)、数据存储大小不同:Cookie数据不能超过4K,适用于会话标识;web storage数据存储可以达到5M;

(3)、数据存储的有效期限不同:cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器;

        sessionStorage,仅在关闭浏览器之前有效;localStorage,数据存储永久有效;

(4)、作用域不同:cookie和localStorage是在同源同窗口中都是共享的;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;


15.html5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

* HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。

* 拖拽释放(Drag and drop) API 
  语义化更好的内容标签(header,nav,footer,aside,article,section)
  音频、视频API(audio,video)
  画布(Canvas) API
  地理(Geolocation) API
  本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;
  sessionStorage 的数据在浏览器关闭后自动删除

  表单控件,calendar、date、time、email、url、search  
  新的技术webworker, websocket, Geolocation

* 移除的元素

纯表现的元素:basefont,big,center,font, s,strike,tt,u;

对可用性产生负面影响的元素:frame,frameset,noframes;

支持HTML5新标签:

* IE8/IE7/IE6支持通过document.createElement方法产生的标签,
  可以利用这一特性让这些浏览器支持HTML5新标签,

  浏览器支持新标签后,还需要添加标签默认的样式:

* 当然最好的方式是直接使用成熟的框架、使用最多的是html5shim框架
   <!--[if lt IE 9]> 
   <script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script> 
   <![endif]--> 
如何区分: DOCTYPE声明\新增的结构元素\功能元素

16.js操作获取和设置cookie

//创建cookie
function setCookie(name, value, expires, path, domain, secure) {
    var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
    if (expires instanceof Date) {
        cookieText += '; expires=' + expires;
    }
    if (path) {
        cookieText += '; expires=' + expires;
    }
    if (domain) {
        cookieText += '; domain=' + domain;
    }
    if (secure) {
        cookieText += '; secure';
    }
    document.cookie = cookieText;
}

//获取cookie
function getCookie(name) {
    var cookieName = encodeURIComponent(name) + '=';
    var cookieStart = document.cookie.indexOf(cookieName);
    var cookieValue = null;
    if (cookieStart > -1) {
        var cookieEnd = document.cookie.indexOf(';', cookieStart);
        if (cookieEnd == -1) {
            cookieEnd = document.cookie.length;
        }

17.js 中的深拷贝跟浅拷贝


在js中,我们经常复制一个对象,复制数据,那么就会有人问了,怎么复制,今天鹏哥就带来js中的复制方法。

JS中对象分为基本类型和复合(引用)类型,基本类型存放在栈内存,复合(引用)类型存放在堆内存。

堆内存用于存放由new创建的对象,栈内存存放一些基本类型的变量和对象的引用变量。

至于堆内存和栈内存的区别介绍,你们可以百度看看。

下面开始讲解复制:

这种只是简单的变量,内存小,我们直接复制不会发生引用。

    var a=123;
    var b=a;
    a=123456;
    alert(a); //123456
    alert(b); //123
    
    //或者是
    
    var a='afafas';
    var b=a;
    a='fgfdsdsgs';
    alert(a); //fgfdsdsgs
    alert(b); //afafas

而对于对象这种内存占用比较大的来说,直接让复制的东西等于要复制的,那么就会发生引用,因为这种复制,只是将复制出来的东西的指向指向了要复制的那个东西,简单的说,就是两个都同时指向了一个空间,如果改变其中一个,另一个也会发生变化。这就发生了引用。

引用只发生在对象的身上:

    var arr1=[1,2,3];
    var arr2=arr1;
    arr1.push(4);
    alert(arr1); //1234
    alert(arr2); //1234
    arr2.push(5);
    alert(arr1); //12345
    alert(arr2); //12345


所谓的浅复制,只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”。

而深复制的话,我们要求复制一个复杂的对象,那么我们就以利用递归的思想来做,及省性能,又不会发生引用。



# 解决方案深拷贝,浅拷贝

两种方法实现深拷贝(深复制)

(1)方法一:兼容性好,请仔细看代码(网上大部分代码有Bug)

(2)方法二:需要对象满足JSON数据格式。JOSN数据格式:http://www.cnblogs.com/mengfangui/p/8257269.html

(3)使用类库,如lodash的_.cloneDeep(value)方法。

 

2、代码

复制代码
<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>JavaScript实现深拷贝(深复制)</title>
    </head>

    <body>

        <script>
            var obj = {
                name: null,
                age: 10
            }
            //方法一:兼容性好
            function deepClone(obj) {
                var o = obj instanceof Array ? [] : {};
                for(var k in obj) {
                    //有bug(属性的值为null时)
                    //o[k] = typeof obj[k] === 'object'?deepClone(obj[k]):obj[k];
                    if(typeof obj[k] === 'object' && obj[k] != undefined) {
                        o[k] = deepClone(obj[k]);
                    } else if(typeof obj[k] === 'object' && obj[k] == undefined) {
                        o[k] = null;
                    } else {
                        o[k] = obj[k];
                    }
                }
                return o;
            }
            //方法二:只能处理符合JSON格式的对象
            function deepClone2(obj) {
                return JSON.parse(JSON.stringify(obj))
            }
            console.log(deepClone(obj));
            console.log(deepClone2(obj));
        </script>
    </body>

</html>
复制代码

 3、浅拷贝;
Object.assign()函数






18.网站重构的理解?

网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。

对于传统的网站来说重构通常是:

表格(table)布局改为DIV+CSS
使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的)
对于移动平台的优化
针对于SEO进行优化
深层次的网站重构应该考虑的方面

减少代码间的耦合
让代码保持弹性
严格按规范编写代码
设计可扩展的API
代替旧有的框架、语言(如VB)
增强用户体验
通常来说对于速度的优化也包含在重构中

压缩JS、CSS、image等前端资源(通常是由服务器来解决)
程序的性能优化(如数据读写)
采用CDN来加速资源加载
对于JS DOM的优化
HTTP服务器的文件缓存

19.开发及性能优化以及解决方案

开发及性能优化

1、规避javascript多人开发函数重名问题

命名空间

封闭空间

js模块化mvc(数据层、表现层、控制层)

seajs

变量转换成对象的属性

对象化

2、请说出三种减低页面加载时间的方法

压缩css、js文件

合并js、css文件,减少http请求

外部js、css文件放在最底下

减少dom操作,尽可能用变量替代不必要的dom操作

3、你所了解到的Web攻击技术

(1)XSS(Cross-Site Scripting,跨站脚本攻击):指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或者JavaScript进行的一种攻击。

(2)SQL注入攻击

(3)CSRF(Cross-Site Request Forgeries,跨站点请求伪造):指攻击者通过设置好的陷阱,强制对已完成的认证用户进行非预期的个人信息或设定信息等某些状态更新。

 4、web前端开发,如何提高页面性能优化?

内容方面:

1.减少 HTTP 请求 (Make Fewer HTTP Requests)

2.减少 DOM 元素数量 (Reduce the Number of DOM Elements)

3.使得 Ajax 可缓存 (Make Ajax Cacheable)

针对CSS:

1.把 CSS 放到代码页上端 (Put Stylesheets at the Top)

2.从页面中剥离 JavaScript 与 CSS (Make JavaScript and CSS External)

3.精简 JavaScript 与 CSS (Minify JavaScript and CSS)

4.避免 CSS 表达式 (Avoid CSS Expressions)

针对JavaScript :

1. 脚本放到 HTML 代码页底部 (Put Scripts at the Bottom)
2. 从页面中剥离 JavaScript 与 CSS (Make JavaScript and CSS External)
3. 精简 JavaScript 与 CSS (Minify JavaScript and CSS)
4. 移除重复脚本 (Remove Duplicate Scripts)



6、浏览器是如何渲染页面的?

渲染的流程如下:

1.解析HTML文件,创建DOM树。

   自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。

2.解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式<HTML中的style样式;

3.将CSS与DOM合并,构建渲染树(Render Tree)

4.布局和绘制,重绘(repaint)和重排(reflow)



20 jquery 操作DOM 元素的常用方法

jQuery操作DOM元素
  HTML DOM常见操作:
  查找节点,插入节点,删除节点,复制节点,替换节点,包裹节点.
  #jQuery查找元素的方法:
         $("#myELement")    选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到的是唯一的元素 
        $("div")           选择所有的div标签元素,返回div元素数组 
        $(".myClass")      选择使用myClass类的css的所有元素 
        $("*")             选择文档中的所有的元素,可以运用多种的选择方式进行联合选择:例如$("#myELement,div,.myclass")

  #jQuery插入元素的方法:
  append(): 向每个匹配的元素内部追加内容.
  appendTo(): 将所有匹配的元素追加到指定的元素中,即$(A).appendTo(B),是将A追加到B.
  prepend(): 向每个匹配的元素内部前置内容.
  prependTo(): 将所有匹配的元素前置到指定的元素中,即$(A).prependTo(B),是将A前置到B.
 
  前面几个方法都是插入子元素,后面的这几个方法是插入兄弟元素.
  after(): 在每个匹配的元素之后插入内容.
  insertAfter(): 将所有匹配的元素插入到指定元素的后面.
  before(): 在每个匹配的元素之前插入内容.
  insertBefore(): 将所有匹配的元素插入到指定元素的前面.
 
  

 
  插入已有节点->移动节点
  除了可以插入新建的节点之外,还可以选择已有节点,插入到别的地方,以完成节点的移动操作.
  注意这里是移动操作,即原来的节点会改变位置:

<!DOCTYPE html>
<html>
	<head>
		<script src="/jquery/jquery-1.11.1.min.js">
		</script>
		<script>
			$(document).ready(function() {

				$("ul li:eq(0)").appendTo("ul");

			});
		</script>
	</head>
	<body>
		<ul>
			<li title="li1">1</li>
			<li title="li2">2</li>
			<li title="li3">3</li>
			<li title="li4">4</li>
			<li title="li5">5</li>
		</ul>
	</body>
</html>

 
 

 
#删除节点
  jQuery中删除节点的方法:
  remove(): 移除所有匹配的元素.
  empty(): 删除匹配的元素集合中所有内容,包括子节点.注意,元素本身没有被删除.
 
  关于remove()方法,有几点需要说明一下:
  1.remove()方法的返回值:
  remove()方法会返回被删除节点的jQuery对象.可以把这个对象插入到其他的地方.
  所以也可以用这种方法来移动节点:
代码
<!DOCTYPE html>
<html>
<head>
<script src="/jquery/jquery-1.11.1.min.js">
</script>
<script>
$(document).ready(function(){

$("ul li:eq(0)").appendTo("ul");//move li method1

//move method2:
var removeLi = $("ul li:eq(0)").remove();//delete li
removeLi.appendTo($("ul"));//add removed li


});
</script>
</head>
<body>
<ul>
<li title="li1">1</li>
<li title="li2">2</li>
<li title="li3">3</li>
<li title="li4">4</li>
<li title="li5">5</li>
</ul>
</body>
</html>
代码

运行结果为:

  注意直接写标签名(例如:appendTo(“ul”))和取jQuery对象(例如:appendTo($(“ul")))的结果一样.
 
  2.remove()方法的参数:
  remove()方法默认情况下会删除选择器选中的所有元素.
  比如下面的代码将删除所有<ul>下的<li>:
//remove all li
$("ul li").remove();
  remove()方法还可以接收参数,设置一些筛选条件,指定到底要删除其中的哪些节点.
  比如除了指定title的,其他全部移除:
//remove some
$("ul li").remove("li[title!='li2']");
 

  empty()方法:删除匹配元素集合中的所有子节点,清空内容.但是元素本身还存在.
  比如:
//empty children
$("ul").empty();
  会删除<ul>中的所有子节点.

  而:
//empty content
$("ul li:eq(3)").empty();
  会得到这样的效果:



 
 
#复制节点
  jQuery中复制节点的方法:
  clone(): 创建匹配元素集合的副本.
  clone()方法返回被复制的节点.
  看一个例子,每次点击<li>都复制同样的元素并添加在<ul>末尾:
代码
<!DOCTYPE html>
<html>
<head>
<script src="/jquery/jquery-1.11.1.min.js">
</script>
<script>
$(document).ready(function(){
$("ul > li").click(function(){
$(this).clone().appendTo("ul");
});
});
</script>
</head>
<body>
<ul>
<li title="li1">1</li>
<li title="li2">2</li>
<li title="li3">3</li>
<li title="li4">4</li>
<li title="li5">5</li>
</ul>
</body>
</html>
代码
 
  注意,clone出来的<li>对象就没有click事件了,即点击复制添加出来的<li>,不会再添加新的<li>.
 
  jQuery考虑到有时候会有需要clone所有的事件,所以clone方法可以带一个参数.
  clone(true): 复制节点,包括所有的事件处理.
  clone(false): 复制节点,但不包括事件处理.不带参数时默认是这种情况.
 
 
#替换节点
  jQuery中替换节点的方法:
  replaceAll(): 用指定的HTML内容或元素替换被选元素.
  语法: $(content).replaceAll(selector).
  replaceWith(): 用新内容替换所匹配到的元素.
  语法: $(selector).replaceWith(content).
 
  其中的content可以是HTML代码,可以是新元素,也可以是已经存在的元素.
 
  关于用已有元素替换:
  w3school的相关文档(http://www.w3school.com.cn/jquery/manipulation_replaceall.asp)中说:
  "已经存在的元素不会被移动,只会被复制."这种说法是不正确的.
 
  实际做了实验之后,发现用已有元素替换,原来的元素是会被移除的:
复制代码
<html>
<head>
<script type="text/javascript" src="/jquery/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#button1").click(function(){
alert("click event");
$("#button1").replaceAll($("div"));

});
});
</script>
<style>
div{height:20px;background-color:yellow}
</style>
</head>
<body>
<p>
This is paragraph:
<div id="div1">This is a div 1</div>
<div id="div2">This is a div 2</div>
<p>
This is button area:
<br><button id="button1" class="btn1">Button1</button>


</body>
</html>
代码
  页面初始状态:

  点击按钮之后:

  点击新得到的两个Button1,是可以弹出alert的,说明替换节点的时候连同节点事件一起放到了新的地方.
 
  查看官方文档:
  replaceAll(): http://api.jquery.com/replaceAll/
  replaceWith(): http://api.jquery.com/replaceWith/
  可以看到使用已有节点是不会复制该节点的,而是会移动该节点到新的地方.
 
 
 
相关杂项知识
  1.关于变量命名的一点题外话:
  变量命名习惯(不是标准):
  var $v jQuery对象变量以$符号开头命名.
  var v 普通HTML DOM对象变量.
  但是个人觉得初学者用这样的命名可能会有点混乱,会比较难以区分什么时候是命名,什么时候是jQuery操作符.
  所以目前的例子里先不这样用.
 
  2.小知识:HTML标签的字符串前面加上$符号即可将其转换为jQuery对象,比如:
  var child = $("<input type='text'/><br/>");
 
  3.从第一个例子可以看出,JavaScript操纵DOM元素的方法和jQuery的相关方法名称区别如下:
  JavaScript: appendChild(), removeChild().
  jQuery: append(), remove(). 不过这个remove()移除的是自身.
 
 
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值