this
- 填空 ``` <!DOCTYPE html>
<!DOCTYPE html>
<!DOCTYPE html>
以上三段代码分别输出什么?
### 原生DOM操作
- 完成以下dom节点的操作,要求:使用原生JS
- #0
- #1
- #2
- #3
- #4
...
- #99998
- #99999
- #100000
为 <ul> 添加一个类 bar;
删除第 10 个 <li>;
在第 500 个 <li> 后面增加一个 <li> , 其文字内容为
答案:
1)
var list = document.getElementById(‘list’).getAttribute(‘class’);
list = list.concat(‘bar’);
document.getElementById(‘list’).setAttribute(‘class’,list)
2)
var ul = document.getElementById(‘list’);
var li = document.getElementsByTagName(‘li’);
ui.removeChild(list[9])
3)
var ul = document.getElementById(‘list’);
var li = document.createElement(‘li’);
var lis = ducument.getElementsByTagName(‘li’);
li.innerText= “
foo();
事件委托: var ul = document.getElementById(‘list’); var lis = ul.getElementsByTagName(‘li’); ul.addEventListener(‘click’, function(e){ var e = e || window.event; var target = e.target || e.srcElement; for (var i=0; i< li.length; i++){ if(li[i] == target){ alert(i) } } })
### 算法
-
###
- 函数节流和防抖
节流: function throttle(fn, delay) { delay = delay || 50 let statTime = 0 return function () { statTime === 0 && fn.apply(this, arguments) let currentTime = new Date() if (currentTime - statTime > delay) { fn.apply(this, arguments) statTime = currentTime } } }
防抖: function debounce(fn, delay) { delay = delay || 50 let timer = null return function () { let self = this clearTimeout(timer) timer = setTimeout(fn.bind(self, arguments), delay); } }
- 原生Bind实现
Function.prototype._bind = function (context) { let self = this let args_1 = [].prototype.slice.call(arguments, 1) return function () { let args_2 = [].prototype.slice.call(arguments) let args = args_1.concat(args_2) return self.apply(context, args) } }
- 下面是一个一个动画版冒泡排序,请补充完整相应的代码
(function (global, undefined) {
/**
* 构造函数
* @param {构造参数} opt
*/
function MySort(opt) {
this.def = opt;
this._initDom();
}
/**
* 初始化dom(计算排序item的宽高,自适应容器)
*/
MySort.prototype._initDom = function () {
//获取容器
let container = document.getElementById(this.def.container);
//获取数据
let arr = this.def.arr;
//获取数组最大值
let max = Math.max.apply(null, arr);
//容器宽度
let cWidth = container.offsetWidth;
//容器高度
let cHeight = container.offsetHeight - 50;
//计算item宽度
let count = arr.length;
let itemWidth = (cWidth - this.def.sep * (count + 1)) / count;
//填充dom
let html = '';
arr.forEach((element, index) => {
//计算left
let left = index * itemWidth + (index + 1) * this.def.sep;
//计算高度
let height = element / max * cHeight;
html += `<div class="item normalItem" style="left:${left}px; width:${itemWidth}px; height:${height}px;">${element}</div>`;
});
container.innerHTML = html;
}
/**
* 交换两个item的dom位置
* @param {左侧item} tempItem1
* @param {右侧item} tempItem2
*/
MySort.prototype._changePosition = function (tempItem1, tempItem2) {
tempItem1.parentNode.removeChild(tempItem2);
tempItem1.parentNode.insertBefore(tempItem2, tempItem1);
}
/**
* 交换两个item的逻辑位置实现动画
* @param {排序数组} resArr
* @param {item列表} itemList
* @param {内侧循环index} j
*/
MySort.prototype._changeItem = function (resArr, itemList, j) {
[resArr[j], resArr[j + 1]] = [resArr[j + 1], resArr[j]];
let tempLeft = itemList[j].style.left;
itemList[j].style.left = itemList[j + 1].style.left;
itemList[j + 1].style.left = tempLeft;
}
/**
* 给当前活跃的item添加样式
* @param {item列表} itemList
* @param {内侧循环index} j
*/
MySort.prototype._activeItem = function (itemList, j) {
itemList[j].classList.add('activeItem');
itemList[j + 1].classList.add('activeItem');
if (j > 0) {
itemList[j - 1].classList.remove('activeItem');
}
}
/**
* 给已完成排序的item添加样式
* @param {item列表} itemList
* @param {外侧循环index} i
* @param {内侧循环index} j
* @param {完成标示} complete
*/
MySort.prototype._completeItem = function (itemList, i, j, complete) {
itemList[j + 1].classList.add('completeItem');
itemList[j].classList.remove('activeItem');
//如果完成把剩余item设置为complete
if (complete) {
for (j = 0; j < itemList.length - i - 1; j++) {
itemList[j].classList.add('completeItem');
}
}
}
/**
* 排序内部逻辑操作
*/
MySort.prototype._render = async function (itemList,resArr,i,j, complete) {
this._activeItem(itemList, j);
await sleep(this.def.speed);
if (resArr[j + 1] < resArr[j]) {
this._changeItem(resArr, itemList, j);
await sleep(this.def.speed);
this._changePosition(itemList[j], itemList[j + 1]);
complete = false;
}
//最后一次比较
if (j == resArr.length - i - 2) {
this._completeItem(itemList, i, j, complete);
}
//回调
this.def.getData(resArr);
return complete;
}
/**
* 开始动画
*/
MySort.prototype.start = async function () {
let resArr = this.def.arr.slice();
let len = resArr.length;
let complete;
let itemList = document.getElementById(this.def.container).childNodes;
for (let i = 0; i < len - 1; i++) {
complete = true;
for (let j = 0; j < len - i - 1; j++) {
//交换逻辑操作
complete = await this._render(itemList,resArr,i,j,complete);
}
if (complete) {
break;
}
}
}
/**
* 线程睡眠
* @param {睡眠时间} time
*/
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, time);
})
};
global.MySort = MySort;
})(window);
html如下:
<!DOCTYPE html>
- reduce实现数组去重
const distinct = arr => arr.sort().reduce( (init, current) => {
if (init.length === 0 || init[init.length - 1] !== current) {
init.push( current );
}
return init; }, []);
- 两数之和:给定一个整数数组和一个目标值,找到数组中和为目标值的两个数.
/**
- @param {number[]} nums
- @param {number} target
-
@return {number[]} */ var twoSum = function(nums, target) {
var map = new Map(); var number = [];
for(var i = 0; i < nums.length; i ++) {
if(map.has(target - nums[i])) { number.push(i, map.get(target - nums[i])); break; } map.set(nums[i], i); } return number; };
```