JavaScript事件处理(三)

上机三 JavaScript事件处理

目的:

  1. 熟练掌握JavaScript事件处理机制
  2. 重点理解面向对象编程思想,并构建程序。

要求:

  1. 定义一个按钮,动态生成DIV,可以生成多个DIV;
  2. 实现DIV的自由拖曳,当和以生成的DIV碰撞时,弹出警告框;
  3. 封装自由拖曳函数,DIV作为参数传入

源代码:



    
    
    
    Third_work







截图:

JavaScript事件处理(三)

总结(遇到问题、解决方式、心得体会):

div的生成和移动相对简单,但在我完成自由拖拽div、开始写判断div碰撞时,我发现了问题。

为了移动div,我将div的position属性都设置成了absolute,但也因此生成的div都聚集在浏览器窗口左上方互相重叠,虽然可以通过拖拽将其移动到其他位置,但如果碰撞功能部分代码完成,点击div开始移动时,就会触发碰撞,弹出警告框从而阻止了div的移动这无疑是个bug。所以若要实现碰撞功能,必须在生成div时就将每个div分隔开。

由于position:absolute绝对位置,通过设置div的外边距,即margin属性,将div分隔的操作失效。我想到可以在生成div时使用静态位置position:static,这样生成的div是会自动排成一竖列,并且可用margin属性。只要在触发拖拽移动时,将position属性修改回绝对位置ele.style.position = “absolute”;这样既实现了生成分隔开的div,又可拖拽移动div!

但是!经过测试,这种通过修改position属性的方法并不可行!在理论上这种方法确实完成了生成分隔开的div和自由拖拽div两种功能。但在实践中,由于受到拖拽的div的position会由静态static转变为绝对absolute,实现了空间自由拖拽移动,但其他div仍然是静态位置position:static,他们会自动排列并置顶。也就是说在拖拽div离开其原本位置时,其他div会自动移动、占据被拖拽的div的位置。在此过程中,div之间的碰撞不可避免,之前分隔div的操作毫无意义,他们依然还是会不受鼠标控制自行发生碰撞。所以不能通过修改绝对位置position:absolute来消除bug。

为了实现拖拽移动div,position:absolute是必须的。在绝对位置下,想要分隔开div就要使用left和top等属性来对div位置进行精准定位,并设置全局变量positionCountX和positionCountY来累计上一个div的位置,和预计生成下一个div的位置。这种靠精准定位div位置生成div的方法成功地解决了自动发生碰撞且强行阻止div移动的bug。

碰撞则是在移动的基础上进行加工,让鼠标事件触发的div与其他div用循环进行两两比较,不碰撞则移动,碰撞则弹出警告框。其中也有需要注意的事项,比如要给弹框上锁(关于上锁详情看代码,解释看实验2总结),避免div重合时不停弹框;还有得在弹出警告框前清除鼠标移动事件,因为alert弹框会发生中断,导致后面的鼠标抬起事件无效,这样div会在鼠标没有按下时也一直跟随着鼠标箭头;此外最好设置在div碰撞后自动移回div碰撞前位置,避免在div碰撞后重叠,这会导致点击事件触发弹框而不是拖拽div移动碰撞触发,并因为alert弹框中断div移动导致两个div在碰撞后出现无法分开的情况。

此外关于div是否发生碰撞判定的算法,我是觉得这很有趣的。div怎么判断是否与其他div发生碰撞呢?这实际上是两个问题,一个是div与其他div比较,数据是没有自己与他人这种概念的;另一个是怎么判断碰撞。关于第一个问题,是靠鼠标拖拽事件区分目标div与所有div,用循环将目标div与所有div的比较转换为两两比较,在比较前还要用if语句避免与自身比较,发生自己与自己碰撞的乌龙;关于第二个问题怎么判断碰撞,一般直接的算法是先判断两个div是否在同一高度范围,这需要这两个目标div的top和bottom进行多次比较,然后才是判断两个目标是否重叠,即这两个div的left和right进行比较。显然直接比较算法需要比较很多次,比较同一高度至少需要比较4次,在同一高度比较是否重叠也需要4次,而且这两种比较是分先后的,也就是所有情况是4*4,共16种情况。这种算法就显得直接比较麻烦,就需要重新构思比较策略。与其分析判断两个div碰撞的情况,不如分析判断两个div不碰撞的情况,这就将所有情况减少了许多,不产生碰撞只有4种情况,其他就算发生碰撞。

解决了以上问题,我个人认为在逻辑上,我的实验源代码已经尽善尽美,但意外还是发生了。在测试中,发生了移动两个div尚未碰撞,就弹出碰撞警告框的情况。经过反复测试并在浏览器控制台输出数据进行查看,我得出结论这并不是我算法设计的问题,而是浏览器显示与计算机计算处理速度不一致,计算机计算速度太快,数据发生了变化,但浏览器还来不及更新显示内容,就被alert弹框强行中断事件。所以要在alert语句外围设置setTimeout(),让计算等待1毫秒,等窗口更新变化。加上setTimeout()语句后,成功解决移动两个div尚未碰撞,就弹出碰撞警告框的问题。

这次实验让我深刻地意识到了重复不停思考的意义。就像research(研究)由re-前缀(表重复)和search(搜索)组成,实验研究就是要不停地探索、不停地测试、不停地思考。

Original: https://www.cnblogs.com/linlinmailbox/p/16063635.html
Author: 霖霖的信箱
Title: JavaScript事件处理(三)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/606632/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 用go把博客园博客下载到本地Hexo目录下

    找到cookie 直接浏览器F12 巴拉巴拉 直接上代码 用hexo建静态博客的话,go文件在 \source\_posts目录下,run之后将会在此目录下生成cnblogs文件夹…

    Linux 2023年6月7日
    095
  • 小白上手Linux系统Redis安装与部署教程

    一:Redis的安装 1.首先需要下载linux版的redis,官网地址:http://redis.io/download。 2.创建文件夹 mkdir+文件名 3.用ftp将压缩…

    Linux 2023年6月13日
    0137
  • Apache Solr Velocity 注入远程命令执行漏洞 (CVE-2019-17558)

    一、Apache Solr介绍 Solr是一个独立的企业级搜索应用服务器,它对外提供类似于web-service的API接口,用户可以通过http请求,向搜索引擎服务器提交一定格式…

    Linux 2023年6月13日
    096
  • CentOS7安装部署Zabbix监控服务

    Zabbix Server通过Agent传来的数据写入数据库(MySQL),最终通过PHP+Apache在Web界面进行前端展示所以在启动Zabbix之前需要搭建LAMP环境 1、…

    Linux 2023年5月27日
    0118
  • 天气干燥怎么防止被静电电到

    可以摸一下墙壁或地板,把电放掉,这样摸门把手之类的金属物品就不会被电到了。 可以摸一下墙壁或地板,把电放掉,这样摸门把手之类的金属物品就不会被电到了。亲身实践,十分有效。只是摸墙和…

    Linux 2023年6月6日
    097
  • Redis 缓存更新一致性

    在使用 Redis 作为数据库缓存的场景中对数据的读取流程通常是先读取缓存如果命中则返回,未命中则从数据库读取并把数据写到缓存中。 当更新数据时则数据库和缓存都要进行更新,此时我们…

    Linux 2023年5月28日
    091
  • Java基础系列–05_面向对象

    1、概述:(1)面向过程:将问题一步一步的解决的过程(详细步骤),在C语言中所有的代码都是基于过程化的代码。(2)面向对象:面向对象是基于面向过程的编程思想,所有的事情都交由创建出…

    Linux 2023年6月7日
    0110
  • 五分钟搭建博客系统 OK?

    前言: 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 概要: 通过 Docker Compose 在使用 Docker容器构建的隔离环境中轻松运行 WordPress。…

    Linux 2023年6月14日
    0142
  • 文件批量改名(有规律)

    1.如你的文件放在桌面名字为file的文件内,我要把这些文件批量名称改为page1.jpg,page2.jpg,page3.jpg………. 2….

    Linux 2023年6月13日
    089
  • Linux下侦听端口被占用,怎么解决?

    不知道你有没有遇到过这种问题:在同一台物理机器上,服务A 启动时侦听 端口1 ,同时它也作为客户端去连接 服务B,连接服务B时候会随机一个端口号,假如随机的是 端口2 ,这个时候 …

    Linux 2023年6月13日
    098
  • 音视频技术入门课- 05 使用FFmpeg与OBS进行直播推流

    做直播推流的前提是要有直播服务器接收直播流,所以需要我们自己建设一个流媒体服务器。 流媒体服务器SRS SRS是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/H…

    Linux 2023年6月7日
    0111
  • ASP.NET Web API实现POST报文的构造与推送

    毕设和OAuth协议相关,而要理解OAuth协议就必须理解HTTP GET/POST方法。因此研究了一下如何使用Web API或MVC构造POST报文并实现客户端与服务器端的交互。…

    Linux 2023年6月13日
    098
  • zabbix模板,角色,用户,权限管理

    用户管理 用户组 用户角色 用户 模板管理 模板组 模板 posted @2022-09-07 22:22 溜溜威 阅读(14 ) 评论() 编辑 Original: https:…

    Linux 2023年6月7日
    098
  • JavaScript this

    本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。 博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高,不足和错误之处在所难免,希望大家能够批评指出。 博主…

    Linux 2023年6月13日
    092
  • 用全域安全防范美国NSA对西工大的网络攻击

    上周写的一篇文章《全域安全:一种运行时安全管理模型》,向大家介绍了全域安全管理模型,它是如何在Laxcus分布式操作系统的分布环境下,解决了分布式应用业务的全流程安全管理问题。其中…

    Linux 2023年6月6日
    0104
  • 【Leetcode】62. 不同路径

    一个机器人位于一个 m x n网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在…

    Linux 2023年6月6日
    0113
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球