我在純js中創建了一個放大鏡。我發現在需要將div的鼠標位置相對於其父母進行轉換時,我發現在計算疊加放大器div的頂部時,offsetTop的工作方式與offsetLeft不同。在調整了什麼後,我需要減去整個容器div的offsetHeight。計算子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>
我知道你的意思是「長於我關心的承認」。我在這方面花了太多時間...以及我自己的其他答案。感謝您花費的時間 - 非常感謝。我顯然不知道getBoundingClientRect - 它看起來非常有用。祝你有美好的一天! – mseifert
很高興我可以幫忙;-)關於'getBoundingClientRect'的一個注意事項是,它會觸發一個[重繪](http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/),所以你可能想緩存它的輸出和/或將它用在['requestAnimationFrame'](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) –