Jacleklm's Blog

场景实现

2019/10/15

HTML & CSS

高度始终是宽度的 50%的盒子

一个 div 垂直居中;其距离屏幕左右两边各 10px;其高度始终是宽度的 50%
div 中有文本’A’;其 font—size:20px;文本水平垂直居中

1
2
width: calc(100vw - 20px);
height: calc(50vw - 10px);

上中下的 flex 布局,上下定高中间自适应

  • 父盒子写 display:flex; flex-direction: colum; 子盒子写 flex: 1
  • 父盒子写 height: calc(100vh - xx px) 或直接 100vh

实现一个图片容器

要求:

  • 图片宽度大于等于容器宽度时,要按容器宽度等比缩放图片,并垂直居中显示
  • 图片高度大于等于容器高度时,要按容器高度等比缩放图片,并水平居中显示
  • 图片宽高均小于等于容器宽高时,要按图片宽高显示并水平和垂直居中

不完美的方法一

利用 background 可以实现前两个要求,但是无法实现第三个要求

1
2
3
4
5
6
7
8
9
.div {
height: 400px;
width: 700px;
border: 1px solid black;
background-repeat: no-repeat;
background-size: contain;
background-position: center;
background-image: url('https://cdn.segmentfault.com/v-5e7dd7fe/global/img/user-64.png');
}

完美实现的方法二

flex布局实现垂直水平居中,图片设置 max-width 和 max-height 为 100% …好容易…

CSS 实现九宫格布局

要求:骰子的一面。hover 的时候数字的边框变红

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<div id="wrapper">
<div class="num">1</div>
<div class="num">2</div>
<div class="num">3</div>
<div class="num">4</div>
<div class="num">5</div>
<div class="num">6</div>
<div class="num">7</div>
<div class="num">8</div>
<div class="num">9</div>
</div>
<style>
#wrapper {
display: grid;
grid-template-columns: 50px 50px 50px;
grid-template-rows: 50px 50px 50px;
}
.num {
border: blue solid 5px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
/* border不重叠 */
margin-left: -5px;
margin-top: -5px;
}
.num:hover {
border-color: red;
/* 由于设置了负边距,得相对定位才能在hover时显示完整边框 */
position: relative;
}
</style>

做一个 todolist

要求:回车键后能把内容添加到 list 中;list 中点 x 能删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<body>
<h1>TodoList</h1>
<input type="text" name="" id="input" />
<div class="content">
<ul id="list"></ul>
</div>
<script>
let input = document.getElementById("input");
let ul = document.getElementById("list");
input.addEventListener("keydown", e => {
// keyCode 一定得区分大小写。添加部分
if (e.keyCode === 13 && input.value !== "") {
let li = document.createElement("li");
ul.appendChild(li);
li.innerHTML = `<span class="item">${input.value}</span><span id="x">x</span>`;
input.value = "";
// 移除部分
let x = li.children[1];
x.addEventListener("click", e => {
li.remove();
});
}
});
</script>
</body>

上传文件不用刷新页面的 JS 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<body>
<input type="file" />
<button id="btn">upload</button>
<script>
let btn = document.getElementById("btn");
btn.onclick = () => {
let file = document.querySelector("input[type='file']");
// 用formdata
let formdata = new FormData();
formdata.append("flie", file.files[0]);

fetch("/", {
method: "POST",
body: formdata
})
.then(response => response.json())
.then(data => {
console.log("Success:", data);
})
.catch(err => {
console.log("Error:", err);
});
};
</script>
</body>

上传文件读取文件名、大小、内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let file = document.querySelector("input");
// 选择文件后触发
file.onchange = () => {
document.getElementById("name").innerHTML = file.files[0].name;
document.getElementById("size").innerHTML = file.files[0].size;
document.getElementById("type").innerHTML = file.files[0].type;

let reader = new FileReader();
reader.readAsDataURL(file.files[0]);
// 读取的过程就相当于 加载过程,读取完会触发onload事件
reader.onload = (e) => {
// 读取结果 base64位数据 表示图片
console.log(e.target.result);
document.querySelector("#img").src = e.target.result;
};
};

实现鼠标拖拽 DOM

见另一篇博客

实现轮播

这篇博文总结的不错
需求:

  1. 鼠标移入轮播图时左右两边显示上一页下一页按钮,移出时隐藏
  2. 鼠标点击箭头,图片发生轮播
  3. 点击号码,切换到指定图片
  4. 鼠标移出,图片每隔一定时间自动轮播
  5. 当图片轮播到最后或最前一张的时候,图片无缝循环切换

思路:

  • DOM:div.screen>ul>li*5>img 放图片,ol>li 显示下标,div>span 显示箭头
  • 样式:让 li 标签 float 实现并排效果,div.screen 要设好宽高并 overflow:hidden 只显示出一张图,轮播的原理就是设置 ul.style.left 的值ul.style.left = -index * screen.offsetWidth + 'px' (变量 index 记录当前需要展示的图片的索引, screen 是外层那个 div)
  • 逻辑:
    • 一个全局变量 index 记录当前需要展示的图片的索引
    • 无限滚动的实现:复制第一张图放到原本图片集的最后。然后当是最后一张还向右滚动的话,就立刻改变 ul 的位置到第一张(index=0,ul.style.left = ….);同理第一向左滚动
    • 鼠标移入移出事件:鼠标移入,显示左右切换按钮,清除 setInterval 自动滚动;移出时隐藏按钮,新建 setInterval 自动滚动
    • 点击按钮
    • 封装一个滚动动画的函数,一个向右滚动函数 scroll,一个在滚动时能设置号码牌样式的函数 indexShow

写一个动画让一个div在水平的两个点之间来回运动

1
2
3
4
5
6
7
8
div {
animation: myanimation 3s infinite;
}
@keyframes myanimation {
0% {transform: translate(0px, 0px);}
50% {transform: translate(800px, 0px);}
100% {transform: translate(0px, 0px);}
}

实现一个前端缓存模块

实现一个前端缓存模块,主要用于缓存 xhr 返回的结果,避免多余的网络请求浪费,要求:

  • 生命周期为一次页面打开
  • 如果有相同的请求同时并行发起,要求其中一个能挂起并且等待另外一个请求返回并读取该缓存

前后端交互&跨域

JS

定时器正确输出

改正代码 输出 0123401234

1
2
3
4
5
6
7
8
9
10
function a() {
for (var i = 0; i < 5; i++) {
this.i = i;
setTimeout(function() {
console.log(i);
}, 0);
console.log(this.i);
}
}
a();

解答:上面这种方式,i 是全局变量;for 循环产生 5 个定时器,拿到全局 i 的时候已经 i=5 了(外层这个 function 和里面的 this 是来干扰的,去掉也无妨)。解决方法就是让变量 i 有块级作用域:let;闭包。
可改成

1
2
3
4
5
6
7
8
9
10
function a() {
for (let i = 0; i < 5; i++) {
this.i = i;
setTimeout(function() {
console.log(i);
}, 0);
console.log(this.i);
}
}
a();

也可以是

1
2
3
4
5
6
7
8
9
10
11
12
function a() {
for (let i = 0; i < 5; i++) {
(function(i) {
this.i = i;
setTimeout(function() {
console.log(i);
}, 0);
console.log(this.i);
})(i);
}
}
a();

编程题

readline()用于行的读取,最好是在一开始就读取完
print()用于输出结果

CATALOG
  1. 1. HTML & CSS
    1. 1.1. 高度始终是宽度的 50%的盒子
    2. 1.2. 上中下的 flex 布局,上下定高中间自适应
    3. 1.3. 实现一个图片容器
      1. 1.3.1. 不完美的方法一
      2. 1.3.2. 完美实现的方法二
    4. 1.4. CSS 实现九宫格布局
    5. 1.5. 做一个 todolist
    6. 1.6. 上传文件不用刷新页面的 JS 代码
    7. 1.7. 上传文件读取文件名、大小、内容
    8. 1.8. 实现鼠标拖拽 DOM
    9. 1.9. 实现轮播
    10. 1.10. 写一个动画让一个div在水平的两个点之间来回运动
    11. 1.11. 实现一个前端缓存模块
  2. 2. JS
    1. 2.1. 定时器正确输出
  3. 3. 编程题