如何用无jQuery的JavaScript实现植物图谱网站重载时的scale动画?
植物图谱网站重载时transform:scale()动画失效解决方案
问题根源排查
你的代码存在四个核心问题,导致动画完全不执行:
- CSS选择器逻辑错误,无法正确匹配添加了
load类的元素 - JavaScript循环条件写反,循环体根本没执行
- JavaScript变量作用域错误,无法访问目标DOM元素
- 未确保DOM加载完成后再执行动画逻辑
分步修复
1. 修正CSS选择器
原代码中#zdj$ID .load是后代选择器,表示匹配#zdj$ID内部的.load元素,但你实际要给#zdj$ID本身添加load类,所以要改成类与ID的组合选择器:
function backgroundSet($ID){ global $conn; $row = mysqli_fetch_array(mysqli_query($conn, "select image from table where plant_ID='$ID';")); echo "#zdj$ID{ background-image: url('../images/subpages/".$row['image']."'); transform: scale(0.9); transition: transform 1s ease; } #zdj$ID.load { /* 修正此处选择器 */ transform: scale(1); } "; }
注:transition可以只在初始状态声明一次,后续状态无需重复写
2. 修复JavaScript逻辑
原JS代码有三个致命错误:
- 循环条件
i > load.length写反,应该是i < load.length loadZdj是loadVar函数的局部变量,外部无法访问- 直接调用
load()时DOM可能还未完全渲染
修正后的JS代码:
<script type="text/javascript"> // 等待DOM完全加载后执行 document.addEventListener('DOMContentLoaded', function() { const loadElements = document.getElementsByClassName('obrazki'); // 遍历所有目标元素 for(let i = 0; i < loadElements.length; i++){ loadElements[i].classList.add('load'); // 直接添加类,无需toggle(初始无类) } }); </script>
优化点:用add替代toggle,避免重复执行时移除类;使用DOMContentLoaded确保DOM渲染完成
3. 额外优化建议
- 避免重复查询数据库:
backgroundSet和Div函数都执行了相同的SQL查询,可以合并为一次查询,提升性能 - 避免使用全局变量
$conn:可以将数据库连接作为参数传入函数,代码更健壮 - 防止SQL注入:当前代码直接将
$ID拼入SQL,存在注入风险,建议使用预处理语句:
// 示例预处理查询 $stmt = $conn->prepare("select image, plantName, plantName_Latin from table where plant_ID=?"); $stmt->bind_param("i", $ID); $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc();
完整修正后代码示例
PHP与CSS部分
<style> <?php function backgroundSet($row, $ID){ echo "#zdj$ID{ background-image: url('../images/subpages/".$row['image']."'); transform: scale(0.9); transition: transform 1s ease; } #zdj$ID.load { transform: scale(1); } "; } // 合并查询,避免重复查库 foreach($datas as $i){ $ID = $i['plant_id']; $stmt = $conn->prepare("select image, plantName, plantName_Latin from table where plant_ID=?"); $stmt->bind_param("i", $ID); $stmt->execute(); $row = $stmt->get_result()->fetch_assoc(); backgroundSet($row, $ID); // 直接输出Div,无需单独函数 echo "<div id='zdj$ID' class='obrazki'> <span class='Efekt'> <span id='name'>".$row['plantName']."</span> <span id='rest'><br/>Lat.".$row['plantName_Latin']."</span> </span> </div>"; } ?> </style>
JavaScript部分
<script type="text/javascript"> document.addEventListener('DOMContentLoaded', function() { const plantCards = document.querySelectorAll('.obrazki'); plantCards.forEach(card => { card.classList.add('load'); }); }); </script>
内容的提问来源于stack exchange,提问作者spaghettiCoder
相关产品推荐
相关产品推荐

