gpt4 book ai didi

javascript - 计算子 div 顶部位置 - 为什么需要减去父 offsetHeight?

转载 作者:行者123 更新时间:2023-11-28 16:29:42 25 4
gpt4 key购买 nike

我用纯 js 创建了一个放大镜。我发现需要相对于其父元素转换​​ div 的鼠标位置时,在计算覆盖放大镜 div 的顶部时,offsetTop 的工作方式与 offsetLeft 不同。调整顶部应该后,我需要减去整个容器 div 的 offsetHeight。

相关代码中的行是这样的:

magnifier.style.top = yPosition - container.offsetHeight + "px";

为什么我需要减去 container.offsetHeight

我知道我读过一些关于此的内容,但找不到。

免责声明 此代码有效。我这样问是为了让我(和后面的人)能够理解盒子模型是如何工作的。

我知道有一些跨浏览器更可靠的 jQuery 替代品。我喜欢自己编写代码,这样我就可以了解它是如何工作的。如果您看到与现代浏览器不兼容的内容,请随时发表评论。

最后,对于任何使用它的人,我从该示例中删除了代码以针对转换进行调整。例如,如果包装器有一个 transform: translate(-50%, 0); 来水平居中包装器,您将需要添加翻译的结果量(翻译到包装器的左边position) 回到计算中。

我创建了一个 jsfiddle here .如果有人感兴趣,我会在 Fiddle 中留下更多关于方法论的评论。

<!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>

最佳答案

我花了比我愿意承认的时间更长的时间,但我找到了原因。在你的 fiddle 中,你定位 #magnifier - 相对元素,这意味着您必须将其从容器内图像下方的“自然”位置移开。

因此,您必须通过拉动 #magnifier 来补偿这一点。到容器的顶部/左侧位置,左侧位置已经匹配,但是 #magnifier 的“自然”顶部位置是容器的完整高度,正如您从 #container 的顶部/左侧位置计算的那样, 你需要减去 #container高度。

一个简单的解决方法是添加 position: relative#container并更改 position: relative#magnifier 上至 position: absolute .

这将为您提供 #magnifier 的预期坐标系作为top: 0; left: 0因为绝对定位元素是其相对父元素(第一个定位父元素,在本例中为 #container )的左上角。

a working example无需减去 container.offsetHeight .


当我在做的时候,你可能想看看 Element.getBoundingClientRect 函数,因为您可以在一次调用中获得确定位置所需的所有信息。

关于javascript - 计算子 div 顶部位置 - 为什么需要减去父 offsetHeight?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35514537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com