记一次阿里巴巴集团招聘在线评测
请在40分钟内完成以下几道题目,遇到不熟悉的原生对象属性或者API,可以适当使用搜索引擎(注意:请不要直接搜索题目答案,自觉遵守规则)
- 给一个div:
<div id="draggable" style="width: 200px; height: 200px; background: #000;"></div>
复制代码
用原生JS让这个 div 可拖拽。
- 写一个类 EventEmitter,实现简单的发布订阅功能:
const e = new EventEmitter();
e.on('update', function(data) { console.log(data) });
e.emit('update', 'message');
复制代码
- 实现一个搜索框的智能提示功能,可自己mock一些测试数据。(如输入”电脑“,显示一个提示列表:电脑游戏 、电脑壁纸、电脑管家、电脑VPN)
// 第一题
function drag(){
let dragEl = document.getElementById('draggable');
dragEl.style.position = 'absolute';
// 如果需要兼容的话 需要做下attachEvent
dragEl.addEventListener('mousedown', function(event){
let mouseX = event.pageX,
mouseY = event.pageY,
elX = dragEl.offsetLeft || 0,
elY = dragEl.offsetTop || 0,
distanceX = mouseX - parseInt(elX),
distanceY = mouseY - parseInt(elY);
let moveCallback = function(moveEvent){
let mouseX = moveEvent.pageX,
mouseY = moveEvent.pageY;
dragEl.style.left = mouseX - distanceX + 'px';
dragEl.style.top = mouseY - distanceY + 'px';
};
dragEl.addEventListener('mousemove', moveCallback, false);
let upCallback = function(upEvent){
dragEl.removeEventListener('mousemove', moveCallback);
dragEl.removeEventListener('mouseup', upCallback);
};
dragEl.addEventListener('mouseup', upCallback, false);
}, false);
}
复制代码
// 第二题
function EventEmitter(){
this.events = [];
}
EventEmitter.prototype = {
constructor: EventEmitter,
sub: function(type, callback){
if(!this.events[type]){
this.events[type] = [];
}
this.events[type].push(callback);
},
pub: function(type, arg){
if(this.events[type]){
for(let callback of this.events[type]){
callback && callback();
}
}
}
};
// 第三题
// 以下是html模版 style什么没有具体写明白,大概写了下
<div id="autocomplete">
<input type="text" style="width:100px;height:28px;" />
// 如果是使用mvvm框架,这里用ngFor会好写点
<ul id="suggestList" style="position:absolute; top: 28px; left: 0;">
</ul>
</div>
// 以下是js代码
let mockData = ['电脑游戏','电脑壁纸','电脑管家','电脑VPN'];
let completeEl = document.getElementById('autocomplete'),
inputEl = completeEl.childNodes[0],
suggestListEl = document.getElementById('suggestList');
let keyupCallback = function(event){
let val = event.target.value;
let promise = new Promise(function(resolve, reject){
// 兼容需要增加下ActiveXObject
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
// 或者用readyState 4 判断
if(xhr.statue == 200){
resolve(JSON.parse(xhr.reponseText));
}
};
// url未知
let url = '/api/get?suggest=' + val;
xhr.open('GET', url, true);
xhr.send();
});
promise.then(function(result){
// 需要增加一些result数据格式的判断,这里先不写了
let tmpl = [];
for(let item of result){
if(item.indexOf(val) != -1){
tmpl[tmpl.length] = `<li>${item}</li>`;
}
}
suggestListEl.innerHTML = tmpl.join('');
});
}
function debounce(fn, time){
let timeout,
self = this;
return function(){
let args = [].slice.call(arguments);
clearTimeout(timeout);
setTimeout(function(){
fn.apply(self, args);
}, time);
}
}
inputEl.addEventListener('keyup', debounce(keyupCallback, 100), false);
// 后续需要自己注意解绑事件
inputEl.removeEventListener('keyup', keyupCallback);
}, false);
}, false);
}复制代码