generated from nuxt/nuxt_site
197 lines
5.7 KiB
JavaScript
197 lines
5.7 KiB
JavaScript
/***
|
||
*
|
||
* 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)
|
||
},
|
||
})
|
||
*
|
||
*/
|
||
import {debounce} from "~/utils/utils";
|
||
|
||
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
|
||
*
|
||
* 用法:
|
||
* <div data-animation="animate__animated animate__fadeInLeft" class="box op0">
|
||
* 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 <
|
||
window.innerHeight * (opt?.preload || 1)) {
|
||
infoItem.dom.classList.remove('op0')
|
||
infoItem.animationName.split(' ').map(item => {
|
||
if (item) {
|
||
infoItem.dom.classList.add(item)
|
||
}
|
||
})
|
||
} else if (opt?.isRe) {
|
||
infoItem.dom.classList.add('op0')
|
||
infoItem.animationName.split(' ').map(item => {
|
||
if (item) {
|
||
infoItem.dom.classList.remove(item)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
window.addEventListener('scroll', opt?.openDelay ? debounce(windowScrollEvent,opt?.debounceNumber || 60) : 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,
|
||
}) {
|
||
return
|
||
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)
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param element
|
||
* @returns {{top: number, left: number}}
|
||
*/
|
||
export function getElementPosition(element) {
|
||
let top = element.offsetTop //这是获取元素距父元素顶部的距离
|
||
let left = element.offsetLeft
|
||
var current = element.offsetParent //这是获取父元素
|
||
while (current !== null) {
|
||
//当它上面有元素时就继续执行
|
||
top += current.offsetTop //这是获取父元素距它的父元素顶部的距离累加起来
|
||
left += current.offsetLeft
|
||
current = current.offsetParent //继续找父元素
|
||
}
|
||
return {
|
||
top,
|
||
left,
|
||
}
|
||
}
|