我用纯js创建了一个放大镜。我发现需要将div的鼠标位置相对于其父项进行转换时,在计算叠加放大器div的顶部时,offsetTop的工作方式与offsetLeft不同。调整 应 顶部后,我需要减去整个容器div的offsetHeight。
相关代码中的行是:
magnifier.style.top = yPosition - container.offsetHeight + "px";
为什么我需要减去container.offsetHeight
?
我知道我已经阅读过有关此事的内容,但无法找到。
免责声明此代码正常运行。我问,所以我(及其后续人员)可以理解盒子模型是如何工作的。
我知道有更多跨浏览器可靠的jQuery替代品。我喜欢自己编写代码,以便我可以了解它是如何工作的。如果您看到与现代浏览器不兼容的内容,请随时发表评论。
最后,对于使用此功能的任何人,我从此示例中删除了代码以调整转换。例如,如果包装器具有transform: translate(-50%, 0);
以使包装器水平居中,则需要将结果的转换量(转换为包装器的左侧位置)添加回计算中。
我创建了一个jsfiddle here。如果有人感兴趣的话,我在方法中留下了更多关于方法论的评论。
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="../css/ms.js"></script>
<style type="text/css">
/********************/
body {
background-color: #FFF;
margin-left: 30px;
margin-top: 10px;
}
.wrapper {
position: absolute;
left: 100px;
}
#container {
width: 527px;
height: 450px;
border: 5px black solid;
overflow: hidden;
background-color: #F2F2F2;
cursor: pointer;
}
#image {
width: 527px;
height: 450px;
}
#magnifier {
width: 250px;
height: 250px;
overflow:hidden;
position:relative;
z-index: 1000;
border: solid 1px;
}
#magnifier img {
position: absolute;
}
</style>
</head>
<body>
<div class="wrapper" id="wrapper">
<div id="container">
<img id="image" src="../docs/grade-2/jpg/g2-bb-saints-francis.jpg">
<div id="magnifier" class="magnifier">
<img id="imagecopy">
</div>
<br>
</div>
<input type="button" value="Zoom" onClick="initmagnifier('magnifier', 'image', 'imagecopy');"><br>
</div>
<script>
function initmagnifier(magnifier, image, imagecopy){
var magnifier = document.getElementById("magnifier");
var container = document.getElementById("container");
var wrapper = document.getElementById("wrapper");
var img = document.getElementById(image);
var imgcopy = document.getElementById(imagecopy);
var zoom = 2;
container.addEventListener("mousemove",
function(e){
movemagnifier(e, img, imgcopy, magnifier, container, wrapper, zoom)
}, false);
var src = img.src;
imgcopy.src = src;
var src2 = imgcopy.src;
imgcopy.height = img.height * zoom;
imgcopy.width = img.width * zoom ;
}
function movemagnifier(e, img, imgcopy, magnifier, container, wrapper, zoom) {
// to get the left & top of the magnifier
// position needs to be adjusted for WRAPPER & CONTAINER top and left
// gets the top and left of the container
var containerPosition = getPosition(e.currentTarget);
// adjust out the CONTAINER's top / left
// Then takes 1/2 the hight of the MAGNIFIER and subtracts it from the MOUSE position to center MAGNIFIER around the MOUSE cursor
var xPosition = e.clientX - containerPosition.x - (magnifier.clientWidth / 2);
var yPosition = e.clientY - containerPosition.y - (magnifier.clientHeight / 2);
magnifier.style.left = xPosition + "px";
magnifier.style.top = yPosition - container.offsetHeight + "px";
// Adjust for zoom
// adjust the MAGNIFIER's top/left at an equal pace to the zoom amount
var yTravel = (e.clientY - containerPosition.y ) * (zoom - 1);
var yimgPosition = -(yPosition - container.clientTop + yTravel);
imgcopy.style.top = yimgPosition + "px";
var xTravel = (e.clientX - containerPosition.x) * (zoom - 1); // * 1.5
var ximgPosition = -(xPosition + xTravel);
imgcopy.style.left = ximgPosition + "px";
console.log('****');
console.log(e.clientY); // MOUSE POSTION
console.log(containerPosition.y);
console.log(wrapper.offsetTop);
console.log(wrapper.clientHeight);
console.log(container.offsetTop);
console.log(container.clientHeight);
console.log(yPosition);
console.log(container.offsetHeight);
console.log(magnifier.style.top);
}
function getPosition(element) {
var xPosition = 0;
var yPosition = 0;
// element is the CONTAINER
// This calculates the postion of the element (CONTAINER) TOP & LEFT relative to ALL parents
while (element) {
// if transform: translate in place for x and y,
// add it back as it skews the offsetLeft offsetTop values by the translate amount
xPosition += ((element.offsetLeft) - element.scrollLeft);
yPosition += ((element.offsetTop) - element.scrollTop);
element = element.offsetParent;
}
return { x: xPosition, y: yPosition };
}
</script>
</body>
</html>
答案 0 :(得分:1)
我花了很长时间才承认,但我找到了原因。在您的小提琴中,您将#magnifier
- 元素置于相对位置,这意味着您必须将其从“自然”位置移动,该位置位于容器内的图像下方。
因此,每次移动都需要对此进行补偿,将#magnifier
拉到容器的顶部/左侧位置,左侧位置已匹配,但{{1}的“自然”顶部位置}}是容器的完整高度,当您从#magnifier
的顶部/左侧位置计算时,需要减去#container
高度。
一个简单的解决方法是将#container
添加到position: relative
并将#container
更改为position: relative
。{/ p>
这将为#magnifier
提供position: absolute
的预期坐标系,因为绝对定位元素是其相对父元素的左上角(第一个定位的父元素,在本例中为{ {1}})。
a working example,无需减去#magnifier
。
虽然我很喜欢,但您可能需要查看Element.getBoundingClientRect
功能,因为您可以获得确定一次通话中所需位置所需的所有信息。