vue pc端-移动端-ipad端适配
2023-12-30 05:04:43
全局使用transform:scale来进行适配
在utils下创建js文件,比如命名为:autofit.js
let currRenderDom = null;
let currelRectification = "";
let currelRectificationLevel = "";
let resizeListener = null;
let timer = null;
let currScale = 1;
let isAutofitRunnig = false;
let isElRectification = false;
let keyboardHeight = 0;
const autofit = {
init(options = {}, isShowInitTip = true) {
if (isShowInitTip) {
console.log(
`%c` + `autofit.js` + ` is running`,
`font-weight: bold; color: #ffb712; background:linear-gradient(-45deg, #bd34fe 50%, #47caff 50% );background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );background-clip: text;-webkit-background-clip: text; -webkit-text-fill-color:linear-gradient( -45deg, #bd34fe 50%, #47caff 50% ); padding: 8px 12px; border-radius: 4px;`
);
console.log(options.dw);
}
const {
dw = 1920,
dh = 929,
el = typeof options === "string" ? options : "#app",
resize = true,
ignore = [],
transition = "none",
delay = 0,
} = options;
currRenderDom = el;
let dom = document.querySelector(el);
if (!dom) {
console.error(`autofit: '${el}' is not exist`);
return;
}
defaultHeight = document.documentElement.clientHeight;
defaultWidth = document.documentElement.clientWidth;
const style = document.createElement("style");
const ignoreStyle = document.createElement("style");
style.lang = "text/css";
ignoreStyle.lang = "text/css";
style.id = "autofit-style";
ignoreStyle.id = "ignoreStyle";
style.innerHTML = `body {overflow: hidden;}`;
dom.appendChild(style);
dom.appendChild(ignoreStyle);
dom.style.height = `${dh}px`;
dom.style.width = `${dw}px`;
dom.style.transformOrigin = `0 0`;
keepFit(dw, dh, dom, ignore);
resizeListener = () => {
clearTimeout(timer);
if (delay != 0)
timer = setTimeout(() => {
keepFit(dw, dh, dom, ignore);
isElRectification &&
elRectification(currelRectification, currelRectificationLevel);
}, delay);
else {
keepFit(dw, dh, dom, ignore);
isElRectification &&
elRectification(currelRectification, currelRectificationLevel);
}
};
resize && window.addEventListener("resize", resizeListener);
isAutofitRunnig = true;
setTimeout(() => {
dom.style.transition = `${transition}s`;
});
},
off(el = "#app") {
try {
isElRectification = false;
window.removeEventListener("resize", resizeListener);
document.querySelector("#autofit-style").remove();
document.querySelector(currRenderDom ? currRenderDom : el).style = "";
isElRectification && offelRectification();
} catch (error) {
console.error(`autofit: Failed to remove normally`, error);
isAutofitRunnig = false;
}
isAutofitRunnig &&
console.log(
`%c` + `autofit.js` + ` is off`,
`font-weight: bold;color: #707070; background: #c9c9c9; padding: 8px 12px; border-radius: 4px;`
);
},
};
function elRectification(el, level = 1) {
if (!isAutofitRunnig) {
console.error("autofit.js:autofit has not been initialized yet");
}
!el && console.error(`autofit.js:bad selector: ${el}`);
currelRectification = el;
currelRectificationLevel = level;
const currEl = document.querySelectorAll(el);
if (currEl.length == 0) {
console.error("autofit.js:elRectification found no element");
return;
}
for (let item of currEl) {
if (!isElRectification) {
item.originalWidth = item.clientWidth;
item.originalHeight = item.clientHeight;
}
let rectification = currScale == 1 ? 1 : currScale * level;
item.style.width = `${item.originalWidth * rectification}px`;
item.style.height = `${item.originalHeight * rectification}px`;
item.style.transform = `scale(${1 / currScale})`;
item.style.transformOrigin = `0 0`;
}
isElRectification = true;
}
function offelRectification() {
if (!currelRectification) return;
for (let item of document.querySelectorAll(currelRectification)) {
item.style.width = ``;
item.style.height = ``;
item.style.transform = ``;
}
}
function keepFit(dw, dh, dom, ignore) {
let clientHeight = document.documentElement.clientHeight;
let clientWidth = document.documentElement.clientWidth;
currScale =
clientWidth / clientHeight < dw / dh ? clientWidth / dw : clientHeight / dh;
dom.style.height = `${clientHeight / currScale}px`;
dom.style.width = `${clientWidth / currScale}px`;
dom.style.transform = `scale(${currScale})`;
for (let item of ignore) {
let itemEl = item.el || item.dom;
typeof item == "string" && (itemEl = item);
if (!itemEl) {
console.error(`autofit: bad selector: ${itemEl}`);
continue;
}
let realScale = item.scale ? item.scale : 1 / currScale;
let realFontSize = realScale != currScale ? item.fontSize : "autofit";
let realWidth = realScale != currScale ? item.width : "autofit";
let realHeight = realScale != currScale ? item.height : "autofit";
let regex = new RegExp(`${itemEl}(\x20|{)`, "gm");
let isIgnored = regex.test(
document.querySelector("#ignoreStyle").innerHTML
);
if (isIgnored) {
continue;
}
document.querySelector("#ignoreStyle").innerHTML += `\n${itemEl} {
transform: scale(${realScale})!important;
transform-origin: 0 0;
width: ${realWidth}!important;
height: ${realHeight}!important;
}`;
document.querySelector(
"#ignoreStyle"
).innerHTML += `\n${itemEl} div ,${itemEl} span,${itemEl} a,${itemEl} * {
font-size: ${realFontSize}px;
}`;
}
}
export { elRectification };
export default autofit;
在App.vue中引入使用
import autofit from "@/utils/autofit";
autofit.init({
dh: 1080,
dw: 1920,
el: "#app",
resize: true,
});
如果想要某个不在上述设置的el下的dom也使用响应式,添加transform
- 在上述代码的基础上添加下述代码
// 定义一个需要额外添加transform的属性默认为false
let hasFlag = false
// 在init方法中的options额外添加一个参数needScaleClass
const {
dw = 1920,
dh = 929,
el = typeof options === 'string' ? options : '#app',
resize = true,
ignore = [],
transition = 'none',
delay = 0,
needScaleClass = ''
} = options
// 然后获取当前所有类名为needScaleClass的dom(init方法中)
let scaleDom = document.querySelectorAll(needScaleClass)
if (scaleDom) {
hasFlag = true
}
if (hasFlag) {
needScaleDom(dw, dh, scaleDom)
}
// resize监听中调用方法
resizeListener = () => {
clearTimeout(timer)
if (delay != 0)
timer = setTimeout(() => {
keepFit(dw, dh, dom, ignore)
if (hasFlag) {
needScaleDom(dw, dh, scaleDom)
}
isElRectification &&
elRectification(currelRectification, currelRectificationLevel)
}, delay)
else {
keepFit(dw, dh, dom, ignore)
if (hasFlag) {
needScaleDom(dw, dh, scaleDom)
}
isElRectification &&
elRectification(currelRectification, currelRectificationLevel)
}
}
setTimeout(() => {
dom.style.transition = `${transition}s`
if (hasFlag) {
for(let m = 0; m<scaleDom.length;m++) {
scaleDom[m].style.transition = `${transition}s`
}
}
})
//添加方法给dom赋值style
function needScaleDom (dw, dh, dom) {
let clientHeight = document.documentElement.clientHeight
let clientWidth = document.documentElement.clientWidth
currScale =
clientWidth / clientHeight < dw / dh ? clientWidth / dw : clientHeight / dh
for(let k = 0; k<dom.length;k++) {
dom[k].style.transform = `scale(${currScale})`
}
}
- App.vue中使用
import autofit from "@/utils/autofit";
autofit.init({
dh: 1080,
dw: 1920,
el: "#app",
resize: true,
needScaleClass: '.message-toolip-box',
});
在移动端的使用
在移动端的时候,如果又要输入内容的时候键盘弹起会导致可视页面变小,就会触发resize监听从而改变scale的值,但是如果我们在输入内容时不想改变页面大小想保持原状,上述代码需要添加键盘弹起判断了
// 全局定义默认宽高
let defaultHeight = 0;
let defaultWidth = 0;
// 在resize监听中
resizeListener = () => {
const windowHeight = window.innerHeight;
const windowWidth = window.innerWidth;
// 如果当前窗口高度小于默认高度,且宽度和默认宽度相等则说明键盘是打开状态
let keyboardHeight = defaultHeight - windowHeight;
if (keyboardHeight > 0 && windowWidth == defaultWidth) {
let transform = dom.style.transform;
const result = transform.slice(0, transform.indexOf(")") + 1);
let a = "translateY(-" + keyboardHeight + "px)";
dom.style.transform = result + a;
return;
}
// 宽度和默认宽度不相等,可能是切换了不同分辨率或者变为了横屏状态
if (windowWidth != defaultWidth) {
defaultHeight = document.documentElement.clientHeight;
defaultWidth = document.documentElement.clientWidth;
}
clearTimeout(timer);
if (delay != 0)
timer = setTimeout(() => {
keepFit(dw, dh, dom, ignore);
isElRectification &&
elRectification(currelRectification, currelRectificationLevel);
}, delay);
else {
keepFit(dw, dh, dom, ignore);
isElRectification &&
elRectification(currelRectification, currelRectificationLevel);
}
};
文章来源:https://blog.csdn.net/weixin_46328739/article/details/135285246
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!