" />

飞道的博客

vue仿京东放大镜加商品缩略图轮播组件

511人阅读  评论(0)

以下是最终的vue版本,光滑流畅,,99%还原京东放大镜甚至更好

1.vue版本


  
  1. <template>
  2. <div id="magnifier">
  3. <div
  4. class= "small-box"
  5. @ mouseover= "smallBoxOver"
  6. @ mousemove= "smallBoxMove($event)"
  7. @ mouseleave= "smallLeave"
  8. >
  9. <img :src="theImg" />
  10. <span class="hover"> </span>
  11. </div>
  12. <div class="thumbnail-box">
  13. <a class="btn btn-prev" @click="prev"> </a>
  14. <a class="btn btn-next" @click="next"> </a>
  15. <div class="list">
  16. <ul class="wrapper">
  17. <li
  18. class= "item"
  19. v-for= "(item, index) in pictureList"
  20. :key= "index"
  21. @ mouseover= "chooseImg(item,index)"
  22. @ mouseleave= "leaveImg(index)"
  23. :class= "activeIndex===index?'item-cur':''"
  24. >
  25. <img :src="item.url" />
  26. </li>
  27. </ul>
  28. </div>
  29. </div>
  30. <div class="big-box">
  31. <img :src="theImg" />
  32. </div>
  33. </div>
  34. </template>
  35. <script>
  36. import $ from 'jquery'
  37. import 'jquery'
  38. export default {
  39. data() {
  40. return {
  41. theImg: '', // 当前选中的图片
  42. activeIndex: 0,
  43. pictureList: [
  44. {
  45. url:
  46. 'http://mp.ofweek.com/Upload/News/Img/member645/201711/17170046839337.jpg'
  47. },
  48. {
  49. url:
  50. 'http://image.buy.ccb.com/merchant/201703/904919627/1522929521661_4.jpg'
  51. },
  52. {
  53. url:
  54. 'http://image5.suning.cn/uimg/b2c/newcatentries/0070130691-000000000826244625_5_800x800.jpg'
  55. },
  56. {
  57. url:
  58. 'http://img12.360buyimg.com/n5/s450x450_jfs/t9952/98/2269407420/279171/6137fe2f/59f28b2bN6959e086.jpg'
  59. },
  60. {
  61. url:
  62. 'http://d.ifengimg.com/w600/p0.ifengimg.com/pmop/2017/1213/A4037864F6728F006B67AAEC51EC8A485F320FD2_size93_w1024_h734.jpeg'
  63. },
  64. {
  65. url:
  66. 'http://d.ifengimg.com/w600/p0.ifengimg.com/pmop/2017/1213/A4037864F6728F006B67AAEC51EC8A485F320FD2_size93_w1024_h734.jpeg'
  67. }
  68. ],
  69. $elem: '',
  70. $smallBox: '',
  71. $smallBox_pic: '',
  72. $smallBox_mask: '',
  73. $thumbnailBox: '',
  74. $thumbnailBox_prev: '',
  75. $thumbnailBox_next: '',
  76. $thumbnailBox_wrapper: '',
  77. $thumbnailBox_item: '',
  78. $thumbnailBox_pic: '',
  79. $bigBox: '',
  80. $bigBox_pic: ''
  81. }
  82. },
  83. created() {
  84. this.theImg = this.pictureList[ 0].url
  85. },
  86. mounted() {
  87. this.initPreview()
  88. },
  89. methods: {
  90. initPreview() {
  91. this.$elem = $( '#magnifier')
  92. this.$smallBox = this.$elem.find( '.small-box')
  93. this.$smallBox_pic = this.$smallBox.find( 'img')
  94. this.$smallBox_mask = this.$smallBox.find( '.hover')
  95. this.$thumbnailBox = this.$elem.find( '.thumbnail-box')
  96. this.$thumbnailBox_prev = this.$thumbnailBox.find( '.btn-prev')
  97. this.$thumbnailBox_next = this.$thumbnailBox.find( '.btn-next')
  98. this.$thumbnailBox_wrapper = this.$thumbnailBox.find( '.wrapper')
  99. this.$thumbnailBox_item = this.$thumbnailBox.find( '.item')
  100. this.$thumbnailBox_pic = this.$thumbnailBox.find( 'img')
  101. this.$bigBox = this.$elem.find( '.big-box')
  102. this.$bigBox_pic = this.$bigBox.find( 'img')
  103. },
  104. moveBigPic() {
  105. // 改变大图
  106. let scaleX =
  107. this.$smallBox_mask.position().left /
  108. ( this.$smallBox.width() - this.$smallBox_mask.width())
  109. let scaleY =
  110. this.$smallBox_mask.position().top /
  111. ( this.$smallBox.height() - this.$smallBox_mask.height())
  112. let scroll_l = scaleX * ( this.$bigBox_pic.width() - this.$bigBox.width())
  113. let scroll_t =
  114. scaleY * ( this.$bigBox_pic.height() - this.$bigBox.height())
  115. this.$bigBox.stop( true)
  116. this.$bigBox.scrollLeft(scroll_l).scrollTop(scroll_t)
  117. },
  118. setMask() {
  119. // 设置 mask 宽高
  120. // let mask_w =
  121. // this.$smallBox.width() /
  122. // (this.$bigBox_pic.width() / this.$bigBox.width()) /
  123. // 2.5
  124. // let mask_h =
  125. // this.$smallBox.height() /
  126. // (this.$bigBox_pic.height() / this.$bigBox.height()) /
  127. // 2.5
  128. // // this.$smallBox_mask.stop(true)
  129. // this.$smallBox_mask.css({ width: mask_w, height: mask_h })
  130. // this.$smallBox_mask.css({ height: '121.5px', width: '121.5px' })
  131. },
  132. smallBoxOver() {
  133. this.$bigBox.show()
  134. this.$smallBox_mask.show()
  135. this.setMask()
  136. this.$smallBox.stop( true)
  137. },
  138. smallBoxMove(ev) {
  139. // console.log('ev.clientX', ev.clientX)
  140. let oEvent = ev || window.event
  141. let offset_pos = {
  142. left:
  143. oEvent.clientX -
  144. this.$smallBox.offset().left -
  145. this.$smallBox_mask.width() / 2,
  146. top:
  147. oEvent.clientY -
  148. this.$smallBox.offset().top -
  149. this.$smallBox_mask.height() / 2 +
  150. $( window).scrollTop()
  151. }
  152. if (offset_pos.left < 0) {
  153. offset_pos.left = 0
  154. } else if (
  155. offset_pos.left >
  156. this.$smallBox.width() - this.$smallBox_mask.width()
  157. ) {
  158. offset_pos.left = this.$smallBox.width() - this.$smallBox_mask.width()
  159. }
  160. if (offset_pos.top < 0) {
  161. offset_pos.top = 0
  162. } else if (
  163. offset_pos.top >
  164. this.$smallBox.height() - this.$smallBox_mask.height()
  165. ) {
  166. offset_pos.top = this.$smallBox.height() - this.$smallBox_mask.height()
  167. }
  168. this.$smallBox_mask.css(offset_pos)
  169. // this.$smallBox_mask.css({ height: '121.5px', width: '121.5px' })
  170. this.moveBigPic()
  171. },
  172. smallLeave() {
  173. this.$smallBox_mask.hide()
  174. this.$bigBox.hide()
  175. },
  176. prev() {
  177. this.$thumbnailBox_wrapper.animate({ marginLeft: 0 })
  178. },
  179. next() {
  180. let ov_pic = this.$thumbnailBox_item.length - 5
  181. let ov_dis = ov_pic * 78
  182. this.$thumbnailBox_wrapper.stop( true)
  183. if (ov_pic > 0) {
  184. this.$thumbnailBox_wrapper.animate({ marginLeft: -ov_dis })
  185. }
  186. },
  187. leaveImg(index) {},
  188. chooseImg(item, index) {
  189. this.theImg = item.url
  190. this.activeIndex = index
  191. }
  192. }
  193. }
  194. </script>
  195. <style lang="less" scoped>
  196. .thumbnail-box .btn-prev {
  197. left: 0;
  198. background: url(../../assets/img/fjd/images/btn_prev.png) no-repeat;
  199. }
  200. .thumbnail-box .btn-next {
  201. right: 0;
  202. background: url(../../assets/img/fjd/images/btn_next.png) no-repeat;
  203. }
  204. ul,
  205. li {
  206. list-style: none;
  207. }
  208. #magnifier {
  209. position: relative;
  210. width: 450px;
  211. }
  212. .small-box {
  213. position: relative;
  214. width: 450px;
  215. height: 450px;
  216. margin-bottom: 20px;
  217. border: 1px solid #eee;
  218. }
  219. .small-box img {
  220. display: block;
  221. object-fit: fill;
  222. width: 100%;
  223. height: 100%;
  224. }
  225. .small-box .hover {
  226. display: none;
  227. position: absolute;
  228. left: 0;
  229. top: 0;
  230. width: 125px;
  231. height: 125px;
  232. border: 1px solid #aaa;
  233. background: #0099ff;
  234. opacity: 0.5;
  235. cursor: move;
  236. }
  237. .thumbnail-box {
  238. position: relative;
  239. width: 100%;
  240. height: 62px;
  241. }
  242. .thumbnail-box .btn {
  243. position: absolute;
  244. top: 50%;
  245. width: 22px;
  246. height: 32px;
  247. margin-top: - 16px;
  248. }
  249. .thumbnail-box .list {
  250. overflow: hidden;
  251. width: 390px;
  252. margin: 0 auto;
  253. height: 58px;
  254. }
  255. .thumbnail-box .wrapper {
  256. width: 100000px;
  257. }
  258. .thumbnail-box .list .item {
  259. float: left;
  260. margin: 0 11.9px;
  261. }
  262. .thumbnail-box .list .item-cur {
  263. }
  264. .thumbnail-box .list .item img {
  265. border: 2px solid #fff;
  266. height: 50px;
  267. width: 50px;
  268. }
  269. .thumbnail-box .list .item-cur img {
  270. border: 2px solid #e53e41;
  271. }
  272. .big-box {
  273. display: none;
  274. overflow: hidden;
  275. position: absolute;
  276. left: 451px;
  277. top: 0;
  278. width: 540px;
  279. height: 540px;
  280. border: 1px solid #e4e4e4;
  281. z-index: 999;
  282. }
  283. .big-box img {
  284. display: block;
  285. }
  286. </style>

2. JQ版本


  
  1. <template>
  2. <div id="magnifier">
  3. <!-- <div class="small-box" @mouseover="smallBoxOver" @mousemove="smallBoxMove"> -->
  4. <div class="small-box">
  5. <img :src="theImg" />
  6. <span class="hover"> </span>
  7. </div>
  8. <div class="thumbnail-box">
  9. <!-- <a href="javascript:;" class="btn btn-prev" @click="prev"></a>
  10. <a href="javascript:;" class="btn btn-next" @click="next"></a>-->
  11. <a href="javascript:;" class="btn btn-prev"> </a>
  12. <a href="javascript:;" class="btn btn-next"> </a>
  13. <div class="list">
  14. <ul class="wrapper">
  15. <!-- <li class="item item-cur" v-for="(item, index) in pictureList" :key="index">
  16. <img :src="item.url" />
  17. </li>-->
  18. <!-- <li
  19. class="item"
  20. v-for="(item, index) in pictureList"
  21. :key="index"
  22. @mouseover="itemMouseOver"
  23. ></li>-->
  24. <li
  25. class= "item"
  26. v-for= "(item, index) in pictureList"
  27. :key= "index"
  28. @ mouseenter= "chooseImg(item)"
  29. >
  30. <img :src="item.url" />
  31. </li>
  32. </ul>
  33. </div>
  34. </div>
  35. <!-- 缩略图容器 -->
  36. <div class="carousel" style="display:none;">
  37. <!-- 左箭头 -->
  38. <div class="left_arrow arrow" @click="leftArrowClick"> </div>
  39. <!-- 缩略图展示盒子 -->
  40. <div class="show_box">
  41. <ul class="picture_container" ref="middlePicture">
  42. <li
  43. class= "picture_item"
  44. @ mouseover= "tabPicture(item)"
  45. v-for= "(item, index) in pictureList"
  46. :key= "index"
  47. >
  48. <img :src="item.url" class="small_img" alt />
  49. </li>
  50. </ul>
  51. </div>
  52. <!-- 向右箭头 -->
  53. <div class="right_arrow arrow" @click="rightArrowClick"> </div>
  54. </div>
  55. <div class="big-box">
  56. <img :src="theImg" />
  57. </div>
  58. </div>
  59. </template>
  60. <script>
  61. import $ from 'jquery'
  62. import jQuery from 'jquery'
  63. import 'jquery'
  64. import '../ProductPreview/fjd/magnifier'
  65. export default {
  66. data() {
  67. return {
  68. theImg: '', // 当前选中的图片
  69. pictureList: [
  70. {
  71. url:
  72. 'http://mp.ofweek.com/Upload/News/Img/member645/201711/17170046839337.jpg'
  73. },
  74. {
  75. url:
  76. 'http://image.buy.ccb.com/merchant/201703/904919627/1522929521661_4.jpg'
  77. },
  78. {
  79. url:
  80. 'http://image5.suning.cn/uimg/b2c/newcatentries/0070130691-000000000826244625_5_800x800.jpg'
  81. },
  82. {
  83. url:
  84. 'http://img12.360buyimg.com/n5/s450x450_jfs/t9952/98/2269407420/279171/6137fe2f/59f28b2bN6959e086.jpg'
  85. },
  86. {
  87. url:
  88. 'http://d.ifengimg.com/w600/p0.ifengimg.com/pmop/2017/1213/A4037864F6728F006B67AAEC51EC8A485F320FD2_size93_w1024_h734.jpeg'
  89. },
  90. {
  91. url:
  92. 'http://d.ifengimg.com/w600/p0.ifengimg.com/pmop/2017/1213/A4037864F6728F006B67AAEC51EC8A485F320FD2_size93_w1024_h734.jpeg'
  93. }
  94. ]
  95. // $elem: '',
  96. // $smallBox: '',
  97. // $smallBox_pic: '',
  98. // $smallBox_mask: '',
  99. // $thumbnailBox: '',
  100. // $thumbnailBox_prev: '',
  101. // $thumbnailBox_next: '',
  102. // $thumbnailBox_wrapper: '',
  103. // $thumbnailBox_item: '',
  104. // $thumbnailBox_pic: '',
  105. // $bigBox: '',
  106. // $bigBox_pic: ''
  107. }
  108. },
  109. created() {
  110. this.theImg = this.pictureList[ 0].url
  111. },
  112. mounted() {},
  113. methods: {
  114. chooseImg(item) {
  115. this.theImg = item.url
  116. },
  117. // 切换图片
  118. tabPicture(item) {
  119. this.middleImg = item.url
  120. },
  121. // 点击左边箭头
  122. leftArrowClick() {
  123. if ( this.middleLeft < 0) {
  124. // 每次向右平移一个图片盒子的宽度
  125. this.middleLeft += this.itemWidth
  126. $( '.picture_container').animate(
  127. {
  128. left: this.middleLeft
  129. },
  130. 500
  131. )
  132. }
  133. },
  134. // 点击右边箭头
  135. rightArrowClick() {
  136. // 每次向左平移一个盒子的宽度,最多移动的宽度为(图片数组长度-4)*每张缩略图的宽度
  137. if ( this.middleLeft > - this.itemWidth * ( this.pictureList.length - 4)) {
  138. this.middleLeft -= this.itemWidth
  139. $( '.picture_container').animate(
  140. {
  141. left: this.middleLeft
  142. },
  143. 500
  144. )
  145. }
  146. console.log( this.middleLeft)
  147. }
  148. }
  149. }
  150. </script>
  151. <style lang="less" scoped>
  152. .thumbnail-box .btn-prev {
  153. left: 0;
  154. background: url(../../assets/img/fjd/images/btn_prev.png) no-repeat;
  155. }
  156. .thumbnail-box .btn-next {
  157. right: 0;
  158. background: url(../../assets/img/fjd/images/btn_next.png) no-repeat;
  159. }
  160. ul,
  161. li {
  162. list-style: none;
  163. }
  164. #magnifier {
  165. position: relative;
  166. width: 450px;
  167. }
  168. .small-box {
  169. position: relative;
  170. width: 450px;
  171. height: 450px;
  172. margin-bottom: 20px;
  173. border: 1px solid #eee;
  174. }
  175. .small-box img {
  176. display: block;
  177. object-fit: fill;
  178. width: 100%;
  179. height: 100%;
  180. }
  181. .small-box .hover {
  182. display: none;
  183. position: absolute;
  184. left: 0;
  185. top: 0;
  186. width: 200px;
  187. height: 200px;
  188. border: 1px solid #aaa;
  189. background: #0099ff;
  190. opacity: 0.5;
  191. cursor: move;
  192. }
  193. .thumbnail-box {
  194. position: relative;
  195. width: 100%;
  196. height: 62px;
  197. }
  198. .thumbnail-box .btn {
  199. position: absolute;
  200. top: 50%;
  201. width: 22px;
  202. height: 32px;
  203. margin-top: - 16px;
  204. }
  205. .thumbnail-box .list {
  206. overflow: hidden;
  207. width: 390px;
  208. margin: 0 auto;
  209. height: 58px;
  210. }
  211. .thumbnail-box .wrapper {
  212. width: 100000px;
  213. }
  214. .thumbnail-box .list .item {
  215. float: left;
  216. margin: 0 11.9px;
  217. }
  218. .thumbnail-box .list .item-cur {
  219. }
  220. .thumbnail-box .list .item img {
  221. border: 2px solid #fff;
  222. height: 50px;
  223. width: 50px;
  224. }
  225. .thumbnail-box .list .item-cur img {
  226. border: 2px solid #e53e41;
  227. }
  228. .big-box {
  229. display: none;
  230. overflow: hidden;
  231. position: absolute;
  232. left: 451px;
  233. top: 0;
  234. width: 540px;
  235. height: 540px;
  236. border: 1px solid #e4e4e4;
  237. z-index: 999;
  238. }
  239. .big-box img {
  240. display: block;
  241. }
  242. </style>

magnifier.js 


  
  1. import jQuery from 'jquery'
  2. import $ from 'jquery'
  3. $( function() {
  4. $( '#magnifier').magnifier()
  5. })
  6. ;( function($, window, document, undefined) {
  7. let Magnifier = function(elem) {
  8. const self = this
  9. this.$elem = elem
  10. this.$smallBox = this.$elem.find( '.small-box')
  11. this.$smallBox_pic = this.$smallBox.find( 'img')
  12. this.$smallBox_mask = this.$smallBox.find( '.hover')
  13. this.$thumbnailBox = this.$elem.find( '.thumbnail-box')
  14. this.$thumbnailBox_prev = this.$thumbnailBox.find( '.btn-prev')
  15. this.$thumbnailBox_next = this.$thumbnailBox.find( '.btn-next')
  16. this.$thumbnailBox_wrapper = this.$thumbnailBox.find( '.wrapper')
  17. this.$thumbnailBox_item = this.$thumbnailBox.find( '.item')
  18. this.$thumbnailBox_pic = this.$thumbnailBox.find( 'img')
  19. this.$bigBox = this.$elem.find( '.big-box')
  20. this.$bigBox_pic = this.$bigBox.find( 'img')
  21. }
  22. Magnifier.prototype = {
  23. moveBigPic: function() {
  24. // 改变大图
  25. let scaleX =
  26. this.$smallBox_mask.position().left /
  27. ( this.$smallBox.width() - this.$smallBox_mask.width())
  28. let scaleY =
  29. this.$smallBox_mask.position().top /
  30. ( this.$smallBox.height() - this.$smallBox_mask.height())
  31. let scroll_l = scaleX * ( this.$bigBox_pic.width() - this.$bigBox.width())
  32. let scroll_t =
  33. scaleY * ( this.$bigBox_pic.height() - this.$bigBox.height())
  34. this.$bigBox.stop( true)
  35. this.$bigBox.scrollLeft(scroll_l).scrollTop(scroll_t)
  36. },
  37. // changeSrouce: function(index, cur_src) {
  38. // // 改变大小图地址
  39. // this.$smallBox_pic.attr('src', cur_src)
  40. // this.$bigBox_pic.attr('src', 'images/big_' + (index + 1) + '.jpg')
  41. // },
  42. changeSrouce: function(index, cur_src) {
  43. // 改变大小图地址
  44. // this.$smallBox_pic.attr('src', cur_src)
  45. // this.$bigBox_pic.attr('src', cur_src)
  46. },
  47. setMask: function() {
  48. // 设置 mask 宽高
  49. let mask_w =
  50. this.$smallBox.width() /
  51. ( this.$bigBox_pic.width() / this.$bigBox.width()) /
  52. 2.5
  53. let mask_h =
  54. this.$smallBox.height() /
  55. ( this.$bigBox_pic.height() / this.$bigBox.height()) /
  56. 2.5
  57. this.$smallBox_mask.stop( true)
  58. this.$smallBox_mask.css({ width: mask_w, height: mask_h })
  59. },
  60. inital: function() {
  61. // 初始化
  62. const self = this
  63. this.$thumbnailBox_next.click( function() {
  64. let ov_pic = self.$thumbnailBox_item.length - 5
  65. let ov_dis = ov_pic * 78
  66. self.$thumbnailBox_wrapper.stop( true)
  67. if (ov_pic > 0) {
  68. self.$thumbnailBox_wrapper.animate({ marginLeft: -ov_dis })
  69. }
  70. })
  71. this.$thumbnailBox_prev.click( function() {
  72. // self.$thumbnailBox_wrapper.stop(true)
  73. self.$thumbnailBox_wrapper.animate({ marginLeft: 0 })
  74. })
  75. this.$thumbnailBox_item.mouseover( function() {
  76. let cur_src = $( this).attr( 'data-src')
  77. self.$thumbnailBox_item.removeClass( 'item-cur')
  78. $( this).addClass( 'item-cur')
  79. // self.changeSrouce($(this).index(), cur_src)
  80. })
  81. this.$smallBox.hover(
  82. function() {
  83. self.$bigBox.show()
  84. self.$smallBox_mask.show()
  85. self.setMask()
  86. $( this).stop( true)
  87. $( this).mousemove( function(ev) {
  88. let oEvent = ev || window.event
  89. let offset_pos = {
  90. left:
  91. oEvent.clientX -
  92. $( this).offset().left -
  93. self.$smallBox_mask.width() / 2,
  94. top:
  95. oEvent.clientY -
  96. $( this).offset().top -
  97. self.$smallBox_mask.height() / 2 +
  98. $( window).scrollTop(),
  99. }
  100. if (offset_pos.left < 0) {
  101. offset_pos.left = 0
  102. } else if (
  103. offset_pos.left >
  104. $( this).width() - self.$smallBox_mask.width()
  105. ) {
  106. offset_pos.left = $( this).width() - self.$smallBox_mask.width()
  107. }
  108. if (offset_pos.top < 0) {
  109. offset_pos.top = 0
  110. } else if (
  111. offset_pos.top >
  112. $( this).height() - self.$smallBox_mask.height()
  113. ) {
  114. offset_pos.top = $( this).height() - self.$smallBox_mask.height()
  115. }
  116. self.$smallBox_mask.css(offset_pos)
  117. self.moveBigPic()
  118. })
  119. },
  120. function() {
  121. self.$smallBox_mask.hide()
  122. self.$bigBox.hide()
  123. }
  124. )
  125. },
  126. constructor: Magnifier,
  127. }
  128. $.fn.magnifier = function() {
  129. var magnifier = new Magnifier( this)
  130. return magnifier.inital()
  131. }
  132. })(jQuery, window, document)

原html插件,纯jq,学习用


  
  1. 链接:https: //pan.baidu.com/s/16hEc-VtP--p_nZOdsMwi8w
  2. 提取码:ex37

 


转载:https://blog.csdn.net/qq_37939251/article/details/106845849
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场