letter-spacing影响文字行数

本文探讨了在不同浏览器(IE8、Firefox 和 Chrome)中同一段文字显示行数不一致的问题,并提供了一种解决方案:通过调整 letter-spacing 属性使文本在各浏览器中的表现统一。

工作中发现,同样一段文字,在IE8,Firefox和Chrome中,行数不同。IE8和Firefox中行数相同,Chrome中行数要多一样。最终的解决方案是使用  letter-spacing: -0.2px; /* for Chrome */ 减小字母的间距,这样文字在3个浏览器中表现的结果就一样了。

<script lang="ts" setup> import { ref, onMounted } from 'vue' import Navigater from '@/components/Navigation/Navigater.vue' import {getTaskDetail} from '@/pages/taskDetail/api/index' import type { UploadFile } from 'element-plus' import { Edit,Delete, Download, Plus, ZoomIn} from '@element-plus/icons-vue' import type { FormInstance, FormRules } from 'element-plus' const route = useRoute() // 正确获取当前 route 实例 const id = ref() const taskDetail = ref()// 任务详情 const partyUserInfo = ref() const checked1 = ref(false) const addTxt1 = ref('') const container = ref(null) let scaleValue = 1 const getData = async (id) => { const res = await getTaskDetail({id:id}) taskDetail.value = res.data partyUserInfo.value = res.data.partyUserInfo console.log(partyUserInfo.value.avatar)//输出结果https://cdn.shenyantuling.com/prod/image/head/shutiao1.png } // 图片上传 const dialogImageUrl = ref('') const dialogVisible = ref(false) const disabled = ref(false) const handleRemove = (file: UploadFile) => { console.log(file) } const handlePictureCardPreview = (file: UploadFile) => { dialogImageUrl.value = file.url! dialogVisible.value = true } const handleDownload = (file: UploadFile) => { console.log(file) } // 表单校验 const ruleFormRef = ref<FormInstance>() const ruleForm = reactive({ // .... }) const handleResize = () => { const containerWidth = container.value.offsetWidth const containerHeight = container.value.offsetHeight const windowWidth = window.innerWidth const windowHeight = window.innerHeight // 计算缩放比例,保持内容完整显示 scaleValue = Math.min( windowWidth / containerWidth, windowHeight / containerHeight ) container.value.style.transform = `scale(${scaleValue})` container.value.style.transformOrigin = 'top left' } onMounted(() => { handleResize() window.addEventListener('resize', handleResize) id.value = route.query.id getData(id.value) }) onBeforeUnmount(() => { window.removeEventListener('resize', handleResize) }) </script> <template> <div class="scale-container" ref="container"> <div class="content"> <!-- 顶部 logo 导航栏 --> <Navigater class="top"></Navigater> <!-- 任务详情 --> <div class="wrap"> <div class="topBack"> <div class="return"> <img src="@/assets/navigater/return.png" alt=""> </div> <div class="title">任务详情</div> </div> <div class="taskBox"> <div class="taskLeft"> <!-- 发布者 --> <div class="publisherBox"> <div class="avatar"> <img :src=partyUserInfo.avatar alt=""> </div> <div class="info"> <div class="infoTop"> <div class="name">avatar</div> <img src="@/assets/navigater/task1.png" alt=""> <img src="@/assets/navigater/task1.png" alt=""> </div> <div class="dic"> The First Onchain Treasury Network for Web 3The First Onchain Treasury Network for Web 3The First Onchain Treasury Network for Web 3 </div> </div> </div> <!-- 任务 --> <div class="taskDic"> <div class="taskImg"> <img src="@/assets/navigater/task1.png" alt=""> </div> <div class="taskText"> <div class="taskTitle">任务标题:关注微博账号赠送3000积分积分赠送</div> <div class="botBox"> <div class="type">任务类型</div> <div class="copy"> <img src="@/assets/navigater/task2.png" alt=""> </div> </div> </div> </div> <div class="tip"> <img src="@/assets/navigater/task1.png" alt=""> <div class="tipTxt">Joinly 将在发放奖励前仔细检查,已提交的任务</div> </div> <div class="taskMain"> <div class="mainTop"> <img src="@/assets/navigater/task2.png" alt=""> <div class="mainTxt">关注 crazy crap在微博的账号,账号名称crazy crap</div> </div> <div class="main"> <el-form ref="ruleFormRef" style="max-width: 600px" :model="ruleForm" status-icon label-width="auto" class="demo-ruleForm" > <!-- :rules="rules" --> <el-card class="step"> <div class="stepTop"> <div class="stepTit"> <el-checkbox v-model="checked1" size="large" /> <div class="stepTxt">关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博</div> </div> <el-button class="stepBtn" color="#715EFF" type="primary" :icon="Edit" disabled>保存修改</el-button> </div> <div class="stepMain"> <div class="title">添加图片</div> <el-upload action="#" list-type="picture-card" :auto-upload="false" :limit=3> <el-icon><Plus /></el-icon> <template #file="{ file }"> <div> <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" /> <span class="el-upload-list__item-actions"> <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)" > <el-icon><zoom-in /></el-icon> </span> <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)" > <el-icon><Delete /></el-icon> </span> </span> </div> </template> </el-upload> <el-dialog v-model="dialogVisible"> <img w-full :src="dialogImageUrl" alt="Preview Image" /> </el-dialog> <div class="title">添加文字</div> <el-input class="addTxt" type="textarea" v-model="addTxt1" placeholder="请输入文字" /> </div> </el-card> <el-card class="step"> <div class="stepTop"> <div class="stepTit"> <el-checkbox v-model="checked1" size="large" /> <div class="stepTxt">关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博</div> </div> <el-button class="stepBtn" color="#715EFF" type="primary" :icon="Edit" disabled>保存修改</el-button> </div> <div class="stepMain"> <div class="title">添加图片</div> <el-upload action="#" list-type="picture-card" :auto-upload="false" :limit=3> <el-icon><Plus /></el-icon> <template #file="{ file }"> <div> <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" /> <span class="el-upload-list__item-actions"> <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)" > <el-icon><zoom-in /></el-icon> </span> <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)" > <el-icon><Delete /></el-icon> </span> </span> </div> </template> </el-upload> <el-dialog v-model="dialogVisible"> <img w-full :src="dialogImageUrl" alt="Preview Image" /> </el-dialog> <div class="title">添加文字</div> <el-input class="addTxt" type="textarea" v-model="addTxt1" placeholder="请输入文字" /> </div> </el-card> <el-card class="step"> <div class="stepTop"> <div class="stepTit"> <el-checkbox v-model="checked1" size="large" /> <div class="stepTxt">关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博关闭微博</div> </div> <el-button class="stepBtn" color="#715EFF" type="primary" :icon="Edit" disabled>保存修改</el-button> </div> <div class="stepMain"> <div class="title">添加图片</div> <el-upload action="#" list-type="picture-card" :auto-upload="false" :limit=3> <el-icon><Plus /></el-icon> <template #file="{ file }"> <div> <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" /> <span class="el-upload-list__item-actions"> <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)" > <el-icon><zoom-in /></el-icon> </span> <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)" > <el-icon><Delete /></el-icon> </span> </span> </div> </template> </el-upload> <el-dialog v-model="dialogVisible"> <img w-full :src="dialogImageUrl" alt="Preview Image" /> </el-dialog> <div class="title">添加文字</div> <el-input class="addTxt" type="textarea" v-model="addTxt1" placeholder="请输入文字" /> </div> </el-card> </el-form> </div> </div> </div> <div class="taskRight"> </div> </div> </div> </div> </div> </template> <style scoped lang="scss"> .scale-container { width: 1920px; /* 设计稿宽度 */ position: absolute; display: block; top: 0; left: 0; .content { width: 100%; height: 100%; background-color: #000; display: block; .wrap{ width: 1552px; margin: 0 auto; .topBack{ display: flex; width: 1552px; height: 74px; justify-content: left; align-items: center; border-bottom: 1px solid #444; margin-bottom: 31px; .return{ width: 24px; height: 24px; margin-right: 10px; img{ width: 100%; height: 100%; } } .title{ font-family: PingFang SC; font-weight: 600; font-style: Semibold; font-size: 20px; color:#fff; line-height: 100%; letter-spacing: -0.3px; } } .taskBox{ display: flex; width: 1174px; margin: 0 auto; .taskLeft{ width: 787px; .publisherBox{ width: 787px; height:100px; display: flex; background-color: #232323; border-radius: 12px; padding: 16px; margin-bottom: 30px; .avatar{ width: 48px; height: 48px; margin-right: 16px; img{ width: 100%; height: 100%; border-radius: 50%; } } .info{ .infoTop{ display: flex; justify-content: left; align-items: center; .name{ font-family: PingFang SC; font-weight: 600; font-style: Semibold; font-size: 20px; color:#fff; line-height: 100%; letter-spacing: -0.3px; } img{ width: 16px; height: 16px; border-radius: 50%; margin-left: 8px; } } .dic{ width: 536px; margin-top: 14px; font-family: PingFang SC; font-weight: 400; font-style: Regular; font-size: 14px; line-height: 21px; letter-spacing: -0.3px; color:#A6A6A6; display: -webkit-box; /* 关键属性:弹性伸缩盒子 */ -webkit-box-orient: vertical; /* 排列方向:垂直 */ -webkit-line-clamp: 2; /* 限制行数2行 */ overflow: hidden; /* 溢出隐藏 */ text-overflow: ellipsis; /* 溢出显示省略号 */ word-break: break-word; /* 长单词换行处理 */ } } } .taskDic{ width: 786px; height: 150px; top: 346px; left: 373px; display: flex; padding-top: 32px; border-top: 1px solid #444; .taskImg{ img{ width: 160px; height: 120PX; border-radius: 12px; } } .taskText{ color: #fff; margin-left: 23px; .taskTitle{ width: 546px; height: 80px; font-family: PingFang SC; font-weight: 600; font-style: Semibold; font-size: 26px; letter-spacing: -0.3px; // display: -webkit-box; /* 关键属性:弹性伸缩盒子 */ // -webkit-box-orient: vertical; /* 排列方向:垂直 */ // -webkit-line-clamp: 2; /* 限制行数2行 */ // overflow: hidden; /* 溢出隐藏 */ // text-overflow: ellipsis; /* 溢出显示省略号 */ // word-break: break-word; /* 长单词换行处理 */ } .botBox{ display: flex; justify-content: space-between; align-items: center; width: 603px; .type{ width: 64px; height: 30px; text-align: center; font-family: PingFang SC; font-weight: 600; font-style: Semibold; font-size: 12px; line-height: 30px; letter-spacing: -0.3px; border-radius: 4px; background-color: #232323; } .copy{ width: 30px; height: 30px; img{ width: 100%; height: 100%; } } } } } .tip{ display: flex; justify-content: left; align-items: center; margin: 32px auto; img{ width: 16px; height: 16px; border-radius: 50%; margin-right: 10px; } .tipTxt{ color:#fff;font-family: PingFang SC; font-weight: 400; font-style: Regular; font-size: 14px; line-height: 100%; letter-spacing: -0.3px; } } .taskMain{ width: 787px; padding: 24px; border-radius: 12px; background-color: #232323; .mainTop{ display: flex; justify-content: left; align-items: center; margin-bottom: 23px; img{ width: 24px; height: 24px; border-radius: 4px; margin-right: 10px; } .mainTxt{ font-family: PingFang SC; font-weight: 600; font-style: Semibold; font-size: 18px; color:#fff; line-height: 100%; letter-spacing: -0.3px; } } .main{ .step{ width: 739px; background-color: #121212; border: 1px solid #121212; .stepTop{ width: 715px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #444; .stepTit{ display: flex; justify-content: space-between; align-items: center; .stepTxt{ font-family: PingFang SC; font-weight: 400; font-style: Regular; font-size: 14px; color:#A6A6A6; line-height: 100%; letter-spacing: -0.3px; margin-left: 10px; } } .stepBtn{ margin-right: 10px; margin-bottom: 3px; } } .stepMain{ width: 667px; margin: 0 auto; .title{ font-family: PingFang SC; font-weight: 400; font-style: Regular; font-size: 12px; color:#fff; letter-spacing: -0.3px; margin: 10px 0; } .addTxt{ &:deep(.el-input){ display: block; width: 667px; height: 80px !important; background-color: #363636 !important; border: none; border-radius: 8px; } } } } } } } .taskRight{ width: 339px; margin-left: 48px; } } } } } </style> 中console.log(partyUserInfo.value.avatar)的输出结果为https://cdn.shenyantuling.com/prod/image/head/shutiao1.png。 但是 报错显示:taskDetail.vue:98 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'avatar') at Proxy._sfc_render (taskDetail.vue:98:53) 即<img :src=partyUserInfo.avatar alt="">中找不到avatar
最新发布
07-29
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Premium Materials Gallery</title> <style> /* 容器样式 */ .luxemg-container { max-width: 80%; margin: 0 auto; padding: 40px 20px; position: relative; } /* 标题区域 */ .luxemg-header { text-align: center; margin-bottom: 50px; padding-bottom: 20px; border-bottom: 1px solid #e0e0e0; } .luxemg-title { font-weight: 300; letter-spacing: 2px; color: #333; margin: 0 0 10px 0; font-size: 28px; } .luxemg-subtitle { color: #7a7a7a; max-width: 600px; margin: 0 auto; line-height: 1.6; } /* 网格布局 */ .luxemg-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px; } /* 卡片样式 */ .luxemg-card { background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.05); transition: transform 0.3s ease, box-shadow 0.3s ease; position: relative; display: flex; flex-direction: column; height: 100%; } .luxemg-card:hover { transform: translateY(-8px); box-shadow: 0 12px 25px rgba(0,0,0,0.08); } .luxemg-card-image { height: 240px; overflow: hidden; background: #f8f8f8; } .luxemg-card-img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .luxemg-card:hover .luxemg-card-img { transform: scale(1.05); } .luxemg-card-content { padding: 25px; flex-grow: 1; display: flex; flex-direction: column; } .luxemg-card-title { font-weight: 400; margin: 0 0 15px 0; font-size: 22px; letter-spacing: 1px; color: #222; } .luxemg-card-desc { color: #666; line-height: 1.7; margin: 0 0 20px 0; font-size: 16px; flex-grow: 1; } /* 详情按钮样式 */ .luxemg-detail-btn { display: inline-block; padding: 10px 20px; background: #000; color: white; border: 2px solid #000; border-radius: 4px; cursor: pointer; font-weight: 500; letter-spacing: 1px; text-transform: uppercase; font-size: 14px; transition: all 0.3s ease; align-self: flex-start; } .luxemg-detail-btn:hover { background: white !important; color: black !important; } /* 模态框样式 */ #luxemg-modal-container { position: fixed; top: 0; left: 10%; width: 100%; height: 100%; background: rgba(0,0,0,0.8); display: none; z-index: 10000; opacity: 0; transition: opacity 0.3s ease; } .luxemg-modal-wrapper { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; padding: 20px; box-sizing: border-box; } .luxemg-modal-content { background: white; width: 100%; max-width: 900px; max-height: 90vh; border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 20px 40px rgba(0,0,0,0.3); transform: scale(0.95); transition: transform 0.4s cubic-bezier(0.18, 0.89, 0.32, 1.28), opacity 0.3s ease; opacity: 0; } .luxemg-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-bottom: 1px solid #eee; } .luxemg-modal-title { margin: 0; font-size: 24px; font-weight: 400; color: #333; } .luxemg-close-btn { background: none; border: none; font-size: 24px; cursor: pointer; color: #888; transition: color 0.3s; } .luxemg-close-btn:hover { color: #333; } .luxemg-modal-body { display: flex; overflow: auto; flex-grow: 1; padding: 0; } .luxemg-modal-image-container { width: 50%; min-width: 300px; background: #f8f8f8; display: flex; align-items: center; justify-content: center; padding: 30px; } .luxemg-modal-img { max-width: 100%; max-height: 400px; object-fit: contain; } .luxemg-modal-description { width: 50%; padding: 30px; overflow-y: auto; } .luxemg-modal-desc { line-height: 1.8; color: #555; } .luxemg-specs-table { width: 100%; border-collapse: collapse; margin-top: 25px; font-size: 15px; } .luxemg-specs-table th { padding: 10px; text-align: left; border-bottom: 1px solid #eee; background: #f5f5f5; } .luxemg-specs-table td { padding: 10px; border-bottom: 1px solid #eee; } /* 响应式设计 */ @media (max-width: 1024px) { .luxemg-grid { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 768px) { .luxemg-container { padding: 30px 15px; } .luxemg-grid { grid-template-columns: 1fr; gap: 25px; } .luxemg-card { max-width: 500px; margin: 0 auto; } .luxemg-modal-body { flex-direction: column; } .luxemg-modal-image-container, .luxemg-modal-description { width: 100% !important; } .luxemg-modal-image-container { height: 300px; min-height: auto; } } @media (max-width: 480px) { .luxemg-title { font-size: 24px; } .luxemg-card-title { font-size: 20px; } .luxemg-card-desc { font-size: 15px; } } @media (max-height: 700px) { .luxemg-modal-content { max-height: 85vh; } } </style> </head> <body> <div class="luxemg-container"> <!-- 材料展示网格 --> <div class="luxemg-grid"> <!-- 材料项 1 --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_45_42_compressed.png" alt="double-sided coated paper" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">double-sided coated paper</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal1">VIEW MORE</button> </div> </div> <!-- 材料项 2 --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/600x400/e8极8e8/999999?text=Oak+Hardwood" alt="Oak Hardwood" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">Oak Hardwood</h3> <p class="luxemg-card-desc">European white oak with natural grain patterns...</p> <button class="luxemg-detail-btn" data-luxemg-modal="modal2">VIEW MORE</button> </div> </div> <!-- 材料项 3 --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/600x400/e8e8e8/999999?text=Brushed+Brass" alt="Brushed Brass" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">Brushed Brass</h3> <p class="luxemg-card-desc">Hand-finished brass with subtle texture...</p> <button class="luxemg-detail-btn" data-luxemg-modal="modal3">VIEW MORE</button> </div> </div> <!-- 材料项 4 --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/600x400/e8e8e8/999999?text=Ceramic+Tiles" alt="Ceramic Tiles" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">Ceramic Tiles</h3> <p class="luxemg-card-desc">High-gloss ceramic tiles with exceptional durability...</p> <button class="luxemg-detail-btn" data-luxemg-modal="modal4">VIEW MORE</button> </div> </div> </div> </div> <!-- 模态框容器 --> <div id="luxemg-modal-container" class="luxemg-modal-container"> <div class="luxemg-modal-wrapper"> <div class="luxemg-modal-content"> <div class="luxemg-modal-header"> <h3 id="luxemg-modal-title" class="luxemg-modal-title">Material Details</h3> <button id="luxemg-close-modal" class="luxemg-close-btn">×</button> </div> <div class="luxemg-modal-body"> <div class="luxemg-modal-image-container"> <img id="luxemg-modal-image" class="luxemg-modal-img" src="" alt="Material"> </div> <div class="luxemg-modal-description"> <div id="luxemg-modal-description" class="luxemg-modal-desc"></div> <table class="luxemg-specs-table"> <thead> <tr> <th>Property</th> <th>Value</th> </tr> </thead> <tbody id="luxemg-modal-specs" class="luxemg-specs-body"></tbody> </table> </div> </div> </div> </div> </div> <script> // 使用IIFE创建私有作用域避免全局污染 (function() { // 材料详情数据 - 使用唯一前缀 const luxemgMaterialDetails = { modal1: { title: "Italian Marble", image: "https://via.placeholder.com/800x600/e8e8e8/999999?text=Italian+Marble+Detail", description: "<p>Premium Carrara marble quarried directly from the Apuan Alps in Tuscany, Italy. This exquisite natural stone features distinctive soft gray veining on a white or blue-gray background, creating timeless elegance.</p><p>Each slab is carefully selected for its unique pattern and quality, ensuring minimal imperfections. Ideal for high-end countertops, flooring, and feature walls. The marble undergoes a specialized polishing process to enhance its natural luster and durability.</p>", specs: [ { property: "Origin", value: "Carrara, Italy" }, { property: "Hardness", value: "3-4 on Mohs scale" }, { property: "Thickness", value: "2cm, 3cm" }, { property: "Finish", value: "Polished, Honed" }, { property: "Maintenance", value: "Sealing recommended" } ] }, modal2: { title: "Oak Hardwood", image: "https://via.placeholder.com/800x600/e8e8e8/999999?text=Oak+Hardwood+Detail", description: "<p>European white oak (Quercus robur) sourced from sustainably managed forests. This premium hardwood features a straight grain with occasional swirls and burls, offering a warm, natural appearance.</p><p>The wood undergoes a meticulous kiln-drying process to achieve optimal moisture content (8-10%), ensuring dimensional stability. Available in various grades from rustic to select, suitable for flooring, furniture, and architectural elements. The natural tannin content provides inherent resistance to insects and decay.</p>", specs: [ { property: "Species", value: "Quercus robur" }, { property: "Janka Hardness", value: "1360 lbf" }, { property: "Density", value: "720 kg/m³" }, { property: "Moisture Content", value: "8-10%" }, { property: "Sustainability", value: "FSC Certified" } ] }, modal3: { title: "Brushed Brass", image: "https://via.placeholder.com/800x600/e8e8e8/999999?text=Brushed+Brass+Detail", description: "<p>Hand-finished brass with a distinctive brushed texture that diffuses light and minimizes fingerprints. This premium alloy contains 85% copper and 15% zinc, offering a warm golden hue that develops a rich patina over time.</p><p>The brushing process creates subtle linear patterns that enhance depth and character. A protective lacquer coating is applied to preserve the finish while allowing for natural aging. Ideal for hardware, fixtures, and decorative accents in both contemporary and traditional settings.</p>", specs: [ { property: "Composition", value: "85% Copper, 15% Zinc" }, { property: "Finish", value: "Satin Brushed" }, { property: "Thickness", value: "1.2mm - 3mm" }, { property: "Protection", value: "Clear Lacquer Coated" }, { property: "Patina Development", value: "Slow, even" } ] }, modal4: { title: "Ceramic Tiles", image: "https://via.placeholder.com/800x600/e8e8e8/999999?text=Ceramic+Tiles+Detail", description: "<p>High-gloss ceramic tiles manufactured using advanced digital printing technology that replicates natural stone with remarkable fidelity. The durable glaze is formulated for exceptional scratch and stain resistance.</p><p>These tiles feature a through-body color composition, meaning any chips or scratches are less noticeable. The rectified edges allow for minimal grout lines (as small as 1.5mm), creating a seamless appearance. Suitable for both walls and floors in high-traffic areas.</p>", specs: [ { property: "Material", value: "Porcelain Ceramic" }, { property: "PEI Rating", value: "IV (Heavy Traffic)" }, { property: "Water Absorption", value: "<0.5%" }, { property: "Slip Resistance", value: "R10 (Dry)" }, { property: "Sizes", value: "60x60cm, 30x60cm" } ] } }; // DOM元素引用 const luxemgModalContainer = document.getElementById('luxemg-modal-container'); const luxemgModalTitle = document.getElementById('luxemg-modal-title'); const luxemgModalImage = document.getElementById('luxemg-modal-image'); const luxemgModalDescription = document.getElementById('luxemg-modal-description'); const luxemgModalSpecs = document.getElementById('luxemg-modal-specs'); const luxemgCloseModal = document.getElementById('luxemg-close-modal'); // 打开模态框函数 function openLuxemgModal(modalId) { const material = luxemgMaterialDetails[modalId]; const modalContent = luxemgModalContainer.querySelector('.luxemg-modal-content'); if (!material) { console.error("Material details not found for:", modalId); return; } // 填充模态框内容 luxemgModalTitle.textContent = material.title; luxemgModalImage.src = material.image; luxemgModalImage.alt = material.title; luxemgModalDescription.innerHTML = material.description; // 填充技术规格 luxemgModalSpecs.innerHTML = ''; material.specs.forEach(spec => { const row = document.createElement('tr'); row.innerHTML = ` <td>${spec.property}</td> <td>${spec.value}</td> `; luxemgModalSpecs.appendChild(row); }); // 显示模态框 luxemgModalContainer.style.display = 'block'; // 强制重绘确保动画执行 void luxemgModalContainer.offsetWidth; // 应用显示动画 setTimeout(() => { luxemgModalContainer.style.opacity = '1'; modalContent.style.transform = 'scale(1)'; modalContent.style.opacity = '1'; }, 10); // 禁止背景滚动 document.body.style.overflow = 'hidden'; } // 关闭模态框函数 function closeLuxemgModal() { const modalContent = luxemgModalContainer.querySelector('.luxemg-modal-content'); luxemgModalContainer.style.opacity = '0'; modalContent.style.transform = 'scale(0.95)'; modalContent.style.opacity = '0'; setTimeout(() => { luxemgModalContainer.style.display = 'none'; document.body.style.overflow = ''; }, 300); } // 事件绑定函数 function initLuxemgGallery() { // 绑定关闭按钮 luxemgCloseModal.addEventListener('click', closeLuxemgModal); // 点击背景关闭 luxemgModalContainer.addEventListener('click', function(e) { if (e.target === this) closeLuxemgModal(); }); // ESC键关闭 document.addEventListener('keydown', function(e) { if (e.key === 'Escape') closeLuxemgModal(); }); // 绑定详情按钮 const detailButtons = document.querySelectorAll('.luxemg-detail-btn'); detailButtons.forEach(button => { button.addEventListener('click', function() { const modalId = this.getAttribute('data-luxemg-modal'); console.log("Opening modal:", modalId); openLuxemgModal(modalId); }); }); console.log("Gallery initialized. Found", detailButtons.length, "detail buttons."); } // DOM加载完成后初始化 document.addEventListener('DOMContentLoaded', initLuxemgGallery); })(); </script> </body> </html> 去掉这段代码中的卡片上的文字描述,保留标题和按钮
06-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值