JavaScript 拖拽与观察者模式的实现及应用

前言

本文将通过几个具体的代码片段,深入探讨 JavaScript 中的拖拽功能和观察者模式(发布-订阅模式)的实现及其应用场景。

这些代码片段不仅展示了如何实现这些功能,还解释了其背后的原理和实际用途。通过阅读本文,读者可以更好地理解 JavaScript 的高级特性,并将其应用到实际项目中。


1. 拖拽功能的实现

在这里插入图片描述

代码片段

```html



    
    
    
    Document
    


    
father
son
```

代码解析

拖拽类 Drag
```javascript
class Drag {
    constructor(selector) {
        // 获取拖拽的对象
        this.ele = document.querySelector(selector);
        // 添加事件
        this.ele.onmousedown = function (evt) {
            // this: 原来指向了 ele 对象,这里需要一个实例对象
            this.fnDown(evt);
        }.bind(this);
    }

    fnDown(evt) {
        let e = evt || window.event;
        // 求鼠标的相对坐标值
        this.dis_x = e.offsetX;
        this.dis_y = e.offsetY;

        // 移动事件
        document.onmousemove = function (evt) {
            // this: document
            this.fnMove(evt);
        }.bind(this);

        // 鼠标抬起事件
        document.onmouseup = this.fnUp.bind(this);

        // 取消默认行为
        document.ondragstart = function () {
            return false;
        };
    }

    fnMove(evt) {
        let e = evt || window.event;
        this.ele.style.left = e.pageX - this.dis_x + 'px';
        this.ele.style.top = e.pageY - this.dis_y + 'px';
    }

    fnUp() {
        document.onmousemove = null;
    }
}

```
子类 Subdrag 继承自 Drag
```javascript
class Subdrag extends Drag {
    constructor(selector) {
        // 调用父类的构造函数
        super(selector);
    }

    fnMove(evt) {
        let e = evt || window.event;
        let left = e.pageX - this.dis_x;
        let top = e.pageY - this.dis_y;

        // 设置边界
        if (left <= 0) {
            left = 0;
        } else if (left >= document.documentElement.clientWidth - this.ele.offsetWidth) {
            left = document.documentElement.clientWidth - this.ele.offsetWidth;
        }

        if (top <= 0) {
            top = 0;
        } else if (top >= document.documentElement.clientHeight - this.ele.offsetHeight) {
            top = document.documentElement.clientHeight - this.ele.offsetHeight;
        }

        this.ele.style.left = left + 'px';
        this.ele.style.top = top + 'px';
    }
}

```

在这里插入图片描述

功能说明

拖拽功能 是一种常见的用户交互方式,允许用户通过鼠标移动元素。在上述代码中,Drag 类实现了基本的拖拽功能,包括:

  1. 获取拖拽对象 :通过选择器获取要拖拽的 DOM 元素。
  2. 添加鼠标按下事件 :当用户按下鼠标时,记录鼠标相对于元素的位置 (dis_x, dis_y)。
  3. 添加鼠标移动事件 :根据鼠标的当前位置更新元素的位置。
  4. 添加鼠标抬起事件 :当用户释放鼠标时,移除鼠标移动事件,防止后续不必要的移动。
  5. 取消默认行为 :阻止浏览器的默认拖拽行为。

Subdrag 类继承自 Drag 类,并在其基础上增加了边界限制,确保拖拽的元素不会超出视口范围。这使得拖拽体验更加友好和实用。


2. 观察者模式(发布-订阅模式)

代码片段 1:药店示例

```html



    
    
    
    Document


    



```

在这里插入图片描述

代码解析

观察者模式 (发布-订阅模式)是一种设计模式,用于定义对象间的一种一对多依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。在上述代码中,drugstore 作为发布者,维护了一个名为 obj 的花名册,记录了不同事件的订阅者列表。

具体实现如下:

  1. 订阅方法listen:接收事件名称 eventName 和回调函数 fn,将回调函数添加到对应事件的订阅者列表中。
  2. 发布方法publish:接收事件名称 eventName 和数据 data,遍历对应的订阅者列表,依次调用每个回调函数并传递数据。

通过这种方式,多个订阅者可以根据不同的条件对同一事件做出响应。例如,在上述代码中,四个不同的订阅者(小周、小易、小王、老王)根据药店发布的口罩信息做出了不同的反应。

代码片段 2:售楼处示例

```html



    
    
    
    Document


    



```

在这里插入图片描述

代码解析

在售楼处示例中,salesOffice 作为发布者,同样使用了花名册 arr 来记录订阅者的回调函数。不同的是,这里的订阅者只关心新楼盘推出的消息,而不需要区分不同的事件类型。

具体实现如下:

  1. 订阅方法listen:接收回调函数 fn 并将其添加到花名册中。
  2. 发布方法publish:接收数据 data,遍历花名册中的所有回调函数并依次调用。

通过这种方式,多个订阅者可以根据新楼盘的信息做出不同的反应。例如,在上述代码中,三个不同的订阅者(小明、小龙、小强)根据售楼处发布的房屋信息做出了不同的决策。


结尾

通过以上两个主要部分的详细探讨,我们深入分析了 JavaScript 中的拖拽功能和观察者模式的实现及其应用场景。拖拽功能使得用户能够直观地操作页面元素,而观察者模式则提供了一种优雅的方式来处理对象间的依赖关系,避免了紧耦合的问题。

在实际项目中,合理运用这些技术和模式可以显著提高用户体验和代码的可维护性。希望本文的内容对读者有所帮助,欢迎继续探索 JavaScript 的更多可能性。无论是构建复杂的用户界面还是实现高效的数据通信,掌握这些高级编程技巧都将为开发者带来更多的便利和灵活性。


文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/6837.html

(0)
LomuLomu
上一篇 2025 年 1 月 19 日
下一篇 2025 年 1 月 21 日

相关推荐

  • 《动态演进架构(第二版)》电子版获取指南

    书籍概要 这本专业著作系统阐述了架构适应性评估体系、智能化架构管理方案以及数据动态演进的前沿方法与实践经验。全书采用三模块结构:首模块着重解析动态架构的核心机制——详细说明开发团队如何运用技术手段构建适应性评估模型、自动化部署流程等现代化软件项目管理工具;次模块聚焦架构模式与设计准则,深入探讨组件耦合度、功能复用性等关键要素,为构建可持续优化的系统架构提供专…

    2025 年 5 月 14 日
    35100
  • 高效灵活!企业级IT资产配置管理数据库解决方案

    在现代企业IT运维中,基础设施规模庞大且变动频繁,传统管理方式往往难以应对复杂的资产配置需求。本文为您推荐一款模块化设计的运维配置管理数据库系统,它能有效提升企业IT团队对硬件设备和软件服务的管控效率。 产品概述 CMDB Pro是一款采用现代化架构的配置管理数据库,具备模型自定义和智能资源探测能力,专为解决企业级IT资产管理难题而设计。核心优势:- 智能探…

    2025 年 5 月 11 日
    47300
  • Claude Pro国内可用订阅开通教程

    Claude Pro国内可用订阅开通教程,整理国内用户用微信支付宝完成Claude Pro充值、订阅和代充的操作流程。

    未分类 2026 年 6 月 29 日
    7100
  • GPT Plus和Claude Pro双会员代充

    GPT Plus和Claude Pro双会员代充,适合同时使用 ChatGPT 和 Claude 的用户,重点说明微信支付宝、账号核对和两个账号各自的会员状态。

    未分类 2026 年 5 月 20 日
    13200
  • MySQL for update skip locked 与 for update nowait

    理论(下方有实操) for update skip locked 官方文档:https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html#innodb-locking-reads-for-update 语法:select语句后跟 for update skip locked 作用:目标对象…

    未分类 2024 年 12 月 31 日
    77200

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信