19秋招面经

8.11 & 8.12笔试

顺丰科技二面 8.11(视频)

  1. 自我介绍 + 实习经历介绍
  2. 将来职业规划
  3. 为何想来顺丰
  4. 了解过顺丰科技的业务吗?为何没关注?
  5. 学习工做中遇到过什么比较困难的事情?怎么解决?
  6. 指望薪资?能降吗?
  7. 提问

猿辅导现场二面 8.10

  1. 自我介绍 + 实习经历
  2. 算法题1:使用setTimeout实现setInterval功能
function mySetInterval(fn, ms) {
    function interval(){
        setTimeout(interval, ms);
        fn();
    }
    setTimeout(interval, ms);
}

// 更好的实现

function mySetInterval(fn, ms, count) {
    function interval() {
        if(typeof count === 'undefined' || count-- > 0) {
            setTimeout(interval, ms);
            try {
                fn();
            } catch(e) {
                t = 0;
                throw e.toString();
            }
        }
    }
    setTimeout(interval, ms);
}
复制代码
  1. 算法题2:使用递归和非递归两种方法统计一棵二叉树的深度
  2. 算法题3:在一个无序数组中,寻找连续两个及两个以上的相同元素的个数
例如:有数组[10, 22, 32, 4, 4, 5, 6, 9, 8, 8, 2],返回结果为2

4, 4
8, 8
复制代码
  1. 算法题3延伸:若是给定的是一个有序数组,如何优化?

猿辅导现场一面 8.10

  1. 自我介绍 + 实习经历
  2. 为何会选前端
  3. React:生命周期 + 组件间数据传递 + ref
  4. 原生JS:做用域链 + 原型链 + 闭包
  5. 缓存机制(强缓存 + 协商缓存) + 相关HTTP头部信息
  6. URL从输入网址到最终呈现的流程 + 哪些步骤能够优化
  7. Canvas API
  8. 算法题:判断一棵二叉树是对称的

CVTE终面(视频) 8.10

太多了,跟面试前补充的简历几乎同样javascript

顺丰科技一面 8.4 (视频)

  1. 自我介绍 + 项目 + 实习
  2. 研究生以后记忆深入的事
  3. 原型的理解
  4. 闭包的理解
  5. ES5/ES6建立对象的方法
  6. ES5/ES6继承的方法
  7. 前端语言体系三要素
  8. HTML语义化
根据内容的结构化(内容语义化),选择合适的标签(代码语义化),
便于开发者阅读和写出更优雅的代码的同时让浏览器的爬虫和机器很好地解析
复制代码
  1. React的Virtual Dom/Diff算法
  2. Set和Map区别
  3. HTTP与TCP/IP或Socket的区别
TCP链接 须要通过“三次握手”

HTTP/1.0 客户端发送的每次请求都须要服务器回送响应,在请求结束后,会主动释放链接
HTTP/1.1 一次链接中处理多个请求,而且多个请求能够重叠进行,不须要等待一个请求结束后再发送下一个请求


复制代码
  1. 为何投顺丰科技
  2. 提问

补充:css

  1. 前端兼容性问题
  2. Webpack更新原理
  3. CSS Hack
  4. 箭头函数为何不能做为构造函数
  5. npm发布版本号
  6. package.json和package-lock.json区别
  7. CSS菊花图(animation-delay实现)
  8. Object.create实现

大疆二面 8.2(视频)

  1. 自我介绍
  2. 工做过程当中遇到什么困难?
  3. 怎么跟产品经理沟通的?出现问题的缘由在哪里?如何解决?最终达成一致的立足点是什么?
  4. 如何学习的?写过组件库吗?看过或本身有开源项目吗?
  5. 了解React Native吗
  6. 了解C/C++吗?(懂Java)那说说Java内存机制?
  7. 数据结构了解?哪些排序算法?实际中有用吗?
  8. 你但愿的工做环境是怎样的?
  9. 你对996制度怎么看?
  10. 你有什么问题?

CVTE二面 8.1(视频)

  1. 自我介绍
  2. 前端的学习曲线
  3. 对本身将来的规划
  4. React的diff算法
  5. React生命周期,setState能用在componentWillUpdate里吗?
  6. 算法题:字符串最长不重复子串的长度
  7. 最近看什么新知识

CVTE一面 7.29

  1. 最近作什么项目?
  2. 跨域了解过哪些?跨域传cookie可使用哪一种方法?
第一步:
设置响应消息头Access-Control-Allow-Credentials值为“true”。
同时,还须要设置响应消息头Access-Control-Allow-Origin值为指定单一域名
第二步:
客户端须要设置Ajax请求属性withCredentials=true,让Ajax请求都带上Cookie
复制代码
  1. 怎么处理cookie?删除cookie?
  2. insertBefore方法
  3. JS异步解决方案
  4. 浏览器端的EventLoop和Node的EventLoop
  5. setTimeout和Ajax的优先级
  6. JS实现事件绑定的方法
1. elementObject.addEventListener(eventName,handle,useCapture) 

2. elementObject.attachEvent(eventName,handle);(仅支持IE8及如下)

3. document.getElementById("demo").onclick = function(){};
复制代码
  1. CSS如何适配浏览器大小?
1. <meta name="viewport"
        content="width=device-width, height=device-height, inital-scale=1.0, maximum-scale=1.0, user-scalable=no;" 
    />
2. 网页内部的元素宽度要使用百分比,在不一样的屏幕大小下需使用媒体查询定义不一样的css代码

代码解析:

width:控制 viewport 的大小,能够是指定的一个值,好比 1920,或者是特殊的值,如 device-width 为设备的宽度,单位为缩放为 100% 时的 CSS 的像素。

height:和 width 相对应,指定高度,能够是指定的一个值,好比 1080,或者是特殊的值,如 device-height 为设备的高度。

initial-scale:初始缩放比例,即当页面第一次载入是时缩放比例。

maximum-scale:容许用户缩放到的最大比例。

minimum-scale:容许用户缩放到的最小比例。

user-scalable:用户是否能够手动缩放。
复制代码
  1. 浏览器的内核有哪些?哪些CSS属性须要设置?
1. IE: Trident内核
2. Firefox:Gecko内核
3. Google:Blink内核
4. Safari:Webkit内核

-webkit- ,针对safari,chrome浏览器的内核CSS写法
-moz-,针对firefox浏览器的内核CSS写法
-ms-,针对ie内核的CSS写法
-o-,针对Opera内核的CSS写法
复制代码
  1. 三列布局的实现
  2. 三角形的实现
  3. HTTP/1.1和HTTP/1.0的区别
  4. HTTP的状态码
  5. 浏览器缓存的分类
  6. cache-control的值有哪些?
  7. 对JS原型链的理解
  8. 实现方法?弊端?
  9. 日常怎么学前端?
  10. 为何选择前端?
  11. 有写博客吗?有给开源项目贡献代码吗?

阿里飞猪二面 7.25

  1. 自我介绍 + 实习状况
  2. 如何判断Array
  3. React-router原理?用到哪些API?
  4. React实现幻灯片组件对外暴露的接口有哪些?
  5. CSS第三方库的原理
  6. CSS响应式设计的方式
CSS响应式设计适配多种设备:

1. <meta name="viewport" content="width=device-width, initial-scale=1" />

2. 不要使用绝对宽度

3. 字体大小和长宽边距属性不要用”px”,应该用相对大小的“rem”

4. 使用流动布局
- 若是宽度过小,放不下两个元素,后面的元素会自动滚动到前面元素的下方,不会在水平方向overflow(溢出),避免了水平滚动条的出现

5. link标签的media属性
- <link rel="stylesheet" type="text/css" media="screen and (min-width: 600px) and (max-device-width: 980px)"  
href="css600-980.css" />  

6. Media Query

7. 图片的自适应(自动缩放)
- img{max-width: 100%;} 
- 最好仍是根据不一样大小的屏幕,加载不一样分辨率的图片
复制代码
  1. XSS和CORS原理及解决方案
  2. HTTP和HTTPS的区别
  3. 前端优化的方法
  4. utf-8和unicode区别
1. Unicode是'字符集',utf-8是'编码规则'
(以8位为一个编码单位的可变长编码,会将一个码位编码为1到4个字节)
2. 字符集:为每个字符分配一个惟一的ID
   编码规则:将码位转为字节序序列的规则

例如:'知'的码位是30693,记做U+7735(16进制为0x77E5)

'Unicode与utf-8关系':
U+0000 - U+007F:0XXXXXXX
U+0080 - U+07FF:110XXXXX 10XXXXXX
U+0800 - U+FFFF:1110XXXX 10XXXXXX 10XXXXXX
U+10000 - U+1FFFF:11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

3. utf-16使用2或4字节来保存,utf-32使用4字节保存

'GBK与utf-8':

- UTF-8包含全世界全部国家须要用到的字符,是国际编码,通用性强。
- GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。
- GBK的文字编码是用'双字节'来表示的,为了区分中文,将其最高位都设定成1,通用性比UTF8差。


复制代码

大疆一面 7.24

  1. 自我介绍
  2. React-router原理 + SPA
  3. React-router的Link和a标签的跳转有什么区别?
  • Link按需更新,a标签会重复渲染、形成白屏

补充: React-router中的Link和Route的区别html

  • route是配置,link是使用
  • 静态跳转:经过Link组件实现静态跳转
    • 必须以写入组件的方式实现跳转
    • 没法跳到历史记录中的前一个界面,后一个界面,前N个界面,后N个界面
  • 动态跳转:经过Route注入component中的route属性实现动态跳转
    • 从Route组件中传入component中的router属性对象解决了这个问题
  • NavLink是Link的一个特定版本,会在匹配上当前的url的时候给已经渲染的元素添加参数
  1. state和props的区别
  2. virtual DOM和diff算法
  3. Ajax请求应该在哪一个生命周期函数中?为何不在componentWillMount里?
  • 在componentDidMount中
  • ajax请求在返回数据后需调用setState方法,进而更新state值,但componentWillMount并不容许(该函数效果与constructor相同,只能设定state初始值),没法触发重渲染
  1. key有什么做用?为何不该该用数组的index值当key?(不稳定)
  2. 算法题:在局部递增数组(如:[3, 4, 5, 1, 2])中查询指定数字是否存在
  3. React学了多久?
  4. 提问

拼多多笔试 7.22

  1. 下面的输出是什么?
const promise = new Promise((resolve, reject) => {
    console.log('a');
    resolve();
    console.log('b');
});

promise.then(() => {
    console.log('c');
});

console.log('d');

// a b d c,Promise的异步执行
复制代码
  1. 下面的输出是什么?
(function(x) {
    return (function(y) {
        console.log(x);
    })(2);
})(1);

// 1,闭包问题
复制代码
  1. 下面的输出是什么?
pi = 0;
radius = 1;
function circum(radius) {
    radius = 3;
    pi = 3.14;
    console.log(2 * pi * radius);   // 18.14
    console.log(arguments[0]);      // 3
}
circum(2);                  
console.log(pi);            // 3.14
console.log(radius);        // 1

函数内修改了radius 修改的是"形式参数",修改的pi是"全局的"pi
复制代码

与下述状况相同前端

var pi = 0;
var radius = 1;
function circum(radius) {
    radius = 3;
    pi = 3.14;
    console.log(2 * pi * radius);   // 18.84
    console.log(arguments[0]);      // 3
}

circum(radius);

console.log(pi);            // 3.14
console.log(radius);        // 1
复制代码

补充java

function foo(a, b){
   arguments[0] = 9;
   arguments[1] = 99;
   console.log(a, b); //9, 99
}
foo(1, 10); 

function foo(a, b){
   a = 8;
   b = 88;
   console.log(arguments[0], arguments[1]); //8, 88
}
foo(1, 10);

// ES6的默认函数不会改变arguments类数组对象值
function foo(a=1, b=10){
   arguments[0] = 9;
   arguments[1] = 99;
   console.log(a, b); //1, 10
}
foo();

// 实例
function f2(a) {
    console.log(a); 
    var a;
    console.log(a);
    console.log(arguments[0])
}
f2(10)

通过变量提高后:
function f2(a) {
    var a;
    console.log(a); 
    console.log(a);
    console.log(arguments[0])
}
f2(10);

var a会被概括,因为a已经有值,故不会变为undefined
复制代码
  1. 哪些是稳定排序?哪些是不稳定排序?
    定义:
    假定在待排序的记录序列中,存在多个具备相同的关键字的记录,若通过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]以前,而在排序后的序列中,r[i]仍在r[j]以前,则称这种排序算法是稳定的;不然称为不稳定的。
稳定排序:
插入排序 [1]  ,冒泡排序 [2]  ,归并排序 [3]  ,基数排序 [4]  ,计数排序 [5] 

不稳定排序:
快速排序 [1],简单选择排序 [2],希尔排序 [3],堆排序 [4]
复制代码
  1. typeof obj === 'object'判断obj是对象的弊端?如何改进?
var  obj = {};
var  arr = [];
var funcInstance = new (function (){});  
var isNull = null;

console.log(typeof obj === 'object');  //true
console.log(typeof arr === 'object');  //true
console.log(typeof funcInstance == 'object');  //true
console.log(typeof isNull === 'object');    // true

// constructor
({}).constructor === Object;  //true
([]).constructor === Array;  //true

// instanceof
({}) instanceof Object;  //true
([]) instanceof Array;   //true

// toString: 将当前对象以字符串的形式返回
console.log(Object.prototype.toString.call(obj));  //[object Object]
console.log(Object.prototype.toString.call(arr));  //[object Array]
console.log(Object.prototype.toString.call(null));  //[object Null]
复制代码
  1. 补充题:下面的输出是什么?
var a = {};
var b = {name:"ZS"};
var c = {};
c[a] = "demo1";
c[b] = "demo2";

console.log(c[a]);      // demo2
console.log(c);         // Object {[object Object]: "demo2"}

c[a]、c[b]隐式的将对象a,b使用了toString()方法进行了转换,而后再对属性赋值。
即:Object.prototype.toString.call(a) ==> [object Object]
所以,c = { [object Object]: 'demo1'} ==> c = {[object Object]: 'demo2' }
复制代码
  1. 编程:实现log函数
function log() {
    // var arr = [].slice.call(arguments);
    var arr = Array.from(arguments);
    var res = '';
    arr.forEach(elem => {
        res += elem + ' ';
    });
    console.log(`(app)${res}`);
}

// 测试
log('hello', 'world');
log('hello world');
复制代码
  1. 将具备父子关系的原始数据格式化成树形结构数据
    第一种思路:
function toTreeData(data){
	var pos={};
	var tree=[];
	var i=0;
	while(data.length!=0){
		if(data[i].pid==0){
			tree.push({
				id:data[i].id,
				text:data[i].text,
				children:[]
			});
			pos[data[i].id]=[tree.length-1];	
			data.splice(i,1);
			i--;
		}else{
			var posArr=pos[data[i].pid];
			if(posArr!=undefined){
				
				var obj=tree[posArr[0]];
				for(var j=1;j<posArr.length;j++){
					obj=obj.children[posArr[j]];
                }
                
				obj.children.push({
					id:data[i].id,
					text:data[i].text,
					children:[]
				});
				pos[data[i].id]=posArr.concat([obj.children.length-1]);
				data.splice(i,1);
				i--;
			}
		}
		i++;
		if(i>data.length-1){
			i=0;
		}
	}
	return tree;
}


var data=[
    {id:1,pid:0,text:'A'},
    {id:2,pid:4,text:"E[父C]"},
    {id:3,pid:7,text:"G[父F]"},
    {id:4,pid:1,text:"C[父A]"},
    {id:5,pid:6,text:"D[父B]"},
    {id:6,pid:0,text:'B'},
    {id:7,pid:4,text:"F[父C]"}
];

var result = toTreeData(data);

console.log(result);
复制代码

第二种思路:web

function treeObj(originObj) {
    // 深拷贝
    let obj = {};
    for(key in originObj) {
        var val = originObj[key];
        // arguments的callee属性指向拥有这个 arguments 对象的函数
        obj[key] = typeof val === 'object'? arguments.callee(val):val;
    }
    obj['children'] = [];
    return obj;
}

function toTreeData(data, attributes) {
    let resData = data;
    let tree = [];
    
    // 找根节点
    for(let i = 0; i < resData.length; i++) {
        if(resData[i][attributes.parentId] === ''
            ||
            resData[i][attributes.parentId] === null) {
                tree.push(treeObj(resData[i]));
                // 删除掉已经放入tree中的根节点
                resData.splice(i, 1);
                i--;
            }
    }
    // 找寻子树
    return run(tree);

    function run(childArr) {
        if(resData.length !== 0) {
            for(let i = 0; i < childArr.length; i++) {
                for(let j = 0; j < resData.length; j++) {
                    if(childArr[i][attributes.id] === resData[j][attributes.parentId]) {
                        let obj = treeObj(resData[j]);
                        childArr[i].children.push(obj);
                        // 删除加入树中的节点
                        resData.splice(j, 1);
                        j--;
                    }
                }
                run(childArr[i].children);
            }
        }
        return tree;
    }
}


let allRes = [
    {
        id: 4,
        resName: "删除角色",
        parentId: 2
    },
    {
        id: 3,
        resName: "编辑角色",
        parentId: ''
    },
    {
        id: 2,
        resName: "设置权限",
        parentId: ''
    },
    {
        id: 5,
        resName: "添加用户",
        parentId: 4
    },
    {
        id: 6,
        resName: "更新用户",
        parentId: 4
    },
    {
        id: 7,
        resName: "删除用户",
        parentId: 6
    },
    {
        id: 8,
        resName: "重置密码",
        parentId: 3
    },
    {
        id: 9,
        resName: "添加地区",
        parentId: 5
    },
    {
        id: 10,
        resName: "编辑地区",
        parentId: 6
    }
];

let data = allRes;
// 属性配置信息
let attributes = {
    id: 'id',
    parentId: 'parentId',
};
let treeData = toTreeData(data, attributes);

console.log(treeData);

复制代码
  1. 深拷贝与浅拷贝的区别?如何实现?
  • 浅拷贝(shallow copy):只复制指向某个对象的指针,而不复制对象自己,新旧对象共享一块内存
  • 深拷贝(deep copy):复制并建立一个一摸同样的对象,不共享内存,修改新对象,旧对象保持不变
// 1. Object.assign

let foo = {
    a: 1,
    b: 2,
    c: {
        d: 1,
    }
}
let bar = {};
Object.assign(bar, foo);
foo.a++;
foo.a === 2 //true
bar.a === 1 //true
foo.c.d++;
foo.c.d === 2 //true
bar.c.d === 1 //false
bar.c.d === 2 //true

Object.assign()是一种能够对非嵌套对象进行深拷贝的方法;
若是对象中出现嵌套状况,那么其对被嵌套对象的行为就成了普通的浅拷贝。


// 2. JSON.parse和JSON.stringify

var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1);   // { body: { a: 10 } } 
console.log(obj2);   // { body: { a: 20 } }
console.log(obj1 === obj2);   // false
console.log(obj1.body === obj2.body);   // false

用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。
可是,会破坏原型链,而且没法拷贝属性值为function的属性


// 3. 递归

var json1={
    "name":"shauna",
    "age":18,
    "arr1":[1,2,3,4,5],
    "string":'got7',
    "arr2":[1,2,3,4,5],
    "arr3":[{"name1":"shauna"},{"job":"web"}]
};
var json2={};

function copy(obj1,obj2){
  var obj2 = obj2 || {};
  for(var name in obj1){
    if(typeof obj1[name] === "object"){ 
      obj2[name]= (obj1[name].constructor===Array)?[]:{}; 
      copy(obj1[name],obj2[name]); 
    }else{
      obj2[name]=obj1[name];  
    }
  }
  return obj2;
}

json2=copy(json1,json2)
json1.arr1.push(6);
alert(json1.arr1);  //123456
alert(json2.arr1);  //12345
复制代码
  1. 补充题: 数组扁平化
// 递归
function flatten(arr){
    var res = [];
    for(var i=0;i<arr.length;i++){
        if(Array.isArray(arr[i])){
            res = res.concat(flatten(arr[i]));
        }else{
            res.push(arr[i]);
        }
    }
    return res;
}
复制代码

CVTE笔试 7.20

  1. 回溯算法面试

  2. 下面的输出是什么?ajax

var array1 = Array(3);
array1[0] = 2;
var result = array1.map(elem => '1');

// ['1', empty * 2]
复制代码
  1. 下面的输出是什么?
var setPerson = function(person) {
    person.name = 'kevin';
    person = {name: 'Nick'};
    console.log(person.name);       // Nick
    person.name = 'Jay';
    console.log(person.name);       // Jay
}
var person = {name: 'Alan'};
setPerson(person);
console.log(person.name);           // Kevin
复制代码
  1. 下面的输出是什么?
var execFunc = () => console.log('a');
setTimeout(execFunc, 0);
console.log('000');
execFunc = () => console.log('b');

// '000', 'a'
复制代码

补充:setTimeout没法使用含参函数参数算法

window.setTimeout(hello(userName),3000);
这将使hello函数当即执行,并将'返回值'做为调用句柄传递给setTimeout函数

// 方法1:
使用'字符串形式'能够达到想要的结果:
window.setTimeout("hello(userName)",3000);
可是,此处的username变量必须处于全局环境下

// 方法2:
function hello(_name){
       alert("hello,"+_name);
}
// 建立一个函数,用于返回一个无参数函数
function _hello(_name){
       return function(){
             hello(_name);
       }
}
window.setTimeout(_hello(userName),3000);
使用_hello(userName)来返回一个不带参数的函数句柄,从而实现了参数传递的功能
复制代码
  1. 下面的输出是什么?
for(var i = {j: 0}; i.j < 5; i.j++) {
    (function(i){
        setTimeout(function() {
            console.log(i.j);
        }, 0);
    })(JSON.parse(JSON.stringify(i)));
}

// 0, 1, 2, 3, 4

for(var i = {j: 0}; i.j < 5; i.j++) {
    (function(i){
        setTimeout(function() {
            console.log(i.j);
        }, 0);
    })(i);
}

// 5, 5, 5, 5, 5
复制代码
  1. Generator
  2. line-height
  3. FileReader
  4. 如何判断x为数组
  5. npm依赖包的版本号
  6. attachEvent, detachEvent, dispathEvent

阿里飞猪1面 7.20

  1. 自我介绍 + 项目介绍(难点)
  2. React相关知识
  • 生命周期
  • diff算法及时间复杂度
  • refs
  • React-router原理
  1. Redux和Relay的了解
  2. Node的了解
  3. Webpack的了解(如何使用)
  4. typeof操做符的返回值(undefined, number, string, boolean, object, function, symbol)
  5. ES6的了解程度
  • var,let,const区别
  • const a = []; a.push(1); 容许吗?
  • Symbol的用处(避免属性名冲突)
  1. 除get和post以外,HTTP的请求方法还有哪些
  2. HTTP的状态码有哪些
  3. 从输入网址到页面呈现的过程
  4. DOMContentLoad和Load的区别
  5. Flex布局
  6. 客户端的存储方法?localStroage和sessionStorage的区别
  7. HTML5点击延迟事件
  8. 移动端前端开发的了解
  9. 前端性能优化的方法
  10. 前端性能工具
  11. 日常怎么学习前端?
  12. 提问

做业帮7.9

  1. Webpack的了解
  2. React的diff算法
  3. 单向数据流
  4. MVC和MVVM的区别
  5. ES6了解程度(let,const,Generator,Promise)
  6. JS异步方法及回调地狱
  7. Node、MongoDB了解多少
  8. 关系型和菲关系型数据库的区别
  9. CSS的position属性有哪些
  10. 左右定宽,中间自适应的多种CSS布局方法
  11. 前端的性能优化
  12. HTTP状态码

做业帮 2018

1.如何进行输入去重?chrome

// 方法1:
function nonDup(arr){
    var res = [];
    for(var i = 0; i < arr.length; i++) {
        if(res.indexOf(arr[i]) === -1) {
            res.push(arr[i]);
        }
    }
    return res;
}

// 方法2:
function nonDup(arr){
    var res = new Set(arr);
    return [...res];
}

// 方法3:
function nonDup(arr){
    return arr.filter((elem, index) => {
        return index === arr.indexOf(elem);
    });
}

// 方法4:

Array.prototype.uniq = function () {
    var hasNaN = false;
    for(var i = 0; i < this.length; i++){
        if(this[i] !== this[i]) hasNaN = true;
        for(var j = i+1; j < this.length;){
            if(this[i] === this[j] ||(hasNaN && this[j] !== this[j])){
                this.splice(j,1);
            }else{
                j++;
            }
        }
    }
    return this;
}
复制代码

2.实现鼠标滑过头像显示简介

<!DOCTYPE html>
<html>
<head>
<style>
    .div1{
        width:100px;
        height:100px;
        background-color:red;
        border-radius: 50px;
    }
    .div2{
        width:100px;
        height:200px;
        margin-top: 10px;
        background-color:black;
        display: none;
    }
</style>
</head>
<body>
    <div class='div1'></div>
    <div class='div2'></div>
    
    <script type="text/javascript">
        var d1 = document.getElementsByClassName('div1')[0];
        var d2 = document.getElementsByClassName('div2')[0];
        var timer;
        d1.addEventListener('mouseenter',function(){
            timer = window.setTimeout(function(){d2.style.display="block"},300);
        })
        d1.addEventListener('mouseout',function(){
            window.clearTimeout(timer);
            d2.style.display="none";
        })
    </script>
</body>
</html>
复制代码
相关文章
相关标签/搜索