`
flyingis
  • 浏览: 297823 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

    译者: Flyingis 

    上一篇文章 介绍了移动页面元素所涉及到的捕获鼠标移动和鼠标点击的相关问题,本段文章将介绍如何移动和放置页面元素。

    移动元素

    我们现在已经知道如何捕获鼠标移动和点击。接下来需要做的就是移动任何我们想拖动的元素。首先,将一个元素准确移动到页面上我们想要的位置,该元素样式表的position值必须为absolute,这意味着你可以设置它的style.top或style.left,测量值相对于页面的左上角,因为我们所有的鼠标移动都是相对于页面左上角的,通常都是这样。

    一旦我们设置了item.style.position='absolute',接下来就需要改变该元素top和left的位置,使它移动!

document.onmousemove  =  mouseMove;
document.onmouseup   
=  mouseUp;

var  dragObject   =   null ;
var  mouseOffset  =   null ;

function  getMouseOffset(target, ev)  {
  ev 
=  ev  ||  window.event;

  
var  docPos  =  getPosition(target);
  
var  mousePos  =  mouseCoords(ev);

   
return   {x:mousePos.x  -  docPos.x, y:mousePos.y  -  docPos.y} ;
}


function  getPosition(e)  {
  
var  left  =   0 ;
  
var  top   =   0 ;

  
while  (e.offsetParent) {
    left 
+=  e.offsetLeft;
    top 
+=  e.offsetTop;
    e 
=  e.offsetParent;
  }


  left 
+=  e.offsetLeft;
  top 
+=  e.offsetTop;

  
return   {x:left, y:top} ;
}


function  mouseMove(ev)  {
  ev 
=  ev  ||  window.event;
  
var  mousePos  =  mouseCoords(ev);

  
if  (dragObject)  {
    dragObject.style.position 
=  'absolute';
    dragObject.style.top 
=  mousePos.y  -  mouseOffset.y;
    dragObject.style.left 
=  mousePos.x  -  mouseOffset.x;
    
return   false ;
  }

}


function  mouseUp()  {
  dragObject 
=   null ;
}


function  makeDraggable(item)  {
  
if  ( ! item)  return ;
  item.onmousedown 
=   function (ev)  {
    dragObject  
=   this ;
    mouseOffset 
=  getMouseOffset( this , ev);
    
return   false ;
  }

}

    你会注意到这些代码是以我们前面的例子为基础的(参考上篇文章),将它们放置在一起,你将能够随意的去移动元素。

    当我们点击一个元素时,存储了另外的一个变量,mouseOffset。mouseOffset简单的包含了我们点击元素的位置信息。如果我们有一张20*20px的图像,然后点击图像的中间,mouseOffset应该是{x:10, y:10}。如果我们点击图像的左上角,mouseOffset应为{x:0, y:0}。我们在鼠标移动后的位置信息中用到它。如果我们没有存储这个值,不论你点击元素的哪一个位置,元素相对于鼠标的位置都将会是相同的。

    mouseOffset函数用到了另外一个函数getPosition。getPosition目的是返回元素相对于documemt文档的坐标位置。如果我们简单的去读取item.offsetLeft或item.style.left,得到的将是元素相对于它父元素的位置,而不是document文档的。在我们的脚本中,所有的元素都是相对于document文档的,因此需要这样做。

    要完成获取元素相对于document文档位置的工作,getPosition从它自身的父级开始,循环获取它的left和top的值并累加,这样我们就得到了我们想要的元素距文档顶部和左侧的累计值。

    当我们获取了这条信息并移动鼠标的时候,mouseMove开始运行。首先我们需要保证item.style.position值为absolute,接着,我们将元素移动到任何一个地方,鼠标位置都会减去我们之前记录的鼠标相对于元素的偏移量。当鼠标释放时,dragObject将被设置为null,并且mouseMove函数不再做任何事情。

    放置元素

    我们前面的例子已经处理了这个问题,仅仅是拖动一个元素,然后将它放下。然后,在我们放下元素的时候通常还有其他的目的,我们以拖动元素到垃圾回收站为例,或我们可能想让该元素和页面中某个特定的区域对齐。

    不幸的是我们在这里进入了一个相对主要的问题。因为我们正在移动的元素总是直接处于我们的鼠标下,而不可能去引发mouseover、mousedown、mouseup或鼠标对页面中其他元素的操作。如果你移动一个元素到垃圾回收站,你的鼠标会一直在移动元素的上方,而不是垃圾回收站。

    那么我们该如何处理这个问题呢?这里有几种解决方案。在前面所提到的mouseOffset的目的是保证元素总是在鼠标下方正确的位置,如果你忽视了这点,然后总是使得元素在鼠标的右下方,你的鼠标将不会被你正在拖动的元素所隐藏,我们也不会碰到问题。但事实上往往不会这样,为了美观我们通常要保持元素在鼠标的下方。

    另外一种选择是不移动你正在拖动的元素,你可以改变鼠标样式,来告诉使用者你正在拖动一个元素,直到你将它放置到某个地方。这解决了我们的问题,但是带来了和前面一种方案面临的同样问题:美观。

    我们最后的一种解决方案既不影响你正在移动的元素,也不影响移动终点位置上的元素(例如垃圾回收站)。不幸的是,这比前面两种解决方案的难度更大。我们将要做的是获得一组我们要放置的目标,当鼠标释放时,我们手工检查当前鼠标相对于每个目标的位置,看鼠标是否释放在这个目标中某一个目标的位置上,如果是的,我们就知道我们已经将元素放置在我们的目标上了。

/**/ /*
All code from the previous example is needed with the exception
of the mouseUp function which is replaced below
*/


var  dropTargets  =  [];

function  addDropTarget(dropTarget)  {
  dropTargets.push(dropTarget);
}


function  mouseUp(ev)  {
  ev 
=  ev  ||  window.event;
  
var  mousePos  =  mouseCoords(ev);

  
for  ( var  i = 0 ; i < dropTargets.length; i ++ {
    
var  curTarget  =  dropTargets[i];
    
var  targPos  =  getPosition(curTarget);
    
var  targWidth  =  parseInt(curTarget.offsetWidth);
    
var  targHeight  =  parseInt(curTarget.offsetHeight);

    
if  (
      (mousePos.x 
>  targPos.x)  &&  
      (mousePos.x 
<  (targPos.x  +  targWidth))  &&  
      (mousePos.y 
>  targPos.y)  &&  
      (mousePos.y 
<  (targPos.y  +  targHeight)))  {
      
//  dragObject was dropped onto curTarget!
      }

  }


  dragObject   
=   null ;
}

    这个例子中当鼠标释放时,我们循环每个可能放置元素的目标,如果鼠标指针在目标上,我们则拥有了一个放置元素的事件,通过鼠标横坐标大于目标元素左侧横坐标(mousePos.x>targPos.x),小于目标元素右侧横坐标(mousePos.x<(targPos.x+targWidth))来判定,对于Y坐标我们做同样的判断。如果所有的这些值都返回true,那么我们的鼠标就是在目标元素的范围内。

    原文链接:http://www.webreference.com/programming/javascript/mk/column2/2.html

    另外两篇:[翻译] 如何在 JavaScript 中实现拖放(上)   [翻译] 如何在 JavaScript 中实现拖放(下)

分享到:
评论

相关推荐

    ExtJS4官方指南翻译:DragandDrop拖放/Grid组件/Tree组件/容器与布局

    在"ExtJS4官方指南翻译:DragandDrop拖放/Grid组件/Tree组件/容器与布局"中,我们将会探讨以下几个核心概念: 1. **Drag and Drop(拖放)**: ExtJS4提供了完善的拖放支持,允许用户通过鼠标操作在界面上移动元素...

    react-Reactjs漂亮可移植性列表拖拽库文档中文翻译

    这个库专注于易用性、性能和无障碍性,使得在React应用中实现拖放操作变得简单而优雅。 `react-beautiful-dnd`的设计目标是提供一种直观的方式,让用户可以通过鼠标或触摸设备轻松地重新排序列表项目。它支持各种...

    jquery easyui 翻译

    在电商应用中,实现类似购物车的拖放功能是常见的需求。以下展示了如何创建一个简单的购物车: ```html &lt;!-- 产品列表 --&gt; &lt;!-- 购物车内容 --&gt; ``` 产品列表由 `ul` 元素中的 `li` 元素表示,每个产品包括...

    ASP.NET客户关系管理系统的实现(源代码+文献综述+外文翻译+答辩PPT).rar

    在这个“ASP.NET客户关系管理系统的实现”项目中,开发者利用ASP.NET技术来设计并实现了客户关系管理系统(CRM),这是一套用于企业管理和维护客户关系的重要工具。 CRM系统的主要目标是通过收集、分析、组织和利用...

    翻译翻译什么叫HTML5(一)配套代码资源包

    10. **拖放功能**:HTML5的拖放API使得用户可以方便地在网页元素之间拖放内容,无需复杂的JavaScript实现。 这个资源包可能包含了这些功能的实例代码,帮助开发者了解和学习如何在实际项目中应用HTML5。通过`code1`...

    基于ASP.NET的客户关系管理项目设计与实现(项目报告+源代码+文献综述+外文翻译+答辩PPT).zip

    4. **AJAX(Asynchronous JavaScript and XML)**:ASP.NET支持AJAX,允许创建异步的、部分刷新的用户界面,提高用户体验,特别是在数据密集型的CRM系统中。 5. **安全性**:ASP.NET内置的安全特性包括身份验证、...

    翻译翻译什么叫HTML5(四)配套资源

    在本资源包“翻译翻译什么叫HTML5(四)配套资源”中,很可能包含了关于HTML5的深入讲解、示例代码、教程或者相关练习,帮助用户更好地理解和掌握这一技术。 HTML5的核心特性包括: 1. **语义化标签**:HTML5引入了...

    react-dnd-in-chinese:react-dnd 中文文档

    React DND(Drag and Drop)中文文档主要涵盖了在React应用中实现拖放功能的相关知识点。React DND是一个流行的JavaScript库,它使得在React组件中添加拖放行为变得简单且直观。下面将详细介绍这个库的核心概念、...

    ASP.NET网络商店设计与实现(源代码)

    此外,HTML、CSS和JavaScript也是构建UI不可或缺的部分,开发者可能利用Bootstrap或自定义CSS来实现响应式布局,确保商店界面在不同设备上都能良好展示。 数据库管理是任何电子商务系统的基础。ASP.NET通常与SQL ...

    ext2.0中文语言包gb2312格式

    这个文件包含了所有EXT JS组件和方法的中文翻译,通过在应用程序中引用这个文件,可以将EXT JS的默认英文界面转换为中文。使用时,开发者通常会在EXT JS的初始化代码中指定这个语言文件,例如: ```javascript Ext....

    js弹出可拖动计算器代码.zip

    该压缩包"js弹出可拖动计算器代码.zip"包含了一个实用的JavaScript实现的可拖动计算器代码。这个计算器不仅能够进行基本的计算操作,还具有动态效果和用户交互功能,使得它在网页中可以作为一个方便的小工具使用。...

    Jquery周历插件weekCalendar汉化并实现单日显示

    在Web开发中,日历插件是一种常见的用户交互元素,尤其对于日程管理、时间预约等应用场景尤为重要。jQuery WeekCalendar是一款强大的周历插件,它允许用户直观地查看和管理一周的日程。本文将详细介绍如何对这个插件...

    网站建设技术外文翻译

    在网站中应用CSS,可实现页面的统一风格,提升视觉效果。 #### 3.2 应用JavaScript设计网页 JavaScript是一种脚本语言,它的出现让网页从静态展示转变为动态交互,增强了用户体验。通过JavaScript,网页可以实时...

    Activiti流程设计汉化

    在国际化(i18n)开发中,这种JSON文件通常用于存储不同语言环境下的字符串资源,便于程序根据用户设置的语言加载相应的翻译。通过修改和更新en.json,开发者或用户可以实现Activiti界面的中文显示,使得中国用户...

    ASP.NET小型证券术语解释及翻译系统的设计与开发(源代码+论文).rar

    2. **Web Forms**:在这个项目中,可能使用了Web Forms模式,这是一种基于控件的模型,允许开发者通过拖放控件来创建用户界面,类似于Windows桌面应用的开发体验。 3. **C#编程**:ASP.NET通常使用C#作为后端编程...

    FullCalendar的使用demo

    - 可能还有其他配置或扩展脚本,如日程拖放、资源管理等功能的实现。 5. **初始化和配置**: 在HTML文件中,你需要通过JavaScript来初始化FullCalendar。配置项可以调整全历的外观、行为和数据源。例如,设置`...

    extjs3.3 中文文档

    虽然标题提到的是3.3版本,但很可能是文档更新到3.2版本时的中文翻译,而3.3的更新可能在英文版中。CHM文件是Windows系统的帮助文档格式,包含索引、搜索和目录等功能,方便用户查找和学习。 下面将详细讲解ExtJS ...

    Ext Designer+中文补丁+代码生成补丁

    在使用这个资源包时,首先需要安装Ext Designer,然后应用中文补丁以实现本地化,最后利用代码生成补丁将设计结果导出为实际的代码。这样,即使是对Ext JS不太熟悉的开发者,也能借助这个工具快速上手并创建出高质量...

    ext(extJS) 3.0 中文API CHM版 ext中文帮助文档

    EXTJS是一个基于JavaScript的开源富客户端框架,专为构建交互式Web应用程序而设计。EXTJS 3.0是EXTJS的一个重要版本,提供了丰富的组件库和强大的数据绑定机制,使得开发者能够创建功能丰富的桌面级应用。EXTJS 3.0...

Global site tag (gtag.js) - Google Analytics