js-learn's People
js-learn's Issues
JS实现回到页面顶部
scrollTop
scrollTop属性表示被隐藏在内容区域上方的像素数。元素未滚动时,scrollTop的值为0,如果元素被垂直滚动了,scrollTop的值大于0,且表示元素上方不可见内容的像素宽度
由于scrollTop是可写的,可以利用scrollTop来实现回到顶部的功能
function scrollToTop() {
document.body.scrollTop = document.documentElement.scrollTop = 0;
}
scrollTo
function scrollToTop() {
scrollTo(0, 0);
}
scrollTo(x,y)方法滚动当前window中显示的文档,让文档中由坐标x和y指定的点位于显示区域的左上角
设置scrollTo(0,0)可以实现回到顶部的效果
scrollIntoView()
Element.scrollIntoView方法滚动当前元素,进入浏览器的可见区域
function scrollToTop() {
const app = document.querySelector("#app");
app.scrollIntoView();
}
优化
控制按钮的显示与隐藏
要注意,display: none;
的属性是无法被hover的
new操作符以及es6转成es5
new操作符
es6 通过babel转成es5
objFactory就类似于new操作符的作用
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
var objFactory = function () {
let obj = new Object();
// 获取实参的第一个值
// 等效于 arguments.shift()
Constructor = [].shift.call(arguments); // arguments 实参 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments
// arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。例如,它没有 pop 方法。但是它可以被转换为一个真正的Array
obj.__proto__ = Constructor.prototype;
// 修改Constructor(这里是指Person)里的this指向obj
// 所以obj.name = 'seven'
// 这里argiments第一个值已经被shift() 了
var ret = Constructor.apply(obj, arguments);
console.log(ret);
// var ret = Person.apply(obj, arguments);
return typeof ret === 'object' ? ret : obj;
};
// let a = new Person('seven');
var a = objFactory(Person, 'seven');
console.log(a.name);
console.log(a.getName());
console.log(Object.getPrototypeOf(a) === Person.prototype);
Mockjs使用
使用
import mockjs from 'mockjs'
mockjs.mock('/api/getdata', 'get', {
code: 200,
body: {
name: 'zs',
age: 20
}
})
然后在需要使用的页面引入即可
如果使用fetch请求的话,则需要额外安装fetchMock
import fetchMock from 'fetch-mock'
// 初始化 fetch-mock
fetchMock.config.overwriteRoutes = true
fetchMock.mock('/api/getdata1', {
code: 200,
data: {
username: 'mock',
age: 18
}
})
规则
http://mockjs.com/examples.html
@id // 随机身份证
@guid // 随机id
@ip // 随机ip地址
// 数字
"number|1-100": 100 // 随机数字1-100内
"number|+1": 202 // 202开始自增1
// 布尔值
'boolean': '@boolean'
// 或者用0/1代替
'numnber|0-1': 0
// 时间
@date
Random.date('yyyy-MM-dd')
@time
// 姓名
@name
Random.name()
@name(true) // 有middle name
图片懒加载
图片懒加载
先看几个API
// 获取屏幕可视区域的高度 (不包括滚动条)
document.documentElement.clientHeight
// 获取元素相对于文档顶部的高度
element.offsetTop
// 获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离
document.documentElement.scrollTop
通过判断
element.offsetTop - document.documentElement.scrollTop < document.documentElement.clientHeight
来确定元素是否进入到了可视区域
<img data-src="./images/1.jpeg" alt="" />
<img data-src="./images/2.png" alt="" />
<img data-src="./images/3.png" alt="" />
<img data-src="./images/4.png" alt="" />
<img data-src="./images/5.png" alt="" />
<img data-src="./images/6.jpeg" alt="" />
<img data-src="./images/7.png" alt="" />
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script>
let imgs = document.querySelectorAll('img');
function getTop(e) {
let T = e.offsetTop;
while ((e = e.offsetParent)) {
T += e.offsetTop;
}
return T;
}
function lazyLoad(imgs) {
let H = document.documentElement.clientHeight; // 获取可视区域高度
let S = document.documentElement.scrollTop || document.body.scrollTop;
imgs.forEach((item) => {
if (H + S > getTop(item)) {
item.src = item.getAttribute('data-src');
}
});
}
window.onload = window.onscroll = () => {
lazyLoad(imgs);
};
_.throttle(window.onscroll, 1000);
</script>
这里用到了一个知识:
img标签在没有src属性的时候是不会去请求的。
Element.getBoundingClientRect()
返回元素的大小及其相对于视口的位置(相对于可视区域左上角)
const bound = el.getBoundingClientRect();
当bound == clientHeight 时,说明元素即将进入可视区域了 。
所以bound <= clientHeight ,图片是在可视区域内的
bound<0 图片离开了可视区域
Intersection Observer API
mdn的解释:
Intersection Observer API提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。
<img data-src="./images/1.jpeg" alt="" />
<img data-src="./images/2.png" alt="" />
<img data-src="./images/3.png" alt="" />
<img data-src="./images/4.png" alt="" />
<img data-src="./images/5.png" alt="" />
<img data-src="./images/6.jpeg" alt="" />
<script>
let imgs = document.querySelectorAll('img');
let callback = (e) => {
// console.log(e);
let el = e[0].target;
// set src attribute to load img
el.src = el.dataset.src;
};
let observer = new IntersectionObserver(callback);
imgs.forEach((img, i) => {
observer.observe(img);
});
</script>
参考文档:
FormData上传二进制文件
multipart/form-data
https://zhuanlan.zhihu.com/p/120834588
一个简单的例子:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryNcxNYP2Llirw6P9C
Content-Type 文件类型
boundary 分隔符 分隔符的作用?多文件多字段时用于划分
看Request body
Request Payload:
------WebKitFormBoundary3BCUw6TpNMWxyC8B
Content-Disposition: form-data; name="myfile"; filename="5g.png"
Content-Type: image/png
------WebKitFormBoundary3BCUw6TpNMWxyC8B--
其中有文件名,formdata.append() 的name字段 以及Content-Type 具体的文件类型
后端接收的文件格式
------WebKitFormBoundaryOjAKFnxCzqgLffEj
Content-Disposition: form-data; name="name"
zs
------WebKitFormBoundaryOjAKFnxCzqgLffEj--
遇到的问题❓
1.Ajax formdata 为空的问题?
在使用ajax上传图片时打印formdata 显示FormData {}
解决办法:
FormData 不能被console.log
使用原生ajax发送formdata,后台接受不到数据;而使用axios来发送请求却可以收到。
1.这是因为使用ajax处理二进制数据时,需要使用XMLHttpRequest
对象的 overrideMimeType()
方法。
var oReq = new XMLHttpRequest();
oReq.open("GET", url);
// 以二进制字符串形式检索未处理的数据
oReq.overrideMimeType("text/plain; charset=x-user-defined");
/* ... */
2.也可以修改XMLHttpRequest的responseType
属性
xhr.open('POST', 'http://127.0.0.1:3000', true);
// xhr.setRequestHeader(
// 'Content-Type',
// 'multipart/form-data;boundary=----WebKitFormBoundaryVFmi5Doq4aeH0RQ1'
// );//无效
// xhr.overrideMimeType('multipart/form-data'); //有效
xhr.responseType = 'blob'; //有效
xhr.send(formdata);
Boolean运算
Boolean('') // false
Boolean(0) // false
!!
符号与Boolean() 功能一样
TypeScript-元组
const arr = [['1', 1], ['2', 2]]
想给上面的二维数组定义一个类型,发现无从下手。
经人提醒想起来元组这个概念
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
于是
type T1 = Array<[string,number]>
这样就可以
sort排序
MDN
sort排序是升序排序
const List = [
{ name: 'zs', age: 20 },
{ name: 'zs', age: 30 },
{ name: 'zs', age: 50 },
{ name: 'zs', age: 80 },
{ name: 'zs', age: 17 },
{ name: 'zs', age: 33 }
]
const List2 = List.sort((a, b) => {
return a.age - b.age
})
- 如果 compareFn(a, b) 大于 0,b 会被排列到 a 之前。小的排在大的前面,即升序
- 如果 compareFn(a, b) 小于 0,那么 a 会被排列到 b 之前;
onevent和addEventListener的区别?
http://if-true.com/2018/09/20/onclick-vs-addEventListener.html
onevent vs addEventListener ?
- Listener(s)
onclick只能绑定一个事件处理函数,并且可以通过设为null
进行移除;
而addEventListener 可以绑定多个事件处理函数,并且可以进行更精细的控制(通过第三个参数,包括 capture、once、passive)等,可以通过 removeEventListener 移除。
<div id="app">Button</div>
const app = document.getElementById('app');
app.onclick = () => {
console.log(123);
};
app.onclick = () => {
console.log(456);
};
app.addEventListener('click', () => {
console.log(789);
});
app.addEventListener('click', () => {
console.log(890);
});
上面的代码中,123会被456覆盖,而789就不会被890覆盖。
- 事件流阶段
事件流有3个阶段:捕获、到达目标、冒泡。可以通过 event.eventPhase 来判断当前。捕获(1)、到达目标(2)、冒泡(3),还有个 None(0)状态,表示该事件已经被处理。
addEventListener 可以根据第三个参数来决定事件处理发生在哪个阶段。而 onclick 往往在冒泡阶段触发。(这个说法并不准确,根据 DOM 结构不同,可能在冒泡也有可能在到达目标阶段)。
当 addEventListener 和 onclick 同时绑定且前者指定冒泡阶段时,按照绑定先后顺序依次触发。
什么是纯函数
纯函数 Pure Function
纯函数符合一下两个条件:
- 返回结果只依赖于它的参数
- 执行过程无任何副作用
纯函数的好处
纯函数非常“靠谱”,执行一个纯函数你不用担心它会干什么坏事,它不会产生不可预料的行为,也不会对外部产生影响。
不管何时何地,你给它什么它就会乖乖地吐出什么。如果你的应用程序大多数函数都是由纯函数组成,那么你的程序测试、调试起来会非常方便。
鼠标拖拽事件mousemove
鼠标按下触发mousedown事件,拖拽触发mousemove事件,但是松开不触发mouseup
需要e.preventDefault 阻止mousemove的默认事件
组件拖拽过程中drop事件 (当元素或选中的文本在可释放目标上被释放时触发),为了获取到触发元素冒泡过程中的所有元素,使用event.path属性,但是这个属性在Firefox下并不存在
百度后的解决方案
e.path || (e.composedPath && e.composedPath())
e.path是Chrome单独支持的属性,不属于MDN的标准,所以在MDN上搜不到event.path,但是composedPath是标准的属性。
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.