Web front – end advanced combat: commodity detailed magnifier effect
When we visit shopping websites such as Taobao, Tmall or JD, click on a product and enter the details page, we will see a thumbnail of the product. When the mouse floats over the thumbnail, a large picture will appear on the right and can be moved, as shown in the picture below:
- Thought analysis
- HTML + CSS layout
- First, there’s a little box for the thumbnails
- In the small box there should be a picture (thumbnail) and a translucent mask
- The mask layer is hidden by default and is displayed when you hover over the box
- Next to the small box, there is a large box for storing a large picture of the goods, which is also hidden by default, and the size of the large picture of the goods is larger than the size of the large box
- When the mouse hovers over the small box, the large box is displayed
- JavaScript code
- Get the elements on the page (small box, mask, small image, big box and big image)
- Gets the width, height, left, and top values for each element
- According to the principle that the ratio of the width and height of the mask layer to the width and height of the small box is the same as the ratio of the width and height of the big box to the width and height of the big picture, the width and height of the big picture can be calculated, so that no matter how the width and height of the small box, the mask layer and the big box change, the enlarged part can be guaranteed to be the part covered by the mask layer
- As the mask moves, the large image moves with it but in the opposite direction
- Mask layer and large image movement calculation principle: mask layer horizontal movement distance/small box width = large image horizontal movement distance/large image width (same vertical distance)
- Some of the details
- The mask is bound when moving and cannot be moved out of the box
- When the mouse enters the small box, the mouse pointer automatically stops in the middle of the mask layer
- Because the big picture is bigger than the big box, set the overflow property of the big box so that the excess is hidden
- The source code to show
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Magnifying glass effect</title>
<style>
.container {
width: 100%;
height: 100%;
}
.container .abbr {
position: relative;
box-sizing: border-box;
width: 300px;
height: 200px;
left: 200px;
top: 100px;
}
.abbr img {
width: 100%;
height: 100%;
}
.mark {
display: none;
position: absolute;
box-sizing: border-box;
width: 150px;
height: 100px;
border: 1px solid red;
left: 0px;
top: 0;
background: rgba(255.0.0.3);
cursor: move;
}
.details {
position: relative;
left: 500px;
top: -100px;
width: 700px;
height: 600px;
overflow: hidden;
}
.details img {
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="container">
<div class="abbr">
<img src="small.jpg" />
<div class="mark"></div>
</div>
<div class="details">
<img class="big-img" src="big.jpg" alt="">
</div>
</div>
</body>
</html>
Copy the code
let abbr = document.querySelector('.abbr'),
mark = document.querySelector('.mark'),
details = document.querySelector('.details'),
bigImg = document.querySelector('.big-img');
let abbrInfo = abbr.getBoundingClientRect(),
abbrWidth = abbrInfo.width,
abbrHeight = abbrInfo.height,
abbrLeft = abbrInfo.left,
abbrTop = abbrInfo.top;
let detailsInfo = window.getComputedStyle(details),
dtlWidth = parseInt(detailsInfo.width),
dtlHeight = parseInt(detailsInfo.height),
dtlLeft = parseInt(detailsInfo.left),
dtlTop = parseInt(detailsInfo.top);
let markInfo = window.getComputedStyle(mark),
markWidth = parseInt(markInfo.width),
markHeight = parseInt(markInfo.height),
markLeft = parseInt(markInfo.left),
markTop = parseInt(markInfo.top);
let maxLeft = abbrWidth - markWidth,
maxTop = abbrHeight - markHeight;
bigImg.style.width = dtlWidth / (markWidth / abbrWidth) + "px";
bigImg.style.height = dtlHeight / (markHeight / abbrHeight) + "px";
const mouseenter = function mouseenter(ev) {
mark.style.display = "block";
details.style.display = "block";
mark.addEventListener('mousemove', mousemove);
}
const mouseleave = function mouseleave(ev) {
mark.style.display = "none";
details.style.display = "none";
mark.removeEventListener('mousemove', mousemove);
}
const mousemove = function mousemove(ev) {
let left = (ev.clientX - abbrLeft - markWidth / 2),
top = (ev.clientY - abbrTop - markHeight / 2);
left = left < 0 ? 0 : left > maxLeft ? maxLeft : left;
top = top < 0 ? 0 : top > maxTop ? maxTop : top;
mark.style.left = `${left}px`;
mark.style.top = `${top}px`;
bigImg.style.left = ` -${left/abbrWidth*bigImg.clientWidth}px`;
bigImg.style.top = ` -${top/abbrHeight*bigImg.clientHeight}px`
}
abbr.addEventListener('mouseenter', mouseenter);
abbr.addEventListener('mouseleave', mouseleave);
Copy the code