当前位置: 首页 > news >正文

继上一篇,设置弹框次数以及自适应图片弹框,部分机型(vivo)老手机不显示的问题

上一篇写的本来测试好多型号都无事, 今天下午公司的战斗机vivo横空冒出…
晕 弹框直接显示都出不来了,现在还有用这种老的机型的,但是没办法咯~ 前端遇到这种兼容性的问题就要勇于解决
主要解决了这几点:

// 添加图片加载事件
<imgv-if="imageUrl":src="imageUrl"@load="handleImageLoad"@error="handleImageError"@click="handleImgClick"
/>// 图片加载完成后再显示
const handleImageLoad = () => {console.log('图片加载完成');imageLoaded.value = true;showPopup();
};

这确保了只有在图片真正加载完成后才显示弹框,避免了空白或闪烁。

多重渲染保护:

const showPopup = () => {requestAnimationFrame(() => {setTimeout(() => {isVisible.value = true;if (popupRef.value) {popupRef.value.style.transform = 'translateZ(0)';}}, 100);});
};

使用 requestAnimationFrame 和 setTimeout 的组合,确保在浏览器的下一帧渲染时才显示,这解决了 vivo 手机上的渲染时机问题。

显示状态控制:
const isVisible = ref(false);
const imageLoaded = ref(false);

const containerStyle = computed(() => ({
visibility: imageLoaded.value ? ‘visible’ : ‘hidden’
}));
使用独立的状态控制显示,而不是直接依赖数据加载。

硬件加速和性能优化:
.popup-container {
-webkit-transform: translateZ(0);
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000;
will-change: transform;
}

这些 CSS 属性强制启用硬件加速,提高渲染性能。
成功的关键在于:
正确的渲染时机:等待图片加载完成
可靠的显示控制:使用多重状态检查
性能优化:启用硬件加速
渲染队列:使用 requestAnimationFrame 确保正确的渲染顺序
这解决了 vivo 手机上的几个典型问题:
渲染时机不对导致的白屏
硬件加速缺失导致的显示问题
图片加载时机导致的布局问题
建议在类似场景下:
总是等待资源加载完成
使用多重渲染保护
添加必要的性能优化属性
保持良好的状态管理

<template><Teleport to="body"><div v-show="isVisible" class="popup-container" :style="containerStyle"><div class="popup-content" ref="popupRef"><imgv-if="imageUrl":src="imageUrl"@load="handleImageLoad"@error="handleImageError"@click="handleImgClick"/><div class="close-btn" @click="handleClose">×</div></div></div></Teleport>
</template><script setup>
import { ref, getCurrentInstance, onMounted, computed } from "vue";
import { getAdList, getConfing } from "@/api/base";const app = getCurrentInstance();
const proxy = app?.appContext.config.globalProperties;
const adPosition = proxy?.$global.AD_POSITION_HOME_POPUP;const diaData = ref({});
const currentPopupIndex = ref(0);
const isVisible = ref(false);
const popupRef = ref(null);
const imageLoaded = ref(false);
const maxShowCount = ref(0);const imageUrl = computed(() => {return diaData.value[adPosition]?.[currentPopupIndex.value]?.pic || "";
});const containerStyle = computed(() => ({visibility: imageLoaded.value ? "visible" : "hidden",
}));const handleImageLoad = () => {console.log("图片加载完成===");imageLoaded.value = true;if (checkCanShow()) {showPopup();} else {isVisible.value = false;currentPopupIndex.value = -1;}
};const handleImageError = (error) => {console.error("图片加载失败===", error);imageLoaded.value = false;
};const showPopup = () => {if (!checkCanShow()) {isVisible.value = false;currentPopupIndex.value = -1;return;}requestAnimationFrame(() => {setTimeout(() => {isVisible.value = true;if (popupRef.value) {popupRef.value.style.transform = "translateZ(0)";}}, 100);});
};// 处理图片点击
const handleImgClick = () => {if (diaData.value?.[adPosition]?.[currentPopupIndex.value]) {proxy?.$adRouter(diaData.value[adPosition][currentPopupIndex.value]);}
};// 处理关闭按钮点击
const handleClose = () => {incrementShowCount();// 检查是否达到最大显示次数if (!checkCanShow()) {isVisible.value = false; // 隐藏整个弹框(包括遮罩)currentPopupIndex.value = -1;return;}if (currentPopupIndex.value < diaData.value[adPosition]?.length - 1) {// 切换到下一张前重置状态imageLoaded.value = false;currentPopupIndex.value++;} else {isVisible.value = false;currentPopupIndex.value = -1;}
};const getTodayShowCount = () => {const today = new Date().toDateString();const storageKey = "popupShowCount_" + today;return parseInt(localStorage.getItem(storageKey) || "0");
};const incrementShowCount = () => {const today = new Date().toDateString();const storageKey = "popupShowCount_" + today;const currentCount = getTodayShowCount();localStorage.setItem(storageKey, (currentCount + 1).toString());
};const checkCanShow = () => {const currentCount = getTodayShowCount();return currentCount < maxShowCount.value;
};onMounted(async () => {try {// 先获取配置的最大显示次数const configRes = await getConfing({ key: proxy.$global.ImageDialogCount });maxShowCount.value = parseInt(configRes.data[0].configValue || "0");console.log("最大显示次数:", maxShowCount.value);// 检查是否可以显示if (checkCanShow()) {// 获取广告数据const res = await getAdList({regionType: [adPosition],});if (res.data) {diaData.value = res.data;console.log("广告数据获取成功:", diaData.value);// 确保数据存在if (diaData.value[adPosition]?.length > 0) {currentPopupIndex.value = 0;}}} else {console.log("已达到最大显示次数");}} catch (error) {cconsole.log("err的信息", error);}
});
</script><style lang="scss" scoped>
.popup-container {position: fixed;top: 0;left: 0;right: 0;bottom: 0;width: 100vw;height: 100vh;background: rgba(0, 0, 0, 0.5);display: flex;justify-content: center;align-items: center;z-index: 999;margin: 0;padding: 0;-webkit-transform: translateZ(0);transform: translateZ(0);backface-visibility: hidden;perspective: 1000;will-change: transform;
}.popup-content {position: relative;width: fit-content;margin: auto;-webkit-transform: translateZ(0);transform: translateZ(0);img {display: block;width: 80vw;max-height: 80vh;object-fit: contain;-webkit-touch-callout: none;user-select: none;-webkit-user-select: none;pointer-events: auto;backface-visibility: hidden;-webkit-backface-visibility: hidden;}
}.close-btn {position: absolute;top: -30px;right: 0;width: 30px;height: 30px;background: rgba(255, 255, 255, 0.8);border-radius: 50%;display: flex;justify-content: center;align-items: center;cursor: pointer;font-size: 20px;color: #333;z-index: 1000;-webkit-tap-highlight-color: transparent;&:active {background: #fff;}
}
</style>

完整代码 解决~

相关文章:

继上一篇,设置弹框次数以及自适应图片弹框,部分机型(vivo)老手机不显示的问题

上一篇写的本来测试好多型号都无事, 今天下午公司的战斗机vivo横空冒出… 晕 弹框直接显示都出不来了,现在还有用这种老的机型的,但是没办法咯~ 前端遇到这种兼容性的问题就要勇于解决 主要解决了这几点: // 添加图片加载事件 <imgv-if"imageUrl":src"image…...

基于RISC-V 的代理内核实验(使用ub虚拟机安装基本环境)

1.安装支撑软件 第一步&#xff0c;安装依赖库 RISC-V交叉编译器的执行仍然需要一些本地支撑软件包&#xff0c;可使用以下命令安装&#xff1a; $ sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bis…...

【MMKV】HarmonyOS中的优秀轻量化存储方式

MMKV 引言 在移动应用开发的世界里&#xff0c;数据存储和管理是至关重要的一环。随着技术的不断进步&#xff0c;开发者们对于高性能、轻量级、易用的数据存储解决方案的需求日益增长。MMKV&#xff08;Memory Mapped Key-Value&#xff09;正是这样一个开源的高性能key-val…...

docker安装hadoop环境

一、使用docker搭建基础镜像 1、拉取centos系统镜像 # 我这里使用centos7为例子 docker pull centos:7 2、创建一个dockerfiler文件&#xff0c;用来构建自定义一个有ssh功能的centos镜像 # 基础镜像 FROM centos:7 # 作者 #MAINTAINER hadoop ADD Centos-7.repo /etc/yum.re…...

开源多媒体处理工具ffmpeg是什么?如何安装?使用ffmpeg将M3U8格式转换为MP4

目录 一、FFmpeg是什么二、安装FFmpeg&#xff08;windows&#xff09;三、将M3U8格式转换为MP4格式 一、FFmpeg是什么 FFmpeg是一款非常强大的开源多媒体处理工具&#xff0c;它几乎可以处理所有类型的视频、音频、字幕以及相关的元数据。 FFmpeg的主要用途包括但不限于&…...

算法刷题Day5: BM52 数组中只出现一次的两个数字

描述&#xff1a; 一个整型数组里除了两个数字只出现一次&#xff0c;其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 要求&#xff1a;空间复杂度 O(1)&#xff0c;时间复杂度O(n)。 题目传送门 is here 思路&#xff1a; 方法一&#xff1a;最简单的思路就…...

55 基于单片机的方波频率可调

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 采用STC89C52单片机最小系统&#xff0c;设计DAC0832、放大器、与示波器显示方波&#xff0c;四位数码管显示频率&#xff0c;两个按键可调。 二、硬件资源 基于KEIL5编写C代码&#xff0c;PROT…...

23.useUnload

在 Web 应用开发中,处理页面卸载(unload)事件是一个重要但常常被忽视的方面。无论是提醒用户保存未保存的更改,还是执行一些清理操作,都需要在用户即将离开页面时进行处理。useUnload 钩子提供了一种简洁的方式来在 React 组件中处理 beforeunload 事件,使得在用户试图关…...

linux环境搭建

1、**连接外网** ssh在192.168.4.x上运行sudo ip link set ens160 down ssh切换到192.168.3.x(外网ip)&#xff0c;运行sudo ip route add default via 192.168.2.1 dev ens192 onlink //连接外网 使用完外网后 ssh在192.168.3.x上运行sudo ip link set ens160 up ssh在1…...

《C++与生物医学的智能融合:医疗变革新引擎》

在当今科技飞速发展的时代&#xff0c;人工智能正以前所未有的深度和广度渗透到各个领域&#xff0c;为传统行业带来革新与突破。其中&#xff0c;将 C与生物学、医学等领域知识相结合&#xff0c;开发用于处理生物医学数据、辅助疾病诊断和治疗的人工智能应用&#xff0c;成为…...

Matlab 绘制雷达图像完全案例和官方教程(亲测)

首先上官方教程链接 polarplothttps://ww2.mathworks.cn/help/matlab/ref/polarplot.html 上实例 % 定义角度向量和径向向量 theta linspace(0, 2*pi, 5); r1 [1, 2, 1.5, 2.5, 1]; r2 [2, 1, 2.5, 1.5, 2];% 绘制两个雷达图 polarplot(theta, r1, r-, LineWidth, 2); hold …...

Lua的环境与热更

一、global_State,lua_State与G表 Lua支持多线程环境&#xff0c;使用 lua_State 结构来表示一个独立的 Lua 线程&#xff08;或协程&#xff09;。每个线程都需要一个独立的全局环境。而lua_State 中的l_G指针&#xff0c;指向一个global_State结构&#xff0c;这个就是我们常…...

HTML CSS JS基础考试题与答案

一、选择题&#xff08;2分/题&#xff09; 1&#xff0e;下面标签中&#xff0c;用来显示段落的标签是&#xff08; d &#xff09;。 A、<h1> B、<br /> C、<img /> D、<p> 2. 网页中的图片文件位于html文件的下一级文件夹img中&#xff0c;…...

若依解析(一)登录认证流程

JWTSpringSecurity 6.X 实现登录 JWT token只包含uuid ,token 解析uuid&#xff0c;然后某个常量加UUID 从Redis缓存查询用户信息 流程图如下 感谢若依&#xff0c;感谢开源&#xff0c;能有这么好系统供我学习。 设计数据库&#xff0c;部门表&#xff0c;用户表&#xff0c…...

Redis设计与实现第17章 -- 集群 总结1(节点 槽指派)

集群通过分片sharding来进行数据共享&#xff0c;并提供复制和故障转移功能。 17.1 节点 一个Redis集群通常由多个节点node组成&#xff0c;刚开始每个节点都是相互独立的&#xff0c;必须将各个独立的节点连接起来&#xff0c;才能构成一个包含多个节点的集群。通过CLUSTER …...

汽车控制软件下载移动管家手机控车一键启动app

移动管家手机控制汽车系统是一款实现车辆远程智能控制的应用程序‌。通过下载并安装特定的APP&#xff0c;用户可以轻松实现以下功能&#xff1a;‌远程启动与熄火‌&#xff1a;无论身处何地&#xff0c;只要有网络&#xff0c;即可远程启动或熄火车辆&#xff0c;提前预冷或预…...

推荐几个可以免费下载网站模板的资源站

推荐几个可以免费下载网站模板的资源站&#xff0c;上面有免费的wordpress模板和帝国CMS模板可以下载。 模板帝 Mobandi.com 模板帝是一个提供丰富网站模板资源的平台&#xff0c;旨在帮助用户快速构建和美化自己的网站。无论是个人博客、企业官网还是电子商务平台&#xff…...

H3C OSPF实验

实验拓扑 实验需求 按照图示配置 IP 地址按照图示分区域配置 OSPF &#xff0c;实现全网互通为了路由结构稳定&#xff0c;要求路由器使用环回口作为 Router-id&#xff0c;ABR 的环回口宣告进骨干区域 实验解法 一、配置IP地址 [R1]int l0 [R1-LoopBack0]ip add 1.1.1.1 32 […...

Vue框架开发一个简单的购物车(Vue.js)

让我们利用所学知识来开发一个简单的购物车 &#xff08;记得暴露属性和方法&#xff01;&#xff01;&#xff01;&#xff09; 首先来看一下最基本的一个html框架 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…...

Windows Terminal Solarized Dark 配色方案调整

起因 Widnows 10/11 下面自带的 Terminal 还是比较方便的&#xff0c;因为不需要安装额外的 Terminal 软件。 我喜欢 Solarized Dark 配色方案&#xff0c;虽然有人批评这个配色方案比较老&#xff0c;但我觉得它比较优雅&#xff0c;尤其对外这种眼神比较差的人&#xff0c;比…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...