是否有在多个事件侦听器上执行逻辑的设计模式

2024-03-03

我有在多个不同事件的步骤上执行的逻辑。 例如,在 mousedown 上完成一些逻辑,这会更改 mousemove 使用的某些共享状态,这也会更改最终 mouseup 使用的某些共享状态。 例如它可能看起来像这样

function handleMouseDown(){
...
setState1()
...
setState2()
}
function handleMouseMove(){
...
consumeState2
...
consumeState1
setState3()
...
}

function handleMouseUp(){
...
consumeState3
...
}

问题是,我觉得这 3 个事件中执行的逻辑之间的依赖关系是隐式的,在我看来,这使得很难弄清楚代码的作用,特别是如果您认为我有多个任务以相同的方式执行。 所以我的问题是有一个设计模式吗?


我想它很简单,不能称之为设计模式。您只需为事件处理程序使用一个公共状态(在我们的例子中是一个对象)。一直想用代理实现拖动,所以就在这里。

带有拖动和调整大小手柄的更新版本在这里:
我怎样才能使div不会脱离紫色div? https://stackoverflow.com/questions/76531761/how-can-i-make-it-so-that-the-divs-dont-get-out-of-the-purple-div/76533863#76533863

const container = document.querySelector('div.container');
const draggable = document.querySelector('div.draggable');

const move = (x, y) => {

  x = state.fromX + (x - state.startX);
  y = state.fromY + (y - state.startY);

  // don't allow moving outside the container
  if (x < 0) x = 0;
  else if (x + draggable.offsetWidth > container.offsetWidth) x = container.offsetWidth - draggable.offsetWidth;
  
  if (y < 0) y = 0;
  else if (y + draggable.offsetHeight > container.offsetHeight) y = container.offsetHeight - draggable.offsetHeight;
  
  draggable.style.left = x + 'px';
  draggable.style.top = y + 'px';
};

const listen = (op = 'add') => 
  Object.entries(listeners).slice(1)
    .forEach(([name, listener]) => document[op + 'EventListener'](name, listener));

const state = new Proxy({}, {
  set(state, prop, val){
    const out = Reflect.set(...arguments);
    const ops = {
      startY: () => {
        listen();
        const style = getComputedStyle(draggable); 
        [state.fromX, state.fromY] = [parseInt(style.left), parseInt(style.top)];
      },
      dragY: () => move(state.dragX, state.dragY),
      stopY: () => listen('remove') + move(state.stopX, state.stopY),
    };
    // use a resolved Promise to postpone the move as a microtask so
    // the order of state mutation isn't important
    ops[prop] && Promise.resolve().then(ops[prop]);
    return out;
  }
});

const listeners = {
  mousedown: e => Object.assign(state, {startX: e.pageX, startY: e.pageY}),
  // here we first provide dragY to check that the order of props is not important
  mousemove: e => Object.assign(state, {dragY: e.pageY, dragX: e.pageX}),
  mouseup: e => Object.assign(state, {stopX: e.pageX, stopY: e.pageY}),
};

draggable.addEventListener('mousedown', listeners.mousedown);
html,body{
  height:100%;
  margin:0;
  padding:0;
}
div.draggable{
  position: absolute;
  padding:30px;
  border-radius:4px;
  background:#ddd;
  cursor:move;
  user-select: none;
  left: 15px;
  top: 15px;
}
div.container{
  left:15px;
  top:15px;
  background: #111;
  border-radius:4px;
  width:calc(100% - 30px);
  height:calc(100% - 30px);
  position: relative;
}
<div class="container">
  <div class="draggable">Draggable</div>
</div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有在多个事件侦听器上执行逻辑的设计模式 的相关文章

  • 为什么我的反应路由器链接将我带到页面中间?

    我的网站上有很多链接 但只有一个可以执行此操作 它没有将我带到导航栏的顶部 而是转到内容的中间 知道为什么会这样吗 这是一个页面 其中有一个 map经历一些JSON 这是渲染div页面下方的文本元素 如果重要的话 这是一些可能相关的代码 路
  • MailTo 从 Javascript

    我有一个链接按钮 用于从页面内容构建邮件 从 javascript 启动它而不打开空白窗口或干扰调用它的窗口的最佳方法是什么 function Email var sMailTo mailto var sBody var alSelecte
  • 如何在通过 .ajaxForm() 提交表单之前执行一些操作?

    我正在使用 ajaxForm 框架来发送我的数据 而无需重新加载我的页面 ReplayForm ajaxForm success function data alert Success 现在 我想在提交表单之前检查一些条件 如果条件为假 则
  • 使用 Jest 和 React JS TestUtils 测试表单

    我有一个带有 3 个单选按钮的表单 如下所示 假名
  • 如何判断一个网页是否支持jquery?

    确定网页是否启用 jquery 的最佳方法是什么 如果这是确定它的最佳方法 则使用 jquery 本身 if jQuery jquery object exists jQuery 并不神奇 它本质上只是一个大对象 您可以像检查任何其他对象一
  • 在 jQuery .live() 方法中模拟“焦点”和“模糊”

    Update 从 jQuery 1 4 开始 live 现在支持focusin and focusout events jQuery http www jquery com currently1 doesn t support blur o
  • 使用 jQuery Select2 清除下拉菜单

    我正在尝试使用奇妙的方式以编程方式清除下拉菜单Select2 http ivaynberg github com select2 图书馆 使用 Select2 远程 ajax 调用动态填充下拉列表query option HTML
  • 如何在不阻止触摸启动的情况下防止“过度滚动历史导航”?

    我正在实现基于滑动的导航 但我在使用 Chrome 时遇到了麻烦 当页面向右拖动时 会触发新实现的功能 过度滚动历史导航 从而导致跳回 到 历史 1 为了防止这种情况 我必须打电话 preventDefault on touchstart
  • 如何立即启动setInterval循环? [复制]

    这个问题在这里已经有答案了 在一个简单的setInterval setInterval function Do something every 9 seconds 9000 第一个动作将在 9 秒后发生 t 9s 如何强制循环立即执行第一个
  • 此页面上的脚本导致 ie 运行缓慢

    问题就在标题中 IE 行为异常 并说有一个脚本运行缓慢 FF 和 Chrome 没有这个问题 我怎样才能找到问题所在 那个页面有很多JS 手动检查不是一个好主意 EDIT 这是我正在处理的一个项目的页面 但我需要一个工具来查找问题 End
  • API 使用令牌向 odoo 进行身份验证

    我想使用令牌从 Express 应用程序向 Odoo 进行身份验证 我在用odoo xmlrpc https www npmjs com package odoo xmlrpc连接 Odoo 的节点模块 我的快递应用程序 Odoo 要求 A
  • JS 保留以零结尾的小数[重复]

    这个问题在这里已经有答案了 在JavaScript中 是否可以 锁定 十进制数 以保留以零结尾的 浮点数 例如 我有 2 个不同的数字 如下所示 伪代码 let a 1 0 let b 1 00 a b true should be fal
  • karma/jasmine 控制台更详细的测试结果

    我使用 Karma 和 Jasmine 进行 javascript 单元测试 假设我有一个失败的测试 如下所示 expect objectA toEqual expectedObjectA 当失败时 我看到控制台上转储了两个对象 并显示一条
  • JavaScript 将键添加到数组中的每个值

    我下面有这个数组 它由一个简单的数组组成 我想要完成的是放一把钥匙id在每个数组值前面以实现类似的效果 id a id b id c id d 有没有一种简单的方法可以做到这一点 任何帮助将不胜感激 谢谢 var test a b c d
  • 使用 JQuery 禁用和启用所有超链接

    我有以下禁用所有超链接的内容 但在事件发生后我想再次启用它们 我该如何执行此操作 a click function return false 我认为这不仅仅是将其设置为 true 那么简单 谢谢大家 不要以这种方式绑定 点击 处理程序 而是
  • javascript 是否有等效的 __repr__ ?

    我最接近Python的东西repr这是 function User name password this name name this password password User prototype toString function r
  • Javascript 浮点乘以 100 仍然有错误

    我有一个货币字段的文本输入 我在字段中输入 33 91 并在尝试使用 乘以 100 技术时得到以下结果 var curWth parseInt trans withdraw index val 100 3390 var curWth par
  • 如何重复 ajax 请求,直到满足 RxJS Observable 的条件?

    我正在尝试重复请求 直到响应包含使用 RxJS 的数据 此时我想调用成功 或失败 处理程序 但我在使用 RxJS 时遇到了麻烦 这是我目前的方法 redux observable action observable mergeMap gt
  • 我可以使用 ASP.NET WebForms 母版页在每个内容页中包含不同的 javascript/css 文件吗?

    我有几个使用相同母版页的内容页 它们并不都需要包含在相同的 javascript 和 css 文件中 tag 是否可以更改内容来自内容页面的标签 确实如此 但我建议采取一些不同的做法 我在关闭正文标签的正上方放置了一个内容占位符 然后我填充
  • ThreeJS 中阴影的奇怪行为

    所以我有一个 ThreeJS 场景 并且添加了一些球体 多材质 我还添加了定向光 this light new THREE DirectionalLight 0xFFFFFF 1 this light position set 2 10 2

随机推荐

  • DLL 的配置文件

    我们的应用程序在运行时从应用程序的根加载我们的自定义 DLL 这些 DLL 正在实现某些接口 并通过反射执行方法 如果自定义 DLL 必须从配置文件中读取某些值 那么我们必须将这些配置设置复制到主应用程序的 app config 文件中 有
  • Scrapy Image Pipeline:如何重命名图像?

    我有一个蜘蛛可以获取数据和图像 我想用我正在获取的相应 标题 重命名图像 以下是我的代码 蜘蛛1 py from imageToFileSystemCheck items import ImagetofilesystemcheckItem
  • .cpp 文件和 .h 文件有什么区别?

    因为我已经做了 cpp文件 然后将它们传输到 h文件 我能找到的唯一区别是你不能 include cpp文件 我缺少什么区别吗 C 构建系统 编译器 不知道有什么区别 所以这都是约定之一 约定是 h文件是声明 并且 cpp文件是定义 这就是
  • 数据原子查询性能改进

    我在 Datomic 数据库中有一个与此类似的架构 tenant db id db id db part db db ident tenant guid db unique db unique identity db valueType d
  • Bootstrap 折叠力 全部展开

    我有很多不同的部分 它们有自己的折叠元素 我已经实现了 jquery 来展开和折叠它们 jQuery collapse each function index this collapse toggle HTML 片段 ul class na
  • 使用 phantomjs/casperjs 测试 DOM 元素

    我有一个基于 AJAX 的 javascript 应用程序 我想对其进行接口测试 例如 我想编写一个测试来加载我的网站 从给定的 URL 并检查是否存在一些 DOM 元素 给定的 id 和给定的类 问题是当我在浏览器中输入 URL 时 我的
  • JFreeChart 在 Y 轴上将整数值显示为浮点数

    我在用着JFreeChart创建时间序列图表 但当我将整数值作为 Y 轴传递时 它会将它们显示为浮点数 问题是什么 我正在创建这样的图表 this TodaySeriesGoldPrice new TimeSeries Price Minu
  • 无法拉取 b/c“您有未暂存的更改”,但状态显示没有更改

    我正在与一位开发人员合作 他遇到了一个我以前从未遇到过的奇怪问题 他正在开发一个存储库 需要先从其他人那里获取最新的更改 然后才能推送 他所有的改变都被承诺了 git pull Cannot pull with rebase You hav
  • 从 Fiddler 嗅探 Android 应用程序的 HTTPS 流量失败,Fiddler 中仅显示“隧道到”条目

    我正在尝试从已 root 的 Android 设备 4 4 4 捕获 HTTPS 流量 以分析应用程序的未记录协议 我已将 Fiddler 设置为代理并启用了 HTTPS 嗅探 我已在我的设备上安装了 Fiddler 生成的根证书 我已在
  • Outlook Mapi 访问共享联系人

    我想通过 Mapi 从 Outlook 导入联系人 第一步使用标准接触是没有问题的 MAPIFolder contactObjects outlookObj Session GetDefaultFolder OlDefaultFolders
  • :首次安装或使用软件包时运行代码

    我正忙着为一位对 R 知之甚少的客户编写一个包 考虑到他们的复杂数据结构 我需要在 R 中建立一个 数据库 其中包含从他们从另一家公司获得的一组电子表格中获得的大量信息 由于他们无法在计算机上安装 SQL 等 ICT 有一些电源控制问题 我
  • ffmpeg、libav 和 avconv 之间有什么区别和相似之处?

    当我跑步时ffmpeg在 Ubuntu 上 它显示 ffmpeg ffmpeg version v0 8 Copyright c 2000 2011 the Libav developers built on Feb 28 2012 13
  • 如何使 Windows 10 枢轴/选项卡标题全宽屏幕

    如何使枢轴 选项卡标题使每个单独的选项卡具有相同的宽度并拉伸枢轴标题的整个宽度而不延伸出屏幕 特别是对于移动设备 我还没有找到如何做到这一点的例子 这就是我想要实现的目标 如何使枢轴 选项卡标题使每个单独的选项卡具有相同的宽度并拉伸整个宽度
  • 用于将结构类型映射到枚举的 C++ 模板?

    我有类似的东西 struct A struct B struct C class MyEnum public enum Value a b c template
  • 如何通过环境变量设置 Java 的最小和最大堆大小?

    如何通过环境变量设置 Java 的最小和最大堆大小 我知道可以在启动java时设置堆大小 但我想通过我的服务器上的环境变量来调整它 您不能直接使用环境变量来做到这一点 您需要使用传递给 java 命令的一组 非标准 选项 运行 java X
  • 如何在没有扩展程序的情况下在 Chrome 中测量像素?

    由于工作中的安全限制 我不被允许安装 Chrome 扩展程序 Chrome 在开发者工具中内置了一个标尺 但我不知道如何像标尺允许的那样定义起点和终点 是否有无需安装 Chrome 扩展程序即可测量像素的工具或技术 您可以创建自己的标尺功能
  • 如何设置仅显示月份和年份的日期选择器的日期

    我正在尝试显示一个仅显示月份 年份菜单的日期选择器 就像这个 Q 中那样jquery 日期选择器仅显示月份年份 https stackoverflow com questions 2208480 jquery date picker to
  • 来自多个数据库的 Hibernate 实体

    我们的数据模型分为两个数据库上的模式 除了一些在两者之间桥接的单键关系之外 这些模式是单独使用的 没有跨两个数据库的写入事务 类似这个问题使用 Hibernate 连接不同数据库中的 2 个表 https stackoverflow com
  • 为什么覆盖会改变列名

    我使用的是 rev 监听器的默认实现 正如预期的那样 我的 REVINFO 表中的列是 revtstmp 和 rev 然而 当我覆盖默认值时 我所做的只是 MyRevisionEntity extends DefaultRevisionEn
  • 是否有在多个事件侦听器上执行逻辑的设计模式

    我有在多个不同事件的步骤上执行的逻辑 例如 在 mousedown 上完成一些逻辑 这会更改 mousemove 使用的某些共享状态 这也会更改最终 mouseup 使用的某些共享状态 例如它可能看起来像这样 function handle