根据下面给定的html结构,在style标签里填充代码实现图中的样式
/* html 结构 */
<div class="box-wrap">
<ul class="box ">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
/* 填充任意代码 */
.box-wrap{ background-color: #DDD; width: 400px; height: 400px; border:1px solid #000;}
解题思路:
- 整体用flex布局,利用flex-direction将子项反转;
- 整体水平居中;
- 利用伪类nth-child实现个性化样式;
.box {
display: flex;
flex-direction: row-reverse;
list-style-type: none;
text-align: center;
align-items: center;
padding-inline-start: 0px;
margin-block-end: 0;
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%);
}
ul li {
width: 38px;
height: 90px;
background-color: rgb(56, 140, 255);
margin-right: 18px;
vertical-align: middle;
line-height: 90px;
}
li:nth-child(3) {
width: 38px;
height: 180px;
line-height: 180px;
}
li:first-child {
margin-right: 0;
}
在数组中找到第K大的元素
示例:
输入: [3,5,6,7,2,4,7,3] 和k=3
输出: 5
解决思路:
- 利用快速排序将数组进行升序排序;
- 创建一个对象obj,对象的key放数组的每一项value,值也是value,这样可以过滤掉相同的元素;
- 从obj中取值就好;
let arr = [3, 5, 6, 7, 2, 4, 7, 3];
function partion(arr, low, high) {
let privot = arr[low];
while (low < high) {
while (low < high && arr[high] > privot) {
high--;
}
arr[low] = arr[high];
while (low < high && arr[low] <= privot) {
low++;
}
arr[high] = arr[low];
}
arr[low] = privot;
return low;
}
function quickSort(arr, low, high) {
if (low < high) {
let index = partion(arr, low, high);
quickSort(arr, 0, index - 1);
quickSort(arr, index + 1, high);
}
}
quickSort(arr, 0, arr.length - 1);
//找到第k大的数
function findKNum(array, k) {
var obj = {},
index = 0,
result;
array.forEach(element => {
obj[element] = element;
});
for (var key in obj) {
index++;
if (k === index) {
result = key;
}
}
return result;
}
let result = findKNum(arr, 3);
console.log('结果是:' + result);//结果应该是4
找到html中最深的那个Element节点
- 将html节点作为根节点进行递归遍历;
- 递归的出口就是没有子节点;
//找到html中最深的那个Element节点
function findDeepestElement() {
var html = document.querySelector('html');
var deepestElement = {};
findChild(html, deepestElement);
var max = deepestElement['max'];
return deepestElement[max];
}
function findChild(parent, deepestElement, max) {
if (parent.hasChildNodes() && parent.children.length > 0) {
var childrenArr = Array.prototype.slice.apply(parent.children);
childrenArr.forEach((child) => {
child['index'] = (parent.index || 0) + 1;
findChild(child, deepestElement, max);
})
} else {
var index = parent['index'] || 0;
var max = deepestElement['max'] || 0;
if (deepestElement[index]) {
deepestElement[index].push(parent);
} else {
deepestElement[index] = [parent];
}
if (index > max) {
max = index;
}
deepestElement['max'] = max;
}
}
var deepestElement = findDeepestElement();
console.log(deepestElement);
实现sum方法,使sum(x)(y) sum(x,y) 返回的结果相同
function sum(num1) {
if (arguments.length > 0 && arguments[1]) {
var arr = Array.prototype.slice.apply(arguments);
num1 = arr.reduce((total, value) => {
return total + value;
})
return num1;
} else {
function add(num) {
num1 = num1 + num;
return add;
}
add.toString = function() {
return num1;
}
return add;
}
}
var result1 = sum(1)(2)(3);
var result2 = sum(1, 2, 3);
console.log('result1:' + result1 + '-----result2:' + result2);
填充代码实现template方法
var str = '您好,<%=name%>。欢迎来到<%=location%>';
var compiled = template(str);
// complied的输出值为:'您好,张三。欢迎来到**游戏'
compiled({name: '张三', location: '**游戏'})
解决思路:
- tempalte方法的返回值是一个方法,并且该返回的方法接受一个json对象作为参数;
- 用json对象的key去匹配str中的该key对应的表达式,用值去替换该表单式;
function template(str) {
return function(options) {
Object.keys(options).forEach(key => {
str = str.replace(new RegExp(`<%=${key}%>`, 'g'), options[key]);
});
return str;
}
}
无缝滚动的实现
效果图:
实现思路:
- 用setInterval来模拟动画;
- 用一个空div来复制一份图片,如果滚动的高度等于空div的offsetTop,则重置滚动条的高度
<template>
<div class="container" ref="container">
<div class="images" ref="images">
<img src="../assets/img/carousel_1.jpg"/>
<img src="../assets/img/carousel_2.jpg"/>
<img src="../assets/img/carousel_3.jpg"/>
<img src="../assets/img/carousel_4.jpg"/>
<img src="../assets/img/carousel_5.jpg"/>
</div>
<div class="empty" ref="empty"></div>
</div>
</template>
<script>
export default{
name:'noGrapScroll',
mounted(){
let vm = this;
vm.$refs.empty.innerHTML = vm.$refs.images.innerHTML;
setInterval(()=>{
let scrollTop = vm.$refs.container.scrollTop;
if(vm.$refs.empty.offsetTop==vm.$refs.container.scrollTop){
vm.$refs.container.scrollTop = 0;
}else{
scrollTop = scrollTop + 5;
vm.$refs.container.scrollTop = scrollTop;
}
},10);
}
}
</script>
<style scoped>
.container{
width: 1080px;
height:840px;
margin:0 auto;
overflow:hidden;
}
img{
width: 1080px;
height: 420px;
}
</style>
promise调用实现
new People('whr').sleep(3000).eat('apple').sleep(5000).eat('durian')
new People('whr').sleep(3000).eat('apple').sleep(5000).eat('durian');
// 打印结果
// (等待3s)--> 'whr eat apple' -(等待5s)--> 'whr eat durian'
实现思路:
- 不用promise的话,可以借助函数的链式调用和队列的思路去完成;
- 如果用promise,借用resolve和then的关系去模拟;
class People {
constructor(name) {
this.name = name;
this.queue = Promise.resolve();
}
sleep(timer) {
this.queue = this.queue.then(() => {
return new Promise(resolve => {
setTimeout(function() {
resolve();
}, timer);
});
});
return this;
}
eat(fruit) {
this.queue = this.queue.then(() => {
console.log(`${this.name} eat ${fruit}`);
})
return this;
}
}
taskSum(1000,()=>{console.log(1)}).task(1200,()=>{console.log(2)}).task(1300,()=>{console.log(3)})
实现taskSum(1000,()=>{console.log(1)}).task(1200,()=>{console.log(2)}).task(1300,()=>{console.log(3)}),
这里等待1s,打印1,之后等待1.2s,打印2,之后等待5.3s,打印3
function taskSum(timer,callback){
return new Task(timer,callback);
}
class Task {
constructor(timer,callback){
this.timer = timer;
this.callback = callback;
setTimeout(()=>{
callback();
},timer);
this.queue = Promise.resolve();
}
sleep(timer) {
this.queue = this.queue.then(() => {
return new Promise(resolve => {
setTimeout(function() {
resolve();
}, timer);
});
});
return this;
}
task(timer,callback){
this.queue.then(()=>{
setTimeout(()=>{
callback();
},timer);
})
return this;
}
}
taskSum(1000,()=>{console.log(1)}).task(1200,()=>{console.log(2)}).task(5300,()=>{console.log(3)});
[1,2,3].map(parseInt) 执行结果
let newArray = arr.map(callback(currentValue[, index[, array]]) {
// return element for newArray, after executing something
}[, thisArg]);
callback中接收3个参数:
- 当前被处理的元素;
- 当前被处理元素的索引;
- 当前遍历的数组;
parseInt(string [, radix])
parseInt中接收2个参数:
- 要被转换的字符串;
- 为解析时的基数,radix是一个介于2-36之间的整数; 返回解析后的整数值,如果被解析参数的第一个字符无法被转化成数值类型,则返回 NaN
parseInt(1,0);//10进制的1,结果为1
parseInt(2,1);//1不属于2~32,结果为NaN
parseInt(3,2);//2进制的3,结果为NaN
所以输出的结果为[1, NaN, NaN]
数组A,数字N,A中找到a,b使a+b=N
怎么样可以更高效一点?这时候要引入哈希表,将数字a和b对应的记录在hash中,如果来了a,直接看hash中是否存在a即可。
字符串,得出最长的没有重复字符的子串长度
思路:
- 暴力解法时间复杂度较高,会达到 O(n^2);
- 故而采取滑动窗口的方法降低时间复杂度;
- 定义一个 map 数据结构存储 (k, v),其中 key 值为字符,value 值为字符位置 +1,加 1 表示从字符位置后一个才开始不重复;
- 我们定义不重复子串的开始位置为 start,结束位置为 end;
- 随着 end 不断遍历向后,会遇到与 [start, end] 区间内字符相同的情况,此时将字符作为 key 值,获取其 value 值,并更新 start,此时 [start, end] 区间内不存在重复字符;
- 无论是否更新 start,都会更新其 map 数据结构和结果 length; 时间复杂度:O(n)
求出一个二维数组[[A, B], [a, b], [1, 2]]所有排列组合
输入[[A, B], [a, b], [1, 2]]
输出[Aa1, Aa2, Ab1, Ab2, Ba1, Ba2, Bb1, Bb2]
实现:
- 分析一下,将计算过程拆解为两两相乘的过程;
- 首先计算[A, B] * [a, b],得到结果[Aa, Ab, Ba, Bb];
- 然后计算[Aa, Ab, Ba, Bb] * [1, 1],得到最终结果[Aa1, Aa2, Ab1, Ab2, Ba1, Ba2, Bb1, Bb2];
- 如果还有后续数组,重复上述过程;
关键点就是将上面的乘法用代码表示,用递归实现,关键的计算公式是:计算(已计算的结果 * 当前结果)
实现sum(1)(2)(3).valueOf(),实现这么一个sum函数,返回6
解决思路:
- sum里面返回一个闭包函数;
- 闭包函数执行的是相加的逻辑;
- 重写闭包函数的valueOf,返回结果;
//实现sum(1)(2)(3).valueOf(),实现这么一个sum函数,返回6
function sum(arg1){
let sum=arg1;
let tmp = function(arg2){
sum = sum+arg2;
return tmp;
}
tmp.valueOf = function(){
return sum;
}
return tmp;
}
let result = sum(1)(2)(3).valueOf();
console.log(result);
优化http请求,限制并发请求数
思路:
- 用 Promise.race来实现,先并发请求3个图片资源,这样可以得到 3 个 Promise实例,组成一个数组promises;
- 然后不断的调用 Promise.race 来返回最快改变状态的 Promise,然后从数组(promises )中删掉这个 Promise 对象实例,再加入一个新的 Promise实例,直到全部的 url 被取完;
var urls = [
'https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg',
'https://www.kkkk1000.com/images/getImgData/gray.gif',
'https://www.kkkk1000.com/images/getImgData/Particle.gif',
'https://www.kkkk1000.com/images/getImgData/arithmetic.png',
'https://www.kkkk1000.com/images/getImgData/arithmetic2.gif',
'https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg',
'https://www.kkkk1000.com/images/getImgData/arithmetic.gif',
'https://www.kkkk1000.com/images/wxQrCode2.png'
];
function loadImg(url) {
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = function () {
console.log('一张图片加载完成');
resolve();
}
img.onerror = reject
img.src = url
})
};
function limitLoad(urls, handler, limit) {
// 对数组做一个拷贝
const sequence = [].concat(urls)
let promises = [];
//并发请求到最大数
promises = sequence.splice(0, limit).map((url, index) => {
// 这里返回的 index 是任务在 promises 的脚标,
//用于在 Promise.race 之后找到完成的任务脚标
return handler(url).then(() => {
return index
});
});
(async function loop() {
let p = Promise.race(promises);
for (let i = 0; i < sequence.length; i++) {
p = p.then((res) => {
//promise中替换:将队列中剩余的请求替换已经请求完成的请求
promises[res] = handler(sequence[i]).then(() => {
return res
});
return Promise.race(promises)
})
}
})()
}
limitLoad(urls, loadImg, 3);
根据传入的节点id找到对应的到达该节点的路径,并且找到其所有的没有子节点的叶子节点
数据构造:
let treeData = {
id:1,
children:[
{
id:11,
children:[
{
id:111
},
{
id:112
}
]
},
{
id:12,
children:[
{
id:121,
children:[
{
id:1211
}
]
},
{
id:122,
children:[
{
id:1221,
children:[
{
id:12211
}
]
},
{
id:1222,
}
]
}
]
}
]
};
题目描述:
- 写一个方法,可以根据传入的节点id找到对应的到达该节点的路径,并且找到其所有的没有子节点的叶子节点
- 比如传入的参数是id=122,则path='1-12-122',leaves为'12211-1222' 采用递归的方法实现
findPathAndLeaves(treeData,122);
function findPathAndLeaves(treeData,id){
let pResult = [],cResult=[];
findTarget(treeData,id);
findAllParents(treeData,id,pResult);
findChildren(target,cResult);
console.log('path---:',pResult.join('-'));
console.log('leaves---:',cResult.join('-'));
}
//查找所有的父节点
function findAllParents(treeData,id,pResult){
findParent(treeData,id);
if(pResult.indexOf(parentId)<0 && parentId){
pResult.push(parentId);
let _parentId = parentId;
parentId = '';
findAllParents(treeData,_parentId,pResult);
}
}
var target='';
var parentId;
//根据节点id查找其目标节点
function findTarget(treeData,id){
if(target){
return target;
}
if(!treeData){
return;
}
if(treeData.id === id){
return treeData;
}
if(treeData.children && treeData.children.length>0){
for(let item of treeData.children){
if(item.id === id){
target = item;
break;
}else{
findTarget(item,id);
}
}
}
}
//根据目标节点查找其父节点
function findParent(treeData,id){
if(parentId){
return parentId;
}
if(!treeData){
return;
}
if(treeData.id === id){
return treeData;
}
if(treeData.children && treeData.children.length>0){
for(let item of treeData.children){
if(item.id === id){
parentId = treeData.id;
break;
}else{
findParent(item,id);
}
}
}
}
//根据目标节点查找其没有叶子节点的子节点
function findChildren(target,cResult){
if(!target || !target.children){
return;
}
for(let item of target.children){
if(!item.children){
cResult.push(item.id);
}else{
findChildren(item,cResult);
}
}
}