/***
*
* js媒体查询
* @param opt
* @return {{}}
* @example:
createMediaList({
480(ctx){
console.log('is 480',ctx)
},
880(ctx){
console.log('is 880',ctx)
},
1220(ctx){
console.log('is 1220',ctx)
},
1440(ctx){
console.log('is 1440',ctx)
},
})
*
*/
export function createMediaList(opt) {
for (let optKey in opt) {
let mediaCtx = window !== undefined ? window.matchMedia(`(max-width: ${optKey}px)`) : global.matchMedia(`(max-width: ${optKey}px)`)
if (mediaCtx ?.matches) {
opt[optKey](mediaCtx)
}
mediaCtx.addListener(opt[optKey])
}
}
/**
*
* 对象转换成css样式变量
* @param obj
* @param prefix
* @return {{}}
*/
export function conversionStyleVal(obj, prefix) {
let res = {}
for (let key in obj) {
if (obj[key] instanceof Object) {
!prefix ? res[key] = conversionStyleVal(obj[key], key) :
Object.assign(res, conversionStyleVal(obj[key], key))
} else {
prefix ? res['--' + prefix + key] = obj[key] :
res['--' + key] = obj[key]
}
}
return res
}
/**
* 滑动到指定位置触发动画
* 需要放到onMounted使用
* @param {*} tagDom (需要触发的class盒子,可读取子级,一般填最外层盒子)
* author: hyw
*
* 用法:
*
* htmlAddAnimations('box')
*
* 参数说明:
* data-animation: 填写需要添加的动画效果class名 (https://animate.style/)(https://blog.csdn.net/a1056244734/article/details/113884374)
* op0:除 /可视区域/ 外在class加上此class名
*/
export function htmlAddAnimations(opt) {
let oTagDomList = opt?.tagDom ? [...document.getElementsByClassName(opt.tagDom)[0].querySelectorAll('*')] : [...document.body.querySelectorAll('*')],
domAnimationInfoPool = []
oTagDomList.map((domItem, idx) => {
let animationName = domItem.getAttribute('data-animation')
if (animationName) {
domAnimationInfoPool.push({
dom: domItem,
animationName
})
}
})
let windowScrollEvent = function (e) {
for (let i = domAnimationInfoPool.length - 1; i >= 0; i--) {
let infoItem = domAnimationInfoPool[i]
if (infoItem.dom.getBoundingClientRect().top +
infoItem.dom.getBoundingClientRect().height <
window.innerHeight * (opt?.preload || 1.5)) {
infoItem.dom.classList.remove('op0')
infoItem.animationName.split(' ').map(item => {
if (item) {
infoItem.dom.classList.add(item)
}
})
}
}
}
window.addEventListener('scroll', windowScrollEvent, false)
windowScrollEvent()
}
/**
*
* @param opt
* opt:{
* 触发的分辨率:要减少的字体
* }
* 需要放到onMounted使用
* @example:
* 使用前要在对应的容器加上类名:font-size-box
* fontSizeReactive({
* 880:1,
* 480:2
* })
* 这里要注意的是,减少的字体是会叠加减少的,例如:
* 我初始字体是15px,我的配置项为
* {
* 880:1,
* 480:2
* },一般来说按照这个配置项的话,我字体在屏幕小于880px的时候会变成14px,在小于480的时候会变成13px
* 但实际的话是在小于880的时候会变成14px,小于480的时候会变成12px,也就是会把880也算上
*/
export function fontSizeReactive(opt = {
880: 1,
480: 1,
}) {
let oBox = document.getElementsByClassName('font-size-box')[0]
let tag = oBox ? [...oBox.querySelectorAll('*')] : [...document.querySelectorAll('*')]
tag.map(item => {
let fontSize = getComputedStyle(item, null)['fontSize'].replace('px', '')
item.style.setProperty('font-size', fontSize + 'px')
})
let fnTpl = ''
for (let key in opt) {
fnTpl += `
${key}(ctx) {
if (ctx.matches) {
tag.map(item => {
item.style.fontSize = item.style.fontSize.replace('px', '') - ${opt[key]} + 'px'
})
} else {
tag.map(item => {
item.style.fontSize = Number(item.style.fontSize.replace('px', '')) + ${opt[key]} + 'px'
})
}
},`
}
(new Function('fn,tag', `
fn({
${fnTpl}
})
`))(function (opt) {
for (let optKey in opt) {
let mediaCtx = window !== undefined ? window.matchMedia(`(max-width: ${optKey}px)`) : global.matchMedia(`(max-width: ${optKey}px)`)
if (mediaCtx ?.matches) {
opt[optKey](mediaCtx)
}
mediaCtx.addListener(opt[optKey])
}
}, tag)
}