拖曳原理:

元素的初始位置 + 鼠标距离差 = 元素最终位置

  • 使元素可以拖动

    • function dragElement(obj){
      obj.onmousedown = function(e){
      e = e || window.event; // 兼容 IE obj.setCapture && obj.setCapture(); // 只有 IE 支持,处理 IE8 ctrl+A // 鼠标初始坐标
      var mouseX = e.clientX;
      var mouseY = e.clientY; // 元素初始坐标
      var eleX = obj.offsetLeft;
      var eleY = obj.offsetTop; document.onmousemove = function(e){
      e = e || window.event; // 鼠标新坐标
      var newMouseX = e.clientX;
      var newMouseY = e.clientY; // 元素的新坐标 = 元素初始坐标+(鼠标新坐标-鼠标初始坐标)
      obj.style.left = eleX + newMouseX - mouseX +"px";
      obj.style.top = eleY + newMouseY - mouseY + "px";
      }; document.onmouseup = function(){
      document.onmousemove = null;
      document.onmouseup = null; obj.releaseCapture && obj.releaseCapture();
      }; e.preventDefault && e.preventDefault();
      return false; // 处理高级浏览器 ctrl+A
      };
      };

拖曳: 范围限定

超出临界值,令其等于临界值

  • 上侧临界值 = 0;
  • 右侧临界值 = 视窗 width - ele.offsetWidth;
  • 下侧临界值 = 视窗 height - ele.offsetHeight;
  • 左侧临界值 = 0;

九宫格碰撞检测

  • ele.offsetLeft 或者 ele.offsetTop

    • 获取的是 元素在 包含块 中的坐标
  • ele.getBoundingClientRect();

    • 获取元素在视窗中的坐标(由该 元素.getClientRects() 返回的一组矩形集合)
  • function dragRangeAround(obj, borderRange, badObj){    // 要拖动的元素,吸附范围,磁性盒子
    borderRange = borderRange || 0;
    obj.onmousedown = function(e){
    e = e || window.event; obj.setCapture && obj.setCapture(); // 只有 IE 支持,处理 IE8 ctrl+A var mouseX = e.clientX;
    var mouseY = e.clientY; var eleX = obj.offsetLeft;
    var eleY = obj.offsetTop; var cDir = "noCollision";
    document.onmousemove = function(e){
    e = e || window.event; var newMouseX = e.clientX;
    var newMouseY = e.clientY; fixedX = eleX + newMouseX - mouseX;
    fixedY = eleY + newMouseY - mouseY; var objBorder = obj.style.border && parseInt(obj.style.border);
    if(fixedX < borderRange){
    fixedX = 0;
    }else if(fixedX > (document.documentElement.clientWidth-obj.offsetWidth-borderRange)){
    fixedX = document.documentElement.clientWidth-obj.offsetWidth-objBorder*2;
    } if(fixedY < borderRange){
    fixedY = 0;
    }else if(fixedY > (document.documentElement.clientHeight-obj.offsetHeight-borderRange)){
    fixedY = document.documentElement.clientHeight-obj.offsetHeight-objBorder*2;
    }
    obj.style.left = fixedX + "px";
    obj.style.top = fixedY + "px"; /**** start 碰撞检测 ****/
    if(badObj){
    var isCollision = false; var badTop = badObj.getBoundingClientRect().top;
    var badRight = badObj.getBoundingClientRect().right;
    var badBottom = badObj.getBoundingClientRect().bottom;
    var badLeft = badObj.getBoundingClientRect().left; var objRight = obj.getBoundingClientRect().right;
    var objLeft = obj.getBoundingClientRect().left;
    var objBottom = obj.getBoundingClientRect().bottom;
    var objTop = obj.getBoundingClientRect().top; if( objRight < badLeft){
    cDir = "left";
    if( objRight > (badLeft-borderRange) &&
    objBottom > badTop && objTop < badBottom){
    obj.style.left = badLeft - obj.offsetWidth + "px";
    }
    }else if( objLeft > badRight ){
    cDir = "right";
    if( objLeft < (badRight+borderRange) &&
    objBottom > badTop && objTop < badBottom){
    obj.style.left = badRight + "px";
    }
    }else if( objBottom < badTop){
    cDir = "top";
    if( objBottom > (badTop-borderRange) &&
    objRight > badLeft && objLeft < badRight){
    obj.style.top = badTop - obj.offsetHeight + "px";
    }
    }else if( objTop > badBottom ){
    cDir = "bottom";
    if( objTop < (badBottom+borderRange) &&
    objRight > badLeft && objLeft < badRight){
    obj.style.top = badBottom + "px";
    }
    }else{
    isCollision = true;
    } if(isCollision){
    badObj.innerHTML = cDir+"in's business";
    }else{
    badObj.innerHTML = cDir+"out's business";
    }
    }
    /**** over ****/
    }; document.onmouseup = function(){
    document.onmousemove = null;
    document.onmouseup = null; obj.releaseCapture && obj.releaseCapture();
    }; e.preventDefault && e.preventDefault();
    return false; // 处理高级浏览器 ctrl+A
    };
    return obj;
    };

自定义滚动条

  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>自定义滚动条</title> <style type="text/css">
    body {
    width: 100%;
    color: #000;
    background: #96b377;
    font: 14px Helvetica, Arial, sans-serif;
    } html,
    body {
    height: 100%;
    overflow: hidden;
    } #things {
    position: absolute;
    top: 0px;
    left: 0px;
    font-size: 27px;
    font-weight: 700;
    color: #210202;
    padding-right: 40px;
    } /**** DIY Scroll ****/
    #diy_scroll_box{
    position: fixed;
    top: 0px;
    right: 0px;
    z-index: 7777; width: 40px;
    height: 100%;
    background-color: #eee;
    } #diy_scroll {
    position: absolute;
    top: 0px;
    left: 0px;
    z-index: 8888; width: 100%;
    height: 20%;
    background-color: #949494;
    } #diy_scroll:hover {
    background-color: #c0c0c0;
    } /**** 上下按键 ****/
    #scroll_up_btn,
    #scroll_down_btn {
    position: absolute;
    z-index: 9999; width: 40px;
    height: 40px;
    background-color: #456;
    } #scroll_up_btn {
    top: 0px;
    right: 0px;
    } #scroll_down_btn {
    bottom: 0px;
    right: 0px;
    } #scroll_up{
    position: absolute;
    top: -10px; border: 20px solid red;
    border-top: 20px solid #f000;
    border-right: 20px solid #f000;
    border-left: 20px solid #f000;
    border-bottom-color: #b3e4aa;
    } #scroll_down{
    position: absolute;
    top: 10px; border: 20px solid red;
    border-bottom: 20px solid #f000;
    border-right: 20px solid #f000;
    border-left: 20px solid #f000;
    border-top-color: #b3e4aa;
    } #scroll_up:hover {
    border-bottom-color: #c5ffbb;
    } #scroll_down:hover {
    border-top-color: #c5ffbb;
    } </style>
    </head> <body> <div id="diy_scroll_box">
    <div id="scroll_up_btn">
    <div id="scroll_up">
    </div>
    </div> <div id="diy_scroll">
    </div> <div id="scroll_down_btn">
    <div id="scroll_down">
    </div>
    </div>
    </div> <div id="things">
    <pre> 姓名:朱元璋别名(外号):朱重八、朱国瑞   性别:男   民族:汉   血型:?   学历:无文凭,秀才举人进士统统的不是,后曾自学过   职业:皇帝   家庭出身:(至少三代)贫农   生卒:1328-1398   最喜欢的颜色:黄色(这个好像没得选)   社会关系:   父亲:朱五四,农民   母亲:陈氏,农民(不好意思,史书中好像没有她的名字)   座右铭:你的就是我的,我还是我的   主要经历:   1328年-1344年放牛   1344年-1347年做和尚,主要工作是出去讨饭(这个……)   1347年-1352年做和尚主要工作是撞钟   1352年-1368年造反(这个猛)   1368年-1398年主要工作是做皇帝   一切的事情都从1328年的那个夜晚开始,农民朱五四的妻子陈氏生下了一个男婴,
    大家都知道了,这个男婴就是后来的朱元璋。
    大凡皇帝出世,后来的史书上都会有一些类似的怪象记载。   比如刮风啊,下暴雨啊,冒香气啊,天上星星闪啊,到处放红光啊
    ,反正就是要告诉你,这个人和别人不一样。
    朱元璋先生也不例外,他出生时,红光满地,夜间房屋中出现异光,以致于邻居以为失
    火了,跑来相救(明实录)。
    </pre>
    </div> <!-- javascript 代码 -->
    <script type="text/javascript">
    var things = document.getElementById("things"); /**** DIY Scroll ****/
    var diyScroll = document.getElementById("diy_scroll");
    var btnHeight = 40;
    diyScroll.style.top = btnHeight+"px"; var diyScrollHeight = document.documentElement.clientHeight-btnHeight*2;
    var thingsScrollHeight = things.offsetHeight-document.documentElement.clientHeight; barHeight = diyScrollHeight*(document.documentElement.clientHeight)/things.offsetHeight;
    diyScroll.style.height = barHeight +"px"; var contentStartTop = 0;
    var mouseStartY = 0;
    var barStartY = 0; /**** 点击滑块 ****/
    diyScroll.onmousedown = function(e){
    e = e || window.event; diyScroll.setCapture && diyScroll.setCapture(); mouseStartY = e.clientY;
    barStartY = diyScroll.offsetTop;
    contentStartTop = things.offsetTop; document.onmousemove = function(e){
    e = e || window.event; var mouseEndY = e.clientY;
    var barEndY = barStartY + mouseEndY - mouseStartY; if(barEndY < btnHeight){
    barEndY = btnHeight;
    }else if(barEndY > (document.documentElement.clientHeight - btnHeight - diyScroll.offsetHeight)){
    barEndY = document.documentElement.clientHeight - btnHeight - diyScroll.offsetHeight;
    } diyScroll.style.top = barEndY+"px";
    things.style.top = contentStartTop + -thingsScrollHeight*(barEndY-barStartY)/(diyScrollHeight-barHeight) +"px";
    }; document.onmouseup = function(){
    document.onmousemove = null;
    document.onmouseup = null;
    diyScroll.releaseCapture && diyScroll.releaseCapture();
    } e.preventDefault && e.preventDefault();
    return false;
    }; document.onmousewheel = scrollWheelFunc;
    document.addEventListener && document.addEventListener("DOMMouseScroll", scrollWheelFunc, false);
    /**** 滚轮事件 ****/
    function scrollWheelFunc(e){
    e = e || window.event; var wheelDir = 0;
    var shouldMove = 5; if(e.wheelDelta){
    wheelDir = (e.wheelDelta>0)?"up":"down";
    shouldMove = (e.wheelDelta>0)?(-5):5;
    }else if(e.detail){
    wheelDir = (e.detail>0)?"down":"up";
    shouldMove = (e.detail>0)?5:(-5);
    }; var barTop = diyScroll.offsetTop;
    var barOffset = barTop; barTop += shouldMove; if(barTop < btnHeight){
    barTop = btnHeight;
    }else if(barTop > (document.documentElement.clientHeight - btnHeight - diyScroll.offsetHeight)){
    barTop = document.documentElement.clientHeight - btnHeight - diyScroll.offsetHeight;
    }; diyScroll.style.top = barTop+"px"; barOffset = barOffset - barTop; contentStartTop = things.offsetTop;
    things.style.top = contentStartTop + thingsScrollHeight*barOffset/(diyScrollHeight-barHeight) +"px"; e.preventDefault && e.preventDefault();
    return false;
    }; /**** 点击按键 ****/
    var scrollDown = document.getElementById("scroll_down_btn");
    var scrollUp = document.getElementById("scroll_up_btn");
    scrollUp.onclick = function(){
    scrollBtnFunc(-5);
    }
    scrollDown.onclick = function(){
    scrollBtnFunc(5);
    } function scrollBtnFunc(barOffset){
    var barTop = diyScroll.offsetTop; if((barTop+barOffset) < btnHeight){
    barOffset = btnHeight - barTop;
    }else if((barTop+barOffset) > (document.documentElement.clientHeight - btnHeight - diyScroll.offsetHeight)){
    barOffset = document.documentElement.clientHeight - btnHeight - diyScroll.offsetHeight - barTop;
    };
    diyScroll.style.top = barTop+barOffset+"px"; contentStartTop = things.offsetTop;
    things.style.top = contentStartTop + -thingsScrollHeight*barOffset/(diyScrollHeight-barHeight) +"px"; }
    </script>
    </body>
    </html>

CSS3_元素拖曳原理_设置全局点击捕获_九宫格碰撞检测_自定义滚动条的更多相关文章

  1. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  2. spring设置全局异常处理器

    1.spring设置全局异常,它的原理是向上捕获 spring.xml配置 <!--自定义全局异常处理器--> <bean id="globalExceptionResol ...

  3. 在.NET Core程序中设置全局异常处理

    以前我们想设置全局异常处理只需要这样的代码: AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledExc ...

  4. pages 元素(ASP.NET 设置架构)web.config 详解

    pages 元素(ASP.NET 设置架构)    buffer="[True|False]"   enableEventValidation="[True|False] ...

  5. compilation 元素(ASP.NET 设置架构)

    配置 ASP.NET 用于编译应用程序的所有编译设置. <configuration> 元素  system.web 元素(ASP.NET 设置架构)    compilation 元素( ...

  6. CSS实现元素居中原理解析

    在 CSS 中要设置元素水平垂直居中是一个非常常见的需求了.但就是这样一个从理论上来看似乎实现起来极其简单的,在实践中,它往往难住了很多人. 让元素水平居中相对比较简单:如果它是一个行内元素,就对它的 ...

  7. drf框架中认证与权限工作原理及设置

    0909自我总结 drf框架中认证与权限工作原理及设置 一.概述 1.认证 工作原理 返回None => 游客 返回user,auth => 登录用户 抛出异常 => 非法用户 前台 ...

  8. roleManager 元素(ASP.NET 设置架构),我是因为SSL弱密码(转)

    为角色管理配置应用程序. 此元素是 .NET Framework 2.0 版中的新元素. configuration 元素(常规设置架构)  system.web 元素(ASP.NET 设置架构)   ...

  9. authorization 元素(ASP.NET 设置架构)

    authorization 元素(ASP.NET 设置架构) 其他版本 1(共 1)对本文的评价是有帮助 - 评价此主题 [本文档仅供预览,在以后的发行版中可能会发生更改.包含的空白主题用作占位符.] ...

随机推荐

  1. 源码来袭:bind手写实现

    JavaScript中的this指向规则 源码来袭:call.apply手写实现与应用 理解建议:如果对this指向规则不了解的话,建议先了解this指向规则,最好还能对call和apply的使用和内 ...

  2. 抓包工具Charles基本用法

    我们在进行B/S架构的Web项目开发时,在前端页面与后台交互的调试的时候,通常使用在JSP中加入“debugger;”断点,然后使用浏览器的F12开发者工具来查看可能出错的地方的数据.或者使用Http ...

  3. Python系列之 - 前端总结

    1. python序列化: 字符串 = json.dumps(对象) 对象->字符串 对象 = json.loads(字符串) 字符串->对象 Javascript: 字符串 = JSON ...

  4. 解决Ubuntu 17.10设置面板打不开的问题

    问题描述 对于Ubuntu桌面系统我用得不多,最近安装了Ubuntu17.10使用,一直都没遇到什么大的问题,界面风格已经与Windows很相似,总体体验还不错.直到某一天我突然手痒痒把Dock面板从 ...

  5. sql server 2008怎样导入mdf,ldf文件,怎样解决导入mdf,ldf文件时出现附加数据库错误的问题

    废话不多说,直入主题吧. 1:打开sql server 2008,右键数据库-->附加 2:这时出现这个界面点击添加 3:打开数据库实例的安装目录,打开DATA文件夹;(如我的实例目录地址为:D ...

  6. 请求超时VUE axios重新再次请求

    //在main.js设置全局的请求次数,请求的间隙 axios.defaults.retry = 4; axios.defaults.retryDelay = 1000; axios.intercep ...

  7. Executors的四种线程池

    Executors.newCachedThreadPool(); Executors.newFixedThreadPool(2); Executors.newScheduledThreadPool(2 ...

  8. Vs2013 使用EF6 连接mysql数据库

    最近在使用MySQL数据库,在使用EF框架连接MySQL数据库时发现了一个问题,使用DB First创建实体对象的时候会出现如下图的错误:您的项目引用了最新版实体框架….. (如下图)或者会出现新建实 ...

  9. Nginx location 正则篇

    location 前缀 没有前缀               匹配以指定模式开头的location =                          精准匹配,不是以指定模式开头 ~       ...

  10. web页面实现文件下载的几种方法

    今天碰到文件下载的一些问题,本着知其然也要知其所以然的精神,站在巨人的肩膀上深入学习和测试了一下,抛砖引玉,现在总结结论如下: 1)标准URL下载方式可以通过在web页面中嵌入 url超级链接,标准的 ...