这是某讯的一道笔试题,是一道挖空填代码的题,其实不难,就是看你对 API 的熟悉程度。哈哈,正好页面移动坐标的哪些 API 我都忘了,给我看老旧都想不出来,害,加油吧。
题目:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.normal {
width: 300px;
height: 300px;
position: relative;
}
.normal > img {
width: 100%;
height: 100%;
}
.lay {
width: 150px;
height: 150px;
background: orange;
opacity: 0.5;
position: absolute;
left: 0;
top: 0;
cursor: move;
display: none;
}
.big {
width: 300px;
height: 300px;
position: absolute;
left: 350px;
top: 0px;
overflow: hidden;
display: none;
}
.big > img {
width: 600px;
height: 600px;
position: absolute;
display: block;
}
</style>
</head>
<body>
<section id="magnifier"></section>
<script type="text/javascript">
var magnifier = {
init(param) {
const el = param.el
const src = param.src
if (!el || !src) return
this.createElement(el, src)
},
createElement(el, src) {
const _this = this
const normalDiv = document.createElement('div')
normalDiv.className = 'normal'
const normalImg = document.createElement('img')
normalImg.src = src.normal
const normalSpan = document.createElement('span')
normalSpan.className = 'lay'
normalDiv.appendChild(normalImg)
normalDiv.appendChild(normalSpan)
const bigDiv = document.createElement('div')
bigDiv.className = 'big'
const bigImg = document.createElement('img')
bigImg.src = src.big
bigDiv.appendChild(bigImg)
el.appendChild(normalDiv)
el.appendChild(bigDiv)
normalDiv.addEventListener('mouseover', () => {
// TODO: 放大镜、被放大的图片都显示,渲染为块级元素
})
normalDiv.addEventListener('mouseout', () => {
// TODO: 放大镜、被放大的图片都隐藏,不渲染
})
normalDiv.addEventListener('mousemove', _moveHandler)
function _moveHandler(event) {
event = event || window.event
_this.moveHandler(event, normalDiv, normalSpan, bigImg)
}
},
moveHandler(event, normalDiv, normalSpan, bigImg) {
// tip: 该函数处理放大镜、被放大的图片的显示区域,x、y分别为鼠标在该模块中的位置坐标
let x = event.clientX - normalSpan.offsetWidth / 2
let y = event.clientY - normalSpan.offsetHeight / 2
// TODO: 判断临界值,重新设置放大镜、被放大的图片的位置
},
}
magnifier.init({
// TODO: 请获取id=magnifier的节点
el: null,
src: {
normal:
'https://uploadfiles.nowcoder.com/images/20211201/920662346_1638327818015/FE8B1A979ADF6E3C2C114AF3F9CA693C',
big: 'https://uploadfiles.nowcoder.com/images/20211201/920662346_1638327818015/FE8B1A979ADF6E3C2C114AF3F9CA693C',
},
})
</script>
</body>
</html>
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.normal {
width: 300px;
height: 300px;
position: relative;
}
.normal > img {
width: 100%;
height: 100%;
}
.lay {
width: 150px;
height: 150px;
background: orange;
opacity: 0.5;
position: absolute;
left: 0;
top: 0;
cursor: move;
display: none;
}
.big {
width: 300px;
height: 300px;
position: absolute;
left: 350px;
top: 0px;
overflow: hidden;
display: none;
}
.big > img {
width: 600px;
height: 600px;
position: absolute;
display: block;
}
</style>
</head>
<body>
<section id="magnifier"></section>
<script type="text/javascript">
var magnifier = {
init(param) {
const el = param.el
const src = param.src
if (!el || !src) return
this.createElement(el, src)
},
createElement(el, src) {
const _this = this
const normalDiv = document.createElement('div')
normalDiv.className = 'normal'
const normalImg = document.createElement('img')
normalImg.src = src.normal
const normalSpan = document.createElement('span')
normalSpan.className = 'lay'
normalDiv.appendChild(normalImg)
normalDiv.appendChild(normalSpan)
const bigDiv = document.createElement('div')
bigDiv.className = 'big'
const bigImg = document.createElement('img')
bigImg.src = src.big
bigDiv.appendChild(bigImg)
el.appendChild(normalDiv)
el.appendChild(bigDiv)
normalDiv.addEventListener('mouseover', () => {
// TODO: 放大镜、被放大的图片都显示,渲染为块级元素
bigDiv.style.display = 'block'
normalSpan.style.display = 'block'
})
normalDiv.addEventListener('mouseout', () => {
// TODO: 放大镜、被放大的图片都隐藏,不渲染
bigDiv.style.display = 'none'
normalSpan.style.display = 'none'
})
normalDiv.addEventListener('mousemove', _moveHandler)
function _moveHandler(event) {
event = event || window.event
_this.moveHandler(event, normalDiv, normalSpan, bigImg)
}
},
moveHandler(event, normalDiv, normalSpan, bigImg) {
// tip: 该函数处理放大镜、被放大的图片的显示区域,x、y分别为鼠标在该模块中的位置坐标
let x = event.clientX - normalSpan.offsetWidth / 2
let y = event.clientY - normalSpan.offsetHeight / 2
console.log('x:', x, 'y:', y)
// TODO: 判断临界值,重新设置放大镜、被放大的图片的位置
// 判断临界值,让放大镜区域的范围不超过图片范围
if (x < 0) {
x = 0
} else if (x > normalDiv.offsetWidth - normalSpan.offsetWidth) {
x = normalDiv.offsetWidth - normalSpan.offsetWidth
}
if (y < 0) {
y = 0
} else if (y > normalDiv.offsetHeight - normalSpan.offsetHeight) {
y = normalDiv.offsetWidth - normalSpan.offsetWidth
}
// 放大镜的移动
normalSpan.style.left = x + 'px'
normalSpan.style.top = y + 'px'
// 计算右边放大显示的图片的相对移动距离
let bigImgX =
x *
((bigImg.offsetWidth - normalDiv.offsetWidth) /
(normalDiv.offsetWidth - normalSpan.offsetHeight))
let bigImgY =
y *
((bigImg.offsetHeight - normalDiv.offsetHeight) /
(normalDiv.offsetHeight - normalSpan.offsetHeight))
// 大图片的移动
bigImg.style.left = -bigImgX + 'px'
bigImg.style.top = -bigImgY + 'px'
},
}
magnifier.init({
// TODO: 请获取id=magnifier的节点
el: document.querySelector('#magnifier'),
src: {
normal:
'https://uploadfiles.nowcoder.com/images/20211201/920662346_1638327818015/FE8B1A979ADF6E3C2C114AF3F9CA693C',
big: 'https://uploadfiles.nowcoder.com/images/20211201/920662346_1638327818015/FE8B1A979ADF6E3C2C114AF3F9CA693C',
},
})
</script>
</body>
</html>