Javascript学习笔记18 高级技巧(自定义事件 拖放)

Outlook新邮件桌面通知问题全解决 仅仅勾选“显示桌面通知”选项可能还不足以满足所有用户的需求。点击桌面通知设置按钮在“邮件到达”板块中,找到并点击“桌面通知设置”按钮。这将弹出一个新的窗口,允许你自定义桌面通知的详细设置。设置显示时间和透明度在桌面通知设置窗口中,你可以根据自己的需求调整通知的显示时间和透明度。显示时间决定了通知在桌面右下角停留的时间长短,而透明度则影响通知窗口的透明程度。预览设置效果调整完设置后,点击“预览”按钮。此时,Outlook将在桌面右下角显示一个模拟的通知提醒窗口,让你查看设置效果是否满意。保存设置。 阅读详情

自定义事件

事件是一种叫做观察者的设计模式,观察者模式由两类对象组成:主体和观察者。主体负责发布事件,同时观察者知道通过订阅这些事件来观察主体。主体可以独自存在并正常运作即使观察者不存在。在DOM结构中,DOM元素便是主体,事件处理代码便是观察者
自定义事件背后的概念是创建一个管理事件的对象,让其他对象监听那些事件。

function EventTarget(){     //用于管理事件的对象
    this.handlers = {};    //handler属性用于存储各种事件类型的处理函数
} 
EventTarget.prototype = {     
    constructor: EventTarget,

    addHandler: function(type, handler){   //添加事件处理程序,接受两个参数,事件类型和处理函数
         if (typeof this.handlers[type] == "undefined"){  //如果是新的事件类型
              this.handlers[type] = [];   //新建一个数组,用于存储新事件类型的一系列处理函数
         }
         this.handlers[type].push(handler);  //将处理函数推入对应事件类型的数组中
     }, 

    fire: function(event){   //触发事件,接受一个对象,包含事件类型和处理函数的输入参数
         if (!event.target){  //设置event对象的target属性
             event.target = this;
         }
         if (this.handlers[event.type] instanceof Array){
             var handlers = this.handlers[event.type];   //取出指定事件类型的处理函数数组
             for (var i=0, len=handlers.length; i < len; i++){  //依次调用数组中的每一个处理函数
                 handlers[i](event); 
            }
         }
     },

     removeHandler: function(type, handler){   //移除事件
        if (this.handlers[type] instanceof Array){ 
            var handlers = this.handlers[type]; 
            for (var i=0, len=handlers.length; i < len; i++){  //寻找对应事件函数在数组中的下标 
                if (handlers[i] === handler){ 
                    break;
                 }
             }
             handlers.splice(i, 1);   //删除对应下标的处理函数
          }
      }
};

使用例子

function handleMessage(event){
    alert("Message received:" + event.message);
}

var target = new EventTarget();

target.addHandler("message",handleMessage);   //添加一个事件处理程序

target.fire({type:"message", message:"Hello world"});   //触发事件处理程序

target.removeHandler("message",handleMessage);   //删除事件处理程序

拖放

实现拖放的基本思想是利用mousemove事件,使绝对定位元素的坐标跟随鼠标指针的位置,在鼠标按下的时候(mousedown事件)启用拖放,在鼠标释放的时候(mouseup事件)关闭拖放,就可以实现。

var DragDrop = function(){
    var dragging = null;     //用于保存拖放的对象
    function handleEvent(event){   //事件处理程序
        switch(event.type){
            case "mousedown":   //鼠标按下,若元素可拖放,则启动拖放
                if (event.target.className.indexOf("draggable") > -1){
                    dragging = event.target;
                }
                break;
            case "mousemove":  //拖放过程中使对象跟随鼠标移动
                if (dragging !== null){
                    dragging.style.left = event.clientX + "px";
                    dragging.style.top = event.clientY + "px";
                }
                break;
            case "mouseup":   //关闭拖放
                dragging = null;
                break;
        }
    }

    return {
        enable:function(){    //启用拖放功能
            document.addEventListener("mousedown",handleEvent,false);
            document.addEventListener("mousemove",handleEvent,false);
            document.addEventListener("mouseup",handleEvent,false);
        },
        disable:function(){  //启用拖放功能
            document.removeEventListener("mousedown",handleEvent,false);
            document.removeEventListener("mousemove",handleEvent,false);
            document.removeEventListener("mouseup",handleEvent,false);
        }
    } 
}();

上述例子,当鼠标开始移动时,元素好像是跳了一下,显得很不自然。原因在于,元素的left和top坐标默认为元素的左上角那一点。要想保持用户点击时那一点的坐标与鼠标坐标保持一致,需要计算鼠标与元素左上角的坐标差值

    var dragging = null;     //用于保存拖放的对象

    var diffX = 0,   //鼠标和元素左上角X方向上的差值
        diffY = 0;  //鼠标和元素左上角Y方向上的差值
    function handleEvent(event){   //事件处理程序
        switch(event.type){
            case "mousedown":   //鼠标按下,若元素可拖放,则启动拖放
                if (event.target.className.indexOf("draggable") > -1){
                    dragging = event.target;
                    diffX = event.clientX - event.target.offsetLeft;
                    diffX = event.clientY - event.target.offsetTop;
                }
                break;
            case "mousemove":  //拖放过程中使对象跟随鼠标移动
                if (dragging !== null){
                    dragging.style.left = (event.clientX - diffX) + "px";
                    dragging.style.top = (event.clientY - diffY) + "px";
                }
                break;
            case "mouseup":   //关闭拖放
                dragging = null;
                break;
        }
    }

以上只是实现了拖放功能,但是缺少事件,不知道什么时候拖放开始和结束,因此可以结合之前的自定义事件,为拖放添加dragstart,drag,dragend三个自定义事件

var DragDrop = function(){
    var dragging = null;     

    var diffX = 0,   
        diffY = 0;

    var dragdrop = new EventTarget();  //创建一个管理自定义事件的对象
    function handleEvent(event){   
        switch(event.type){
            case "mousedown":   
                if (event.target.className.indexOf("draggable") > -1){
                    dragging = event.target;
                    diffX = event.clientX - event.target.offsetLeft;
                    diffX = event.clientY - event.target.offsetTop;
                    dragdrop.fire({type:"dragstart",target:dragging,
                                    x:event.clientX,y:event.clientY});  //触发dragstart事件
                }
                break;
            case "mousemove":  
                if (dragging !== null){
                    dragging.style.left = (event.clientX - diffX) + "px";
                    dragging.style.top = (event.clientY - diffY) + "px";
                    dragdrop.fire({type:"drag",target:dragging,
                                    x:event.clientX,y:event.clientY});  //触发drag事件
                }
                break;
            case "mouseup":
                dragdrop.fire({type:"dragend",target:dragging,
                                    x:event.clientX,y:event.clientY});  //触发dragend事件   
                dragging = null;
                break;
        }
    }

    dragdrop.enable = function(){    
            document.addEventListener("mousedown",handleEvent,false);
            document.addEventListener("mousemove",handleEvent,false);
            document.addEventListener("mouseup",handleEvent,false);
    };
    dragdrop.disable = function(){  
            document.removeEventListener("mousedown",handleEvent,false);
            document.removeEventListener("mousemove",handleEvent,false);
            document.removeEventListener("mouseup",handleEvent,false);
    };

    return dragdrop;  //返回事件对象

}();

添加事件处理程序

DragDrop.addHandler("dragstart",function(event){
    var status = document.getElementById("status");
    status.innerHTML = "start dragging" + event.target.id;  
}); 

DragDrop.addHandler("drag",function(event){
    var status = document.getElementById("status");
    status.innerHTML = "dragged" + event.target.id + "to" + event.x + "," + event.y;
}); 

DragDrop.addHandler("dragend",function(event){
    var status = document.getElementById("status");
    status.innerHTML = "droped" + event.target.id + "at" + event.x + "," + event.y;
}); 
Outlook收不到邮件?这些方法或许能帮你解决 然而,有时候我们可能会遇到无法收到邮件的困扰,这不仅会影响工作效率,还可能带来不必要的麻烦。希望这篇文章能够帮助你解决Outlook收不到邮件的问题,让你的邮件管理更加高效和便捷。这是一个有效的解决方法,因为有时候Outlook的索引可能会损坏或过时,导致邮件无法正常接收。在这种情况下,我们需要联系邮件提供商的客服部门,寻求他们的帮助。有时候,Outlook中的邮件规则或过滤器可能会阻止某些邮件的接收。Outlook提供了一个内置的诊断工具,可以帮助我们检测和解决一些常见的邮件接收问题。 阅读详情

相关推荐

H医药公司配送中心布局仿真优化

新增2个Source,Source1命名为“货物到达”,用来进行仿真供应商原料到达,Source2命名为“订单到达”,用来进行仿真客户需求订单的到达,如下图是设置两个发生器的具体参数。通过主操作界面上的各个实体工具,如发生器、暂存区、货架、处理器、吸收器等实体工具对初始模型和优化后的方案模型进行仿真建模,建立优化前后的模型图如下图所示。通过下表可以看出,优化前操作员的总运行距离为132.11km,而优化后操作员的总运行距离为128.17km,运行距离缩短,操作员的疲劳强度降低。

m0_72514516的博客 2529

使用TS中元素使用offsetHeight,offsetTop,offsetLeft报错

使用ts后,可以使用scroll家族和client家族,但使用offset家族虽然会报错但也能运行

weixin_59916662的博客 3664

画个板子玩一玩STM32F030F4P6,也许是最便宜的32bit MCU

前言,什么是STM32F030F4P6 STM32目前最便宜的芯片之一应该就是这一块,STM32F030F4P6,这一个芯片没有USB,但是其他都有,引脚少,价格低廉,如果找不到原厂,可以买替代的国产芯片,性能也一样。 不管怎么样也是Cortex-M0,比8bit和16bit的性能都强,总的来说就是低价,引脚少,体积小的同时,还容易开发,有很多模拟输入可玩,还有SPI,硬件I2C等等 所以,这一款MCU真的是从理论来说又便宜又好用,非常适合把玩。 画个板,最小系统 STM32F030其..

arenascat的博客 2万+

vue3(ts)类型“EventTarget”上不存在属性“value”

e.target在ts下的类型断言

Gaojuncheng112的博客 7213

01 - 什么是SVM

摘要:SVM(共享虚拟内存)技术使CPU和GPU能共享同一虚拟地址空间,简化异构计算编程。传统模型需手动管理CPU/GPU内存和拷贝数据,而SVM允许直接传递指针,自动处理页面迁移和一致性维护。其核心包括统一地址空间、按需迁移、页面故障处理和一致性管理,显著降低编程复杂度并提升性能。通过HMM框架、MMU通知和GPU页面异常等机制实现高效内存共享,支持复杂数据结构,为异构计算带来便利。

图形/计算GPU的驱动与虚拟化技术分享园地 3132

Flink实战案例(十三):Flink DataStream 八大分区策略与自定义分区器

声明:本系列博客是根据SGG的视频整理而成,非常适合大家入门学习。 《2021年最新版大数据面试题全面开启更新》 分区策略决定了一条数据如何发送给下游。Flink中默认提供了八大分区策略(也叫分区器)。 本文基于Flink 1.9.0总结Flink DataStream中的八大分区策略以及手动实现一个自定义分区器。 八大分区策略继承关系图 ChannelSelector: 接口,决定将记录写入哪个Channel。有3个方法: void setup(int numberOfChannels):

微信搜:import_bigdata,大数据领域硬核原创作者 1124

react事件对象无法获取offsetLeft、offsetTop、X、Y等元素解决方法

react获取到的事件缺少了部分一些属性,和原生事件对象不同,如图: * 解决方法 事件中使用: e.nativeEvent 这是一个比较坑的地方,应该是react的事件对象没有包含一些原生eventDom的属性。

量子前端的博客 1923

Python控制程控电源(USB)

随着智能电动汽车行业的持续发展,汽车电子或嵌入式设备在软硬件的测试中,都会使用程控电源供电,特别是自动化测试、压力测试场景必定使用到程控电源控制,控制电源上下电,监听电源电流、电压等,以下就以常见的艾德克斯程控电源为例,分享如何通过USB连接方式Python语言来控制程控电源。

测试领域技术分享 2865

类型“EventTarget”上不存在属性“clientHeight”。

类型“EventTarget”上不存在属性“clientHeight”。

KaiSarH 3661

基于LLM【M3】驱动的自动化攻击智能体AK(受控使用)

摘要:文章实测了基于大模型的目标驱动型云攻击智能体,展示攻击者仅需输入业务目标(如"窃取BigQuery数据")即可自动完成SSRF、令牌解析、数据导出等全链条攻击。研究发现:(1)攻击编排范式已从固定脚本升级为自适应路径;(2)传统基于IOC的防御与新型攻击存在结构性错位;(3)防御需转向元数据加固、跨服务行为序列检测和AI驱动的紫队演练。实验在授权靶场使用合成数据,验证了攻击智能体"监督者模型+专业执行组"的协作模式,强调防御体系需从单点检测升级为攻击链理解能力。

云上笛暮 307

VTK API 详解(103):vtkGPUVolumeRayCastMapper - GPU加速体绘制

是 VTK 中基于 GPU 的高效体绘制映射器,利用现代显卡的计算能力,通过射线投射算法实现快速且高质量的三维体积渲染。相比 CPU 版本的,GPU 映射器性能大幅提升,支持更复杂的光照和渲染效果,是体绘制的主流选择。是 VTK 中性能优异的GPU体绘制映射器;适合大数据集和实时交互应用;配合灵活设置颜色、透明度和光照;建议在支持OpenGL的环境中使用。

yumeiguo的博客 295

实现自定义拖放

实现自定义拖放------创建COleDropSource对象来控制放置对于大多数应用程序,拖放功能的默认实现就已经足够了。但是,某些应用程序可能要求更改此标准行为。马上你会看到一个更改标准的拖放行为的例子,可以说明其实这是一件多么简单的事情,或许,你会得到一些自定义拖放的感性认识。在我的工具条上,有一个按钮,资源ID号为:ID_DRAG_MY_OBJ,点击该按钮后,将开始拖放动作(注

1011

基于STM32L4XX、HAL库的RTL8201F 以太网收发器(PHY)驱动程序设计

define PHY_RESET_DELAY 1000 // PHY复位延迟(ms)#define PHY_AUTONEGO_DELAY 3000 // 自动协商延迟(ms)/* 检查PHY ID (RTL8201F的ID为0x001CC816) *//* 系统时钟配置,确保ETH有50MHz时钟 *//* 初始化CPU, AHB和APB总线时钟 */

zhusl6688的博客 810

Outlook添加多个邮箱:账户与共享邮箱

本文详细介绍了在Outlook中添加多个邮箱账户的操作方法。通过文件菜单进入账户设置,选择数据文件选项卡进行高级配置,可添加新邮箱地址。添加成功后可在客户端统一管理多个邮箱,提升工作效率。教程适用于Outlook 2016/2019/2021及Microsoft 365版本,若自动配置失败建议检查网络或手动输入服务器信息。企业用户需提前获取IT管理员提供的配置参数。

分享 Windows 系统部署、镜像封装、终端管理、故障排查与运维自动化实践,涵盖 Sysinternals、PowerShell 和 AI 工具应用。记录真实问题、探索过程与解决方法,也分享 AI 时代的学习心得和实践经验,让技术更易理解 2万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Outlook 也是可以进行高度复杂的搜索

原来,Outlook 也是可以进行高度复杂的搜索的:在按下 检索 按钮后,出现了一行菜单。在这行菜单栏的最右边,有一个Option选项按钮。按下这个按钮。在下拉菜单里选高度检索,就可以了。这样就可以进行各种复杂条件的检索,像对文...

cuibin7108的博客 261

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Microsoft Outlook邮箱存储清理问题

前言记录一次outlook邮箱存储占满,用户又无法自主清理的问题。微软官方也记录了很多处理步骤文档,但是写的过于“官方”,处理起来冗余复杂,于是决定记录一下,有需要的可以进行参考。问题描述outlook邮箱存储一共50G(这个与分配的License有关,比如Microsoft 365 Business Basic分配的Ex...

weixin_36892727的博客 2508

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

如果使用Outlook 2024出现问题

如果使用Outlook 2024出现问题

XZZ_2018的博客 825

[原创] - C#编程大幅提高OUTLOOK的邮件搜索能力!

使用OUTLOOK, 你有没有遇到过上图的问题? 多达18419封邮件! 太多了, 每次想找一个邮件都非常耗时, 想办法解决这个问题成了一件非常紧迫的事情. 利用MS Search当然可以, 但是它太heavy了, 而且不支持如逻辑搜索表达式等复杂查找功能, 怎么办? 幸运的是我有WEBUS2.0 SDK, 于是我决定自己开发一个名为Outlook Searcher (Outlook搜索精灵)...

weixin_30376323的博客 327

Outlook 添加附件闪退:yi赛通 DynamicDll64.dll 冲突排查

摘要 Outlook添加附件时闪退问题排查案例:故障表现为用户点击添加附件时Outlook立即崩溃,事件查看器显示故障模块为yi赛通安全客户端中的DynamicDll64.dll。通过Windows可靠性监视器和事件查看器分析,确认问题源于第三方加密软件的组件冲突。最终通过卸载并重装yi赛通客户端解决问题。案例重点展示了如何通过系统日志定位进程崩溃的真实原因,强调当宿主进程(如Outlook)崩溃时,故障模块可能来自加载的第三方DLL,而非主程序本身。

分享 Windows 系统部署、镜像封装、终端管理、故障排查与运维自动化实践,涵盖 Sysinternals、PowerShell 和 AI 工具应用。记录真实问题、探索过程与解决方法,也分享 AI 时代的学习心得和实践经验,让技术更易理解 2万+

Outlook HTML渲染引擎

拉伸图片可能不会正确的渲染,所有的图形应该设置正确的尺寸在属性中。不要依赖于HTML定义图片尺寸这点对于Email很重要。

2503_92095625的博客 831

Outlook同步问题

买了新手机(Moto V220)后,有软件可以和Outlook数据库同步,很是高兴,后来接着就发现ArcGIS不能用,也许和此软件有关系,也许没有关系。 同步后,发现这个软件好像会修改、甚至部分损坏Outlook数据库,这点非常之不好。 其实Outlook同步并不是什么很难实现的技术,原来觉得复杂,现在想想,很简单,因为Office都是COM对象,这些COM对象创建后,就可以访...

weixin_30616969的博客 320

Outlook安全钩子控件Security Manager for Microsoft Outlook介绍和下载

Outlook Security Manager (全称 - Security Manager for Microsoft Outlook) 是一个单线程的编程工具,可以让你实现旁路安全设置,以及避免安全警告或快速附件和应用程序,其结合了 Microsoft Outlook. Outlook Security Manager 用于 .NET, VCL 以及 ActiveX 平台上的开发(VB.NE

控件选型需谨慎 1177

Outlook曝出安全漏洞,让用户难以分辨钓鱼邮件

Outlook用户在使用中发现,通过相似字母欺骗用户,能够让用户相信这些邮件来自于真正的联系人,攻击者能够利用此漏洞让用户确信邮件真实性,从而更容易发动钓鱼邮件攻击。 这个漏洞是通过相似字母的邮件地址,利用几乎同样的地址欺骗用户,使用户误以为邮件真实可靠。漏洞发现者举例说明了这一问题,因为西里尔字母在外观上与拉丁字母相似,如果一个公司的域名是'somecompany[.]com',一个注册了诸如' omecompany[.]com'(xn--omecompany-l2i[.]com)等国际域名的攻击者可以

互联网安全研究院 576

在outlook复制所有文件夹

outlook 邮件

呼格金贵 2131
上一篇: Javascript学习笔记17 高级技巧(函数绑定,柯里化,定时器)
下一篇: Javascript学习笔记19 离线应用和客户端存储
PAT-python-zjw
博客等级 码龄10年 381粉丝 408原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值