这是某讯的一道笔试题,是一道挖空填代码的题,其实不难,就是看你对 API 的熟悉程度。哈哈,正好页面移动坐标的哪些 API 我都忘了,给我看老旧都想不出来,害,加油吧。

题目:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Document</title>
  8. <style type="text/css">
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. }
  13. .normal {
  14. width: 300px;
  15. height: 300px;
  16. position: relative;
  17. }
  18. .normal > img {
  19. width: 100%;
  20. height: 100%;
  21. }
  22. .lay {
  23. width: 150px;
  24. height: 150px;
  25. background: orange;
  26. opacity: 0.5;
  27. position: absolute;
  28. left: 0;
  29. top: 0;
  30. cursor: move;
  31. display: none;
  32. }
  33. .big {
  34. width: 300px;
  35. height: 300px;
  36. position: absolute;
  37. left: 350px;
  38. top: 0px;
  39. overflow: hidden;
  40. display: none;
  41. }
  42. .big > img {
  43. width: 600px;
  44. height: 600px;
  45. position: absolute;
  46. display: block;
  47. }
  48. </style>
  49. </head>
  50. <body>
  51. <section id="magnifier"></section>
  52. <script type="text/javascript">
  53. var magnifier = {
  54. init(param) {
  55. const el = param.el
  56. const src = param.src
  57. if (!el || !src) return
  58. this.createElement(el, src)
  59. },
  60. createElement(el, src) {
  61. const _this = this
  62. const normalDiv = document.createElement('div')
  63. normalDiv.className = 'normal'
  64. const normalImg = document.createElement('img')
  65. normalImg.src = src.normal
  66. const normalSpan = document.createElement('span')
  67. normalSpan.className = 'lay'
  68. normalDiv.appendChild(normalImg)
  69. normalDiv.appendChild(normalSpan)
  70. const bigDiv = document.createElement('div')
  71. bigDiv.className = 'big'
  72. const bigImg = document.createElement('img')
  73. bigImg.src = src.big
  74. bigDiv.appendChild(bigImg)
  75. el.appendChild(normalDiv)
  76. el.appendChild(bigDiv)
  77. normalDiv.addEventListener('mouseover', () => {
  78. // TODO: 放大镜、被放大的图片都显示,渲染为块级元素
  79. })
  80. normalDiv.addEventListener('mouseout', () => {
  81. // TODO: 放大镜、被放大的图片都隐藏,不渲染
  82. })
  83. normalDiv.addEventListener('mousemove', _moveHandler)
  84. function _moveHandler(event) {
  85. event = event || window.event
  86. _this.moveHandler(event, normalDiv, normalSpan, bigImg)
  87. }
  88. },
  89. moveHandler(event, normalDiv, normalSpan, bigImg) {
  90. // tip: 该函数处理放大镜、被放大的图片的显示区域,x、y分别为鼠标在该模块中的位置坐标
  91. let x = event.clientX - normalSpan.offsetWidth / 2
  92. let y = event.clientY - normalSpan.offsetHeight / 2
  93. // TODO: 判断临界值,重新设置放大镜、被放大的图片的位置
  94. },
  95. }
  96. magnifier.init({
  97. // TODO: 请获取id=magnifier的节点
  98. el: null,
  99. src: {
  100. normal:
  101. 'https://uploadfiles.nowcoder.com/images/20211201/920662346_1638327818015/FE8B1A979ADF6E3C2C114AF3F9CA693C',
  102. big: 'https://uploadfiles.nowcoder.com/images/20211201/920662346_1638327818015/FE8B1A979ADF6E3C2C114AF3F9CA693C',
  103. },
  104. })
  105. </script>
  106. </body>
  107. </html>

代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Document</title>
  8. <style type="text/css">
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. }
  13. .normal {
  14. width: 300px;
  15. height: 300px;
  16. position: relative;
  17. }
  18. .normal > img {
  19. width: 100%;
  20. height: 100%;
  21. }
  22. .lay {
  23. width: 150px;
  24. height: 150px;
  25. background: orange;
  26. opacity: 0.5;
  27. position: absolute;
  28. left: 0;
  29. top: 0;
  30. cursor: move;
  31. display: none;
  32. }
  33. .big {
  34. width: 300px;
  35. height: 300px;
  36. position: absolute;
  37. left: 350px;
  38. top: 0px;
  39. overflow: hidden;
  40. display: none;
  41. }
  42. .big > img {
  43. width: 600px;
  44. height: 600px;
  45. position: absolute;
  46. display: block;
  47. }
  48. </style>
  49. </head>
  50. <body>
  51. <section id="magnifier"></section>
  52. <script type="text/javascript">
  53. var magnifier = {
  54. init(param) {
  55. const el = param.el
  56. const src = param.src
  57. if (!el || !src) return
  58. this.createElement(el, src)
  59. },
  60. createElement(el, src) {
  61. const _this = this
  62. const normalDiv = document.createElement('div')
  63. normalDiv.className = 'normal'
  64. const normalImg = document.createElement('img')
  65. normalImg.src = src.normal
  66. const normalSpan = document.createElement('span')
  67. normalSpan.className = 'lay'
  68. normalDiv.appendChild(normalImg)
  69. normalDiv.appendChild(normalSpan)
  70. const bigDiv = document.createElement('div')
  71. bigDiv.className = 'big'
  72. const bigImg = document.createElement('img')
  73. bigImg.src = src.big
  74. bigDiv.appendChild(bigImg)
  75. el.appendChild(normalDiv)
  76. el.appendChild(bigDiv)
  77. normalDiv.addEventListener('mouseover', () => {
  78. // TODO: 放大镜、被放大的图片都显示,渲染为块级元素
  79. bigDiv.style.display = 'block'
  80. normalSpan.style.display = 'block'
  81. })
  82. normalDiv.addEventListener('mouseout', () => {
  83. // TODO: 放大镜、被放大的图片都隐藏,不渲染
  84. bigDiv.style.display = 'none'
  85. normalSpan.style.display = 'none'
  86. })
  87. normalDiv.addEventListener('mousemove', _moveHandler)
  88. function _moveHandler(event) {
  89. event = event || window.event
  90. _this.moveHandler(event, normalDiv, normalSpan, bigImg)
  91. }
  92. },
  93. moveHandler(event, normalDiv, normalSpan, bigImg) {
  94. // tip: 该函数处理放大镜、被放大的图片的显示区域,x、y分别为鼠标在该模块中的位置坐标
  95. let x = event.clientX - normalSpan.offsetWidth / 2
  96. let y = event.clientY - normalSpan.offsetHeight / 2
  97. console.log('x:', x, 'y:', y)
  98. // TODO: 判断临界值,重新设置放大镜、被放大的图片的位置
  99. // 判断临界值,让放大镜区域的范围不超过图片范围
  100. if (x < 0) {
  101. x = 0
  102. } else if (x > normalDiv.offsetWidth - normalSpan.offsetWidth) {
  103. x = normalDiv.offsetWidth - normalSpan.offsetWidth
  104. }
  105. if (y < 0) {
  106. y = 0
  107. } else if (y > normalDiv.offsetHeight - normalSpan.offsetHeight) {
  108. y = normalDiv.offsetWidth - normalSpan.offsetWidth
  109. }
  110. // 放大镜的移动
  111. normalSpan.style.left = x + 'px'
  112. normalSpan.style.top = y + 'px'
  113. // 计算右边放大显示的图片的相对移动距离
  114. let bigImgX =
  115. x *
  116. ((bigImg.offsetWidth - normalDiv.offsetWidth) /
  117. (normalDiv.offsetWidth - normalSpan.offsetHeight))
  118. let bigImgY =
  119. y *
  120. ((bigImg.offsetHeight - normalDiv.offsetHeight) /
  121. (normalDiv.offsetHeight - normalSpan.offsetHeight))
  122. // 大图片的移动
  123. bigImg.style.left = -bigImgX + 'px'
  124. bigImg.style.top = -bigImgY + 'px'
  125. },
  126. }
  127. magnifier.init({
  128. // TODO: 请获取id=magnifier的节点
  129. el: document.querySelector('#magnifier'),
  130. src: {
  131. normal:
  132. 'https://uploadfiles.nowcoder.com/images/20211201/920662346_1638327818015/FE8B1A979ADF6E3C2C114AF3F9CA693C',
  133. big: 'https://uploadfiles.nowcoder.com/images/20211201/920662346_1638327818015/FE8B1A979ADF6E3C2C114AF3F9CA693C',
  134. },
  135. })
  136. </script>
  137. </body>
  138. </html>

image.png