设置objectPosition为何导致JavaScript崩溃?
问题:设置objectPosition导致JavaScript崩溃
我看到有示例代码通过document.getElementById("myImg").style.objectPosition = "0 10%";设置objectPosition,但自己尝试时JavaScript直接崩溃。
我在CSS中是这样设置objectPosition的:
#img1 { object-position: 0 0; width: 635px ; height: 580px ; }
在getImg函数末尾附近,调试代码显示该属性值为“0px 0px”,但如果在调试语句前添加imgStyle.objectPosition = "0 0";,后续所有语句都不会执行。以下是注释掉问题语句后的完整代码:
原代码
JavaScript
"use strict"; const numberOfFigures = document.getElementsByTagName('figure').length; const scale = 3; // scaling up factor // 仅用于调试的函数 function insert(figNum) { document.getElementById("para").innerHTML = "OK so far" + figNum; } // 创建所有缩略图和大图 for (let i = 0; i < numberOfFigures; i++) { getImg(i + 1); } function getImg(figNum) { // 创建缩略图和大图 let startPosn = "0px"; // 缩略图object-position的x坐标 var btnDiv = document.createElement('div'); btnDiv.setAttribute("id", "bigImg" + figNum); btnDiv.style.backgroundColor = "white"; // 获取figure的标题 const figcap = document.getElementById("fig" + figNum).firstElementChild; btnDiv.innerHTML = '<button type="button"' + 'class="displayBtn"' + 'onclick="hideBigImg (' + figNum + ')">Hide large image</button>'; const btnPtr = figcap.appendChild(btnDiv); var imgDiv = document.createElement('div'); imgDiv.setAttribute("id", "imgDiv" + figNum); if (figNum === 1) { /* 第一张图需要设置height: 100vh,否则只显示顶部部分;其他图设置这个属性可能会出错 */ imgDiv.innerHTML = '<' + 'img id="img' + figNum + '" ' + 'class = "sprite-img" ' + 'src="bates-sprite.jpeg" ' + 'style="height: 100vh; ' + 'transform-origin: top left; ' + 'transform: scale(' + scale + ');">'; } else { imgDiv.innerHTML = '<' + 'img id="img' + figNum + '" ' + 'class = "sprite-img" ' + 'src="bates-sprite.jpeg" ' + 'style="transform-origin: top left; ' + 'transform: scale(' + scale + ');">'; } const imgPtr = btnPtr.appendChild(imgDiv); /* 让imgDiv足够大以容纳缩放后的图片,同时让配套文本可见 重要:必须在创建并追加图片后执行此操作 */ // 获取图片的宽高 let img = document.getElementById("img" + figNum); const imgStyle = getComputedStyle(img); // 设置imgDiv刚好容纳图片 imgDiv.style.width = parseInt(imgStyle.width) * scale + "px"; imgDiv.style.height = parseInt(imgStyle.height) * scale + "px"; imgDiv.style.overflow = "hidden"; // 裁剪掉精灵图的其余部分 /*********************** 创建缩略图 *************/ let thumbHTML = '<' + 'div id="thumbDiv' + figNum + '" ' + 'onclick = "showBigImg(' + figNum + ')" ' + 'style="float: left; ' + 'height: imgStyle.height; ' + 'width: imgStyle.width; ' + 'margin-right: 1.5em; ' + 'background-color: white; ' + 'border: thick solid black;"> ' + '<' + 'img id="img' + figNum + '" ' + 'class = "sprite-img" ' + 'src="bates-sprite.jpeg" ' + 'style="transform-origin: top left; ' + 'transform: scale(0.5);" ' + 'onclick = "showBigImg(' + figNum + ');">' + '</div>'; figcap.insertAdjacentHTML("afterend", thumbHTML); /* 缩小div以匹配缩略图尺寸,释放完整尺寸图片原本会占据的空白空间(如果没有用transform: scale缩小的话) */ let thumbnail = document.getElementById("thumbDiv" + figNum); thumbnail.style.width = parseInt(imgStyle.width) / 2 + "px"; thumbnail.style.height = parseInt(imgStyle.height) / 2 + "px"; // 设置精灵图中图片的object-position //imgStyle.objectPosition = "0 0"; insert(imgStyle.objectPosition); hideBigImg(figNum); } function showBigImg(figNum) { document.getElementById('bigImg' + figNum).style.display = 'block'; document.getElementById('thumbDiv' + figNum).style.display = 'none'; } function hideBigImg(figNum) { document.getElementById('bigImg' + figNum).style.display = 'none'; document.getElementById('thumbDiv' + figNum).style.display = 'block'; }
CSS
/* 全局常量 */ :root { --shrink: 0.30; /* 尺寸压缩至30% */ } figure { display: block; width: 96%; float: left; border-width: thin; } figcaption { background-color: yellow; } .sprite-img { background-repeat: no-repeat; object-fit: none; } #img1 { object-position: 0 0; width: 635px; height: 580px; }
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="general.css"> </head> <body> <figure id="fig1"> <figcaption>Camberley Mail</figcaption> <p id="para">Text to go with picture.</p> </figure> </body> </html>
问题原因
getComputedStyle(img)返回的是只读的计算样式对象,不能直接修改它的属性。在严格模式下(代码开头使用了"use strict";),尝试给只读属性赋值会抛出错误,导致代码终止执行,这就是后续语句无法运行的核心原因。- 代码中创建缩略图时,给缩略图内的img设置了和大图相同的ID(
id="img' + figNum + '"),违反了HTML中ID必须唯一的规则,可能导致后续选择元素时出现异常。
解决方案
- 修改objectPosition的设置方式:直接操作元素的
style属性,而非计算样式对象:
// 替换原注释掉的行 img.style.objectPosition = "0 0";
- 修复重复ID问题:给缩略图的img设置唯一ID,比如修改缩略图HTML部分的img ID为
"thumbImg' + figNum + '":
let thumbHTML = '<' + 'div id="thumbDiv' + figNum + '" ' + 'onclick = "showBigImg(' + figNum + ')" ' + 'style="float: left; ' + 'height: imgStyle.height; ' + 'width: imgStyle.width; ' + 'margin-right: 1.5em; ' + 'background-color: white; ' + 'border: thick solid black;"> ' + '<' + 'img id="thumbImg' + figNum + '" ' + 'class = "sprite-img" ' + 'src="bates-sprite.jpeg" ' + 'style="transform-origin: top left; ' + 'transform: scale(0.5);" ' + 'onclick = "showBigImg(' + figNum + ');">' + '</div>';
内容的提问来源于stack exchange,提问作者Hobbyist
相关产品推荐
相关产品推荐

