查漏补缺(十一)
移动端横竖屏监听
orientation属性
- 0(竖屏模式):portrait
- -90(设备逆时针旋转):landscape
- 90(设备顺时针旋转):landscape
//orientationchange事件
window.addEventListener('orientationchange', function(){
let orientation = window.orientation
switch(orientation){
case 90:
case -90:
orientation = 'landscape'
break;
default:
orientation = 'portrait'
}
})
//onorientationchange事件
<div id="box"></div>
window.onrientationchange = toOrientation
function toOrientation() {
let box = document.querySelector("#box");
let orientation = window.orientation
if (window.orientation == 90 || window.orientation == -90) {
orientation = 'landscape'
console.log(box.parentNode);
box.parentNode.setAttribute('class',orientation);
} else {
orientation = 'portrait'
box.parentNode.setAttribute('class',orientation);
}
}
window.onorientationchange()
/**竖屏 body显示红色**/
.portrait div{
background: red;
}
/**横屏 body显示蓝色**/
.landscape div{
background: blue;
}
viewport适配
initial-scale = 屏幕的宽度 / 设计稿的宽度
<head>
<script>
const WIDTH = 750
const mobileAdapter = () => {
let scale = screen.width / WIDTH
let content = `width=${WIDTH}, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}`
let meta = document.querySelector('meta[name=viewport]')
if (!meta) {
meta = document.createElement('meta')
meta.setAttribute('name', 'viewport')
document.head.appendChild(meta)
}
meta.setAttribute('content',content)
}
mobileAdapter()
window.onorientationchange = mobileAdapter //屏幕翻转时再次执行
</script>
</head>
移动端双击300ms的延迟
移动端要判断用户是单击还是双击,如果用户点击300ms内没有进行其他操作,则为单击,否则判断为双击。如何解决300ms延迟的问题?
- 设置禁止缩放
<meta name="viewport" content="user-scalable=no">
- 封装判断函数
function tap(ele, callback){
let isMove = falase
let startTime = 0
ele.addEventListener('touchstart', function(){
startTime = Date.now()
})
ele.addEventListener('touchmove', function(){
isMove = true
})
ele.addEventListener('touchend', function(){
if(!isMove && (Date.now()-startTime)<150){
callback && callback()
}
isMove = false
startTime = 0
})
}
- 使用fastclick插件
//安装插件
cnpm install fastclick --save
//全局引入 main.js
import fastClick from 'fastclick'
//配置一下
fastClick.attach(document.body)
fastclick官网链接:https://github.com/ftlabs/fastclick
https://blog.csdn.net/LILEILEILOVE/article/details/122587764
小数精度问题
var one = 0.1
var two = 0.2
var six = 0.6
var eight = 0.8
console.log([two - one == one, eight - six == two]) //[true, false]
简单判断:0.2-0.1=0.1的原因是0.2是0.1的2倍,二进制乘2或者除2,左移或又移一位就行,所以0.2-0.1=0.1,但是0.8不是0.6的倍数,所以0.8-0.6!=0.2。本题考察JS计算的精度问题。
JS数值类型计算的精度问题
由于JS的Number类型使用IEEE 754 格式,不区分浮点型和整数型,因此在转换成二进制的时候会出现精度丢失的问题。我们在对小数进行计算时需要使用函数库或者自己写函数对数值进行处理,以防出现精度问题。
(一)自己写函数
- 小数乘法
//先把小数转为字符串,找出小数位,将两个字符串相乘的值除以10的m次幂
function multify(a, b){
let m = 0
const val1 = String(a)
const val2 = String(b)
if(val1.includes('.')){
m += val1.split('.')[1].length || 0
}
if(val2.includes('.')){
m += val2.split('.')[1].length || 0
}
return (Number(val1.replace('.', '')) * Number(val2.replace('.', ''))) / (10 ** m)
}
console.log(multify(1222.1,100000)) // 122210000
- 小数除法
//先把小数转为字符串,找出小数位,将两个字符串相除的值乘以10的n-m次幂
function division(a, b){
let m=0, n=0
let val1 = String(a)
let val2 = String(b)
if(val1.includes('.')){
m = val1.split('.')[1].length || 0
}
if(val2.includes('.')){
n = val2.split('.')[1].length || 0
}
return (Number(val1.replace('.', '')) / Number(val2.replace('.', ''))) * (10 ** (n-m))
}
console.log(division(0.6, 3)) //0.2
- 小数加法
function add(a, b){
let m=0, n=0
let val1 = String(a)
let val2 = String(b)
if(val1.includes('.')){
m = val1.split('.')[1].length || 0
}
if(val2.includes('.')){
n = val2.split('.')[1].length || 0
}
let len = Math.max(m, n)
return (a*(10**len) + b*(10**len)) / (10**len)
}
console.log(add(0.2, 0.1)) //0.3
- 小数减法
function subtraction(a, b){
let m=0, n=0
let val1 = String(a)
let val2 = String(b)
if(val1.includes('.')){
m = val1.split('.')[1].length || 0
}
if(val2.includes('.')){
n = val2.split('.')[1].length || 0
}
let len = Math.max(m, n)
return (a*(10**len) - b*(10**len)) / (10**len)
}
console.log(add(0.2, 0.1)) //0.1
- toPrecision()方法
以指定的精度(1-100)返回该数值对象的字符串,四舍五入参数显示指定的数字位数
let num = 1234.56789
num.toPrecision() //1234.56789,如果没有值调用toString方法返回原始值的字符串形式
num.toPrecision(5) //1234.6
num.toPrecision(10) //1234.567890
num.toPrecision(101) //超出100报错
(二)使用插件
- number-precision库
import NP from 'number-precision'
NP.strip(0.09999999999999998); // = 0.1
NP.times(3, 0.3); // 3 * 0.3 = 0.9, not 0.8999999999999999
NP.divide(1.21, 1.1); // 1.21 / 1.1 = 1.1, not 1.0999999999999999
NP.plus(0.1, 0.2); // 0.1 + 0.2 = 0.3, not 0.30000000000000004
NP.minus(1.0, 0.9); // 1.0 - 0.9 = 0.1, not 0.09999999999999998
- Math.js库
//安装
npm install mathjs
import * as math from 'mathjs'
math.add(0.1+0.2) //0.3
- decimal.js库
//安装
npm install --save decimal.js
import Decimal from 'decimal.js'
let a = 0.1
let b = 0.2
let sum = new Decimal(a).add(new Decimal(b)) //0.3
参考文章:https://juejin.cn/post/6944243108410458149
**的意思
console.log(2**3) //8,**表示2的3次方,**表示次方
input的image属性
创建一个图片按钮,但是image不是HTML5新增的内容
<input type="image" src="" width="" alt="" />
alt和title的区别
alt是指当图片遇到例如网络问题,无法展示时的替代图片的展示文字
title表示元素的额外信息,当鼠标移动到这个属性上时,会展示出title的内容,起到补充说明的作用
[“1”, “2”, “3”].map(parseInt)
//等价于
["1","2","3"].map((item, index)=> parseInt(item, index))
parseInt("1", 0) // 代表转换为10进制的整数 1
parseInt("2", 1) // 1不在2~36之内,所以解析为NaN
parseInt("3", 2) // 2进制之内不会有3,所以解析为NaN
一些经典的面试题
https://zhuanlan.zhihu.com/p/65730012/
https://juejin.cn/post/6844904041000992781