废话
老规矩,废话部分,也是很久没写博客了。主要是最近都被工作缠身,没什么太多独立学习的内容。
一、forEach不是一个纯粹的同步函数
年前到年初的一段时间重构一个功能,需要接收话术市场数据结构,然后前端进行解析,重新排列数据,再纯前端数据整理,之后调用存储json的接口,存到后端。这里发生一个事情就是我有一个数据处理函数。里面使用纯forEach,不断嵌套,使用。最大层次达到3层,中间还有使用async await请求接口数据,然后等待得到结果的情况。
大致代码结构是如下
forEach(async () => {
const data = await fun
})
async fun () {
await data()
}
最后我得到的数据在数据量较少情况下一开始没有发生问题,后来数据较多的一次发生情况,我的数据最后之间被返回出去了,没有被处理。
最后发现,类似上述代码情况,要使用for循环代替foreach情况,否则,你的数据就会处理不完全。结果是错的。
这个属于一个小知识点吧。
二、最近做了一个ipad端,横屏的,引发的rem适配问题
做横屏的时候说实在,rem适配发现在手机端完全错误了。但是我手机原生浏览器没问题。
设备信息:小米6,原生浏览器,百度,uc,QQ,原生没问题,uc,qq,百度全军覆没。
我的方案是,下面是适配ipad端的方式
html {
font-size: calc(100vw/1024);
}
上面的代码适配ipad的,电脑,等等都没问题。但是手机端就完全行不通。页面错的厉害。
我个人最后是放弃了rem适配方案,采用了vw去适配响应式,效果出奇的好,完美适配。
最后分享下vw和各个设计图比值
设计图比值
1240:0.08065vw
1024: 0.09765625vw
####手机
750: 0.1333vw
375: 0.2667vw
我个人后来也是多方百度,猜测的结果应该是font-size值太小了,发生了最小font-size问题。但是我没机会验证了,主要是发生vw有点香。你不去适配很老的机型就完全OK啊。
不过我大致也知道了我上面的rem方式应该最后再乘以100,这样就不会发生最小font-size问题了。也是为什么大家对于rem一般采用除以20或者10的方式了。
真的很好奇,小程序的rpx单位怎么实现的。
三、总结一个函数,包含页面下拉,滚动到底部,监听页面返回,页面滚动,页面显示隐藏等功能。
当然这个代码是存在缺陷的。
特别是页面下拉和滚动到底部的监听容易发生问题。
关于页面下拉监听推荐使用vant封装的组件,或者自己去封装一个。
然后页面滚动到底部这个组件因为vant没有封装,那么我只能自己再封装一个了。核心函数是上面js里面拿出来的。
vue3组件:文档地址
<template>
<div class="root" @scroll="OnScroll" ref="root">
<slot></slot>
</div>
</template>
<script>
import { ref, defineComponent, onBeforeUnmount, onMounted } from 'vue'
export default defineComponent({
name: 'DhtReachBottom',
emit: ['load', 'roll'],
props: {
bottom: {
type: Number,
default: 10,
},
},
setup(props, ctx) {
const root = ref('root')
let _currentScroll = 0 // 当前滚动距离,判断上还是下
let _isOnReachBottom = false // 是否触发过滑动到底部事件,保证不会一次性触发多次事件
function OnScroll() {
const dom = root.value
const clientHeight = dom.clientHeight
const contentHeight = dom.scrollHeight //内容高度
const scrollTop = dom.scrollTop // 滚动距离
const scollType = scrollTop >= _currentScroll ? 'down' : 'up'
const BottomDistance = contentHeight - clientHeight - scrollTop
// 页面滚动事件
ctx.emit('roll', {
dom: dom,
clientHeight,
contentHeight,
scrollTop,
PercentageDown: scrollTop / (contentHeight - clientHeight), // 向下滚动百分比
BottomDistance: BottomDistance, // 底部距离,px
})
//到达底部10px时,页面滚动到底部的事件
if (!_isOnReachBottom && scollType === 'down' && BottomDistance <= props.bottom) {
_isOnReachBottom = true
ctx.emit('load')
}
if (scollType === 'up') {
_isOnReachBottom = false
}
_currentScroll = scrollTop
}
return {
root,
OnScroll,
}
},
})
</script>
<style scoped lang="scss"></style>
四、监听页面大小变化,元素是否隐藏的问题
这个问题是因为ipad上面测试的时候会发生页面底部使用abslote或者fixed的元素会被输入框顶起来。部分机型,不是所有。这里提供一个解决方案就是页面变小的时候隐藏。之后再显示回来。
同样是vue3代码,使用的时候,导出一个ref:fiexdShow,根据这个去控制显隐就行了
import { ref, onBeforeUnmount, onDeactivated, watch, reactive } from 'vue'
export default function () {
const fiexdShow = ref(true) // 显示或者隐藏
onBeforeUnmount(() => {
window.removeEventListener('resize', heightscroll)
})
onDeactivated(() => {
window.removeEventListener('resize', heightscroll)
})
const h2 = reactive({
docmHeight: document.documentElement.clientHeight, //默认屏幕高度
showHeight: document.documentElement.clientHeight, //实时屏幕高度
})
window.addEventListener('resize', heightscroll)
function heightscroll() {
h2.showHeight = document.documentElement.clientHeight
}
watch(
() => h2.showHeight,
() => {
if (h2.docmHeight > h2.showHeight) {
fiexdShow.value = false
} else {
fiexdShow.value = true
}
},
)
return {
fiexdShow,
}
}
五、我们常用的navigator.userAgent无法判断出来安卓平板是手机还是ipad
这个问题真的是操蛋的很,一来是我电脑上面测的好好的,结果到平板上面就各种不行啊。最后发现,到安卓平板上面得出的只是安卓系统,也就是只能是手机,但不知道是平板还是手机。
还好项目还没三端适配,我直接给干成全ipad页面了。但是这个问题也是很困扰,多方百度情况下,本来想获取页面物理英寸判断,但是貌似不管用。
最后发现也就像素比较好使了。但是像素有点靠经验判断。我总结一个函数
但是实际使用建议大家根据横竖屏再判断一下
// 根据px判断是手机端,pc,平板
export default function clientPX() {
const width = window.screen.width
if (width <= 600) {
return 'mobile'
}
if (width > 600 && width < 960) {
return 'ipad'
}
return 'pc'
}
横竖屏判断
// 判断横屏还是竖屏
export function orientation() {
const clientWidth = document.documentElement.clientWidth
const clientHeight = document.documentElement.clientHeight
// 横
if (clientWidth >= clientHeight) return 'vertical'
else return 'transverse' // 竖
}
六、canvas生成二维码并且下载图片和a标签下载提供
// 利用a标签下载东西
export function Download(url) {
if (!url) return false
let a = document.createElement('a')
a.href = url
a.download = url
a.click()
a = null
}
canvas生成二维码,下载
import QRCode from 'qrcode'
export default function (text, name = '二维码.png') {
let canvas = document.createElement('canvas')
return new Promise((resolve, reject) => {
QRCode.toCanvas(
canvas,
text,
{
width: 400,
height: 400,
},
function (error) {
if (error) reject(error)
else {
const fullQuality = canvas.toDataURL('image/jpeg', 1.0)
let save_link = document.createElement('a')
save_link.href = fullQuality
save_link.download = name
save_link.click()
save_link = null
canvas = null
return resolve()
}
},
)
})
}
致谢:
感谢观赏,喜欢点个赞。