经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » XHTML » 查看文章
HTML 拖拉功能的实现代码_HTML/Xhtml
来源:jb51  时间:2021/3/1 8:38:10  对本文有异议

基于 vue

此功能核心思想就是通过 JavaScript 代码控制 node 在页面上的左边距与顶边距,不同的的样式定位方式有不同的解决方案

本方案采用position: absolute定位方式的解决方案

css 样式的核心代码

  1. // 父容器核心样式
  2.  
  3. width: 100%;
  4. height: 100%;
  1. // 子容器核心样式
  2. position: absolute;
  3. top: 50%;
  4. left: 50%;
  5. transform: translate(-50%,-50%);

父容器通过width && height字段占满整个浏览器的可视范围,子容器通过position: absolute属性开启在父容器内的绝对定位,在通过top && left && transform: translate(-50%, -50%)属性控制子容器在父容器内的绝对位置

JavaScript 逻辑控制的核心代码

首先分解下,要实现 node 的移动需要哪些步骤和对应的 event 事件

  • 子容器创建时,在父容器内的绝对位置
  • 鼠标按键按下时,onmousedown 事件
  • 鼠标移动时,onmousemove 事件
  • 鼠标按键弹起时,onmouseup 事件

只要使用 onMousedown、onMousemove和onMouseup 这三个事件,就可以实现最简单的移动

  1. /*
  2. * 在子容器创建的时候获取子容器相对于父容器的 top 和 left 位置
  3. */
  4.  
  5. mounted () {
  6. this.left = this.$refs.fatherBox.offsetLeft
  7. this.top = this.$refs.fatherBox.offsetTop
  8. }
  1. /*
  2. * 鼠标按下时
  3. * 1. 开启允许子容器移动的 flag
  4. * 2. 记录鼠标点击时的位置信息
  5. */
  6.  
  7. mouseDown (e) {
  8. // 设置允许弹窗移动的 flag
  9. this.moveFlag = true
  10. // 保存鼠标开始位置
  11. this.startLeft = e.clientX - this.left
  12. this.startTop = e.clientY - this.top
  13. }
  1. /*
  2. * 鼠标移动时
  3. * 1. 判断 flag 是否允许子容器移动
  4. * 2. 设置弹框左边位置
  5. * 3. 设置弹框右边位置
  6. */
  7.  
  8. move (e) {
  9. // 判断 flag 是否允许移动
  10. if (!this.moveFlag) return
  11.  
  12. // 设置弹框左边位置
  13. this.left = e.clientX - this.startLeft
  14. // 设置弹框右边位置
  15. this.top = e.clientY - this.startTop
  16.  
  17. }
  1. /*
  2. * 鼠标按键弹起时
  3. * 1. 关闭允许子容器移动的 flag
  4. */
  5.  
  6. mouseUp (e) {
  7. this.flag = false
  8. }

通过这几个方法就可以获取鼠标按下移动时,鼠标的top 和 left 的偏移量,通过把这偏移量暴露出去给父组件,父组件实时设置子组件的 top 和 left 值,来使得子容器跟随鼠标的移动

父组件部分代码

父组件通过设置子组件的 ref、zIndex 值,而且父组件的 backValue 方法会从子组件接收 zIndex 值,通过 zIndex 来识别具体的子组件实例

  1. /*
  2. * 父组件代码片段 jsx 版
  3. */
  4.  
  5. export default {
  6. props: {
  7. playList: {
  8. type: Array,
  9. required: true
  10. }
  11. },
  12. render () {
  13. return (
  14. <div style={{width: '100%', height: '100%'}} ref={'father'}>
  15. {
  16. this.playList && this.playList.map((item, index) => {
  17. return (
  18. <ChildComponents
  19. key={index}
  20. ref={index}
  21. zIndex={index}
  22. visible={true}
  23. backValue={this.backValue}
  24. info={item}
  25. width={600}
  26. height={400}
  27. />
  28. )
  29. })
  30. }
  31. </div>
  32. )
  33. },
  34. methods: {
  35. backValue (left, top, zIndex) {
  36. this.$refs[zIndex].$el.style.top = `${top}px`
  37. this.$refs[zIndex].$el.style.left = `${left}px`
  38. }
  39. }
  40. }
  1. <!-- 父组件代码片段 vue 文件版 -->
  2.  
  3. <template>
  4. <div
  5. ref="father"
  6. style"width: 100%, height: 100%"
  7. >
  8. <ChildComponents
  9. v-for="(item, index) in playList"
  10. :key="index"
  11. :ref="index"
  12. :visible="true"
  13. :z-index="index"
  14. :back-value="backValue"
  15. :info="item"
  16. :close="close"
  17. :width="600"
  18. :height="400"
  19. />
  20. </div>
  21. </template>
  22. <script>
  23. export default {
  24. components: {
  25. VideoPlayerModal
  26. },
  27. props: {
  28. playList: {
  29. type: Array,
  30. required: true
  31. }
  32. },
  33. methods: {
  34. backValue (left, top, zIndex) {
  35. this.$refs[zIndex][0].$el.style.top = `${top}px`
  36. this.$refs[zIndex][0].$el.style.left = `${left}px`
  37. }
  38. }
  39. }
  40. </script>

设置子组件的围栏范围

这个功能只需要在 onmousemove 事件中进行判断 子容器的 top 和 left 是否超出浏览器的可视范围

  1. /*
  2. * 1. this.width 数据为父组件传递进来的 width 值,或者子组件本身设置的默认值
  3. * 2. this.height 数据为父组件传递进来的 height 值,或者子组件本身设置的默认值
  4. */
  5.  
  6. move (e) {
  7. // 判断 flag 是否允许移动
  8. if (!this.moveFlag) return
  9.  
  10. // 判断是否超出左边视图
  11. if (this.$refs.fatherBox.offsetLeft < this.width / 2) {
  12. // 禁止弹框移动
  13. this.moveFlag = false
  14. // 设置弹框左边位置
  15. this.left = this.width / 2 + 10
  16. // 调用回调函数把偏移量暴露给父组件
  17. this.backValue(this.left, this.top, this.zIndex)
  18. return
  19. }
  20.  
  21. // 判断是否超出右边视图
  22. if (this.$refs.fatherBox.offsetLeft > document.body.clientWidth - this.width / 2) {
  23. // 禁止弹框移动
  24. this.moveFlag = false
  25. // 设置弹框右边位置
  26. this.left = document.body.clientWidth - this.width / 2 - 10
  27. // 调用回调函数把偏移量暴露给父组件
  28. this.backValue(this.left, this.top, this.zIndex)
  29. return
  30. }
  31.  
  32. // 判断是否超出顶部视图
  33. if (this.$refs.fatherBox.offsetTop < this.height / 2 + 70) {
  34. // 禁止弹框移动
  35. this.moveFlag = false
  36. // 设置弹框顶部位置
  37. this.top = this.height / 2 + 70 + 10
  38. // 调用回调函数把偏移量暴露给父组件
  39. this.backValue(this.left, this.top, this.zIndex)
  40. return
  41. }
  42.  
  43. // 判断是否超出底部视图
  44. if (this.$refs.fatherBox.offsetTop > document.body.clientHeight - this.height / 2 - 50) {
  45. // 禁止弹框移动
  46. this.moveFlag = false
  47. // 设置弹框底部位置
  48. this.top = document.body.clientHeight - this.height / 2 - 50 - 10
  49. // 调用回调函数把偏移量暴露给父组件
  50. this.backValue(this.left, this.top, this.zIndex)
  51. return
  52. }
  53.  
  54. // 设置弹框左边位置
  55. this.left = e.clientX - this.startLeft
  56. // 设置弹框右边位置
  57. this.top = e.clientY - this.startTop
  58.  
  59. // 调用回调函数把偏移量暴露给父组件
  60. this.backValue(this.left, this.top, this.zIndex)
  61. }

子组件还要设置一个当鼠标超出子容器时的 onmouseout 事件,用来防止不可预期的 bug 问题

  1. mouseOut (e) {
  2. this.moveFlag = false
  3. }

到此这篇关于HTML 拖拉功能的文章就介绍到这了,更多相关HTML 拖拉功能内容请搜索w3xue以前的文章或继续浏览下面的相关文章,希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号