JS基于面向对象实现的拖拽库实例

JavaScript07

JS基于面向对象实现的拖拽库实例,第1张

本文实例讲述了JS基于面向对象实现的拖拽库。分享给大家供大家参考。具体如下:

这是一个面向对象的JS拖拽库,可设置水平锁定、垂直锁定、锁定位置、锁定范围等,设定这些范围后,只能在设定的模式下拖动,我觉得这是个挺不错的拖拽实例。

运行效果截图如下:

在线演示地址如下:

http://demo.jb51.net/js/2015/js-mxdx-draw-plug-codes/

具体代码如下:

<!DOCTYPE

html

PUBLIC

"-//W3C//DTD

XHTML

1.0

Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html

xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta

http-equiv="Content-Type"

content="text/html

charset=utf-8"

/>

<title>拖拽库</title>

<style

type="text/css">

div,h2,p{margin:0padding:0}

body{font:14px/1.5

arial}

#box{width:100pxheight:100pxbackground:#fef4ebpadding:5pxmargin:50pxborder:1px

solid

#f60}

#box

.title{height:25pxbackground:#f60}

#tool{margin-bottom:10px}

</style>

<script

type="text/javascript">

function

Drag()

{

//初始化

this.initialize.apply(this,

arguments)

}

Drag.prototype

=

{

//初始化

initialize

:

function

(drag,

options)

{

this.drag

=

this.$(drag)

this._x

=

this._y

=

0

this._moveDrag

=

this.bind(this,

this.moveDrag)

this._stopDrag

=

this.bind(this,

this.stopDrag)

this.setOptions(options)

this.handle

=

this.$(this.options.handle)

this.maxContainer

=

this.$(this.options.maxContainer)

this.maxTop

=

Math.max(this.maxContainer.clientHeight,

this.maxContainer.scrollHeight)

-

this.drag.offsetHeight

this.maxLeft

=

Math.max(this.maxContainer.clientWidth,

this.maxContainer.scrollWidth)

-

this.drag.offsetWidth

this.limit

=

this.options.limit

this.lockX

=

this.options.lockX

this.lockY

=

this.options.lockY

this.lock

=

this.options.lock

this.onStart

=

this.options.onStart

this.onMove

=

this.options.onMove

this.onStop

=

this.options.onStop

this.handle.style.cursor

=

"move"

this.changeLayout()

this.addHandler(this.handle,

"mousedown",

this.bind(this,

this.startDrag))

},

changeLayout

:

function

()

{

this.drag.style.top

=

this.drag.offsetTop

+

"px"

this.drag.style.left

=

this.drag.offsetLeft

+

"px"

this.drag.style.position

=

"absolute"

this.drag.style.margin

=

"0"

},

startDrag

:

function

(event)

{

var

event

=

event

||

window.event

this._x

=

event.clientX

-

this.drag.offsetLeft

this._y

=

event.clientY

-

this.drag.offsetTop

this.addHandler(document,

"mousemove",

this._moveDrag)

this.addHandler(document,

"mouseup",

this._stopDrag)

event.preventDefault

&&

event.preventDefault()

this.handle.setCapture

&&

this.handle.setCapture()

this.onStart()

},

moveDrag

:

function

(event)

{

var

event

=

event

||

window.event

var

iTop

=

event.clientY

-

this._y

var

iLeft

=

event.clientX

-

this._x

if

(this.lock)

return

this.limit

&&

(iTop

<

0

&&

(iTop

=

0),

iLeft

<

0

&&

(iLeft

=

0),

iTop

>

this.maxTop

&&

(iTop

=

this.maxTop),

iLeft

>

this.maxLeft

&&

(iLeft

=

this.maxLeft))

this.lockY

||

(this.drag.style.top

=

iTop

+

"px")

this.lockX

||

(this.drag.style.left

=

iLeft

+

"px")

event.preventDefault

&&

event.preventDefault()

this.onMove()

},

stopDrag

:

function

()

{

this.removeHandler(document,

"mousemove",

this._moveDrag)

this.removeHandler(document,

"mouseup",

this._stopDrag)

this.handle.releaseCapture

&&

this.handle.releaseCapture()

this.onStop()

},

//参数设置

setOptions

:

function

(options)

{

this.options

=

{

handle:

this.drag,

//事件对象

limit:

true,

//锁定范围

lock:

false,

//锁定位置

lockX:

false,

//锁定水平位置

lockY:

false,

//锁定垂直位置

maxContainer:

document.documentElement

||

document.body,

//指定限制容器

onStart:

function

()

{},

//开始时回调函数

onMove:

function

()

{},

//拖拽时回调函数

onStop:

function

()

{}

//停止时回调函数

}

for

(var

p

in

options)

this.options[p]

=

options[p]

},

//获取id

$

:

function

(id)

{

return

typeof

id

===

"string"

?

document.getElementById(id)

:

id

},

//添加绑定事件

addHandler

:

function

(oElement,

sEventType,

fnHandler)

{

return

oElement.addEventListener

?

oElement.addEventListener(sEventType,

fnHandler,

false)

:

oElement.attachEvent("on"

+

sEventType,

fnHandler)

},

//删除绑定事件

removeHandler

:

function

(oElement,

sEventType,

fnHandler)

{

return

oElement.removeEventListener

?

oElement.removeEventListener(sEventType,

fnHandler,

false)

:

oElement.detachEvent("on"

+

sEventType,

fnHandler)

},

//绑定事件到对象

bind

:

function

(object,

fnHandler)

{

return

function

()

{

return

fnHandler.apply(object,

arguments)

}

}

}

//应用

window.onload

=

function

()

{

var

oBox

=

document.getElementById("box")

var

oTitle

=

oBox.getElementsByTagName("h2")[0]

var

oSpan

=

document.getElementsByTagName("span")[0]

var

oDrag

=

new

Drag(oBox,

{handle:oTitle,

limit:false})

var

aInput

=

document.getElementsByTagName("input")

//锁定范围接口

aInput[0].onclick

=

function

()

{

oDrag.limit

=

!oDrag.limit

this.value

=

oDrag.limit

?

"取消锁定范围"

:

"锁定范围"

}

//水平锁定接口

aInput[1].onclick

=

function

()

{

oDrag.lockX

=

!oDrag.lockX

this.value

=

oDrag.lockX

?

"取消水平锁定"

:

"水平锁定"

}

//垂直锁定接口

aInput[2].onclick

=

function

()

{

oDrag.lockY

=

!oDrag.lockY

this.value

=

oDrag.lockY

?

"取消垂直锁定"

:

"垂直锁定"

}

//锁定位置接口

aInput[3].onclick

=

function

()

{

oDrag.lock

=

!oDrag.lock

this.value

=

oDrag.lock

?

"取消锁定位置"

:

"锁定位置"

}

//开始拖拽时方法

oDrag.onStart

=

function

()

{

oSpan.innerHTML

=

"开始拖拽"

}

//开始拖拽时方法

oDrag.onMove

=

function

()

{

oSpan.innerHTML

=

"left:"

+

this.drag.offsetLeft

+

",

top:"

+

this.drag.offsetTop

}

//开始拖拽时方法

oDrag.onStop

=

function

()

{

oSpan.innerHTML

=

"结束拖拽"

}

}

</script>

</head>

<body>

<div

id="tool">

<input

type="button"

value="锁定范围"

/>

<input

type="button"

value="水平锁定"

/>

<input

type="button"

value="垂直锁定"

/>

<input

type="button"

value="锁定位置"

/>

</div>

<p>拖放状态:<span>未开始</span></p>

<div

id="box">

<h2

class="title"></h2>

</div>

</body>

</html>

希望本文所述对大家的JavaScript程序设计有所帮助。

这是一个真实的例子,展示了三种最常见的编程范式的差异。我将用三种不同的方式解决一个问题。

每个示例将处理表单提交、验证用户输入并将创建的用户打印到控制台。我还添加了保存错误记录器。

案例表单

简单的 HTML 登录表单,它将包含三个js不同范式的有效文件。

过程化编程

过程式编程只是一步一步地解决问题。这是完全有效的编码方式,但是当您希望应用程序扩展时它有许多缺点。

简单一步一步解决问题。但它根本不可重用和可扩展。尽管它对于解决此类问题完全有效,并且您将看到它比其他问题要短得多。

面向对象编程

面向对象编程 ( OOP ) 是最接近现实世界的,因此很容易让您思考。我们查看将其划分为Object的代码,其中每个都只完成它的工作。在OOP 中学习的有用概念是SOLID。

现在你可以明白我将问题划分为Objects 的意思了:

正如你所看到的,有更多的代码,看起来更复杂……那么为什么有人会喜欢这个?

酷的是,现在我们可以将它用于任何类似的形式,只需调用:

因此,它可以在包含此脚本的每个文件中重复使用。而且它很容易扩展,因为一切都被分成只做一件事的块(单一责任原则)。

函数式编程

非常流行,而且非常简单。请注意,这并不意味着它无论如何都更好。尽管某些范例可能对某些问题更好,但使用哪个完全取决于您。

正如您在 函数式编程 中看到的,我们希望使用小的(理想情况下是纯函数)函数来解决问题。这种方法也非常具有可 扩展性 ,并且函数可以重用。

纯函数是一种没有难以追踪的副作用的函数。纯函数应该只依赖于给定的参数。

结论

没有更好和更坏的范式。有经验的开发人员可以看到每个的优点,并为给定的问题选择最好的。

过程式编程并不是说你不能使用函数,函数式编程也不会阻止你使用“类”。这些范式只是帮助以一种随着代码增长而有益的方式来解决问题。

函数式编程 vs 面向对象编程 vs 过程式编程的JS演示比较 - DEV