This is a JavaScript library that lets you easily implement user-friendly and customisable dragging and resizing of your page elements.
Добавил: Amro Дата: 05.11.2014 12:22
Добавил: Amro Дата: 05.11.2014 12:22
This is a JavaScript library that lets you easily implement user-friendly and customisable dragging and resizing of your page elements. You might want to use it as part of a web application -- it contains all you need for a lightweight "windowing" system. Features include:
- Can both drag and resize page elements.
- Works with absolute and relatively positioned elements in your page.
- Customisable appearance as it makes extensive use of CSS classes for layout of its resisze handles.
- Unobtrusive, Object-Orientated JavaScript means it's easy to add to your pages.
- Bounding boxes and minimum sizes can be set and automatically enforced.
- Cross-browser compatible so it works for everyone.
- Small code size so your visitors don't have to wait!
Javascript
if (typeof addEvent != 'function') { var addEvent = function(o, t, f, l) { var d = 'addEventListener', n = 'on' + t, rO = o, rT = t, rF = f, rL = l; if (o[d] && !l) return o[d](t, f, false); if (!o._evts) o._evts = {}; if (!o._evts[t]) { o._evts[t] = o[n] ? { b: o[n] } : {}; o[n] = new Function('e', 'var r=true,o=this,a=o._evts["' + t + '"],i;for(i in a){o._f=a[i];r=o._f(e||window.event)!=false&&r;o._f=null}return r'); if (t != 'unload') addEvent(window, 'unload', function() { removeEvent(rO, rT, rF, rL) }) } if (!f._i) f._i = addEvent._i++; o._evts[t][f._i] = f }; addEvent._i = 1; var removeEvent = function(o, t, f, l) { var d = 'removeEventListener'; if (o[d] && !l) return o[d](t, f, false); if (o._evts && o._evts[t] && f._i) delete o._evts[t][f._i] } } function cancelEvent(e, c) { e.returnValue = false; if (e.preventDefault) e.preventDefault(); if (c) { e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation() } }; function DragResize(myName, config) { var props = { myName: myName, enabled: true, handles: ['tl', 'tm', 'tr', 'ml', 'mr', 'bl', 'bm', 'br'], isElement: null, isHandle: null, element: null, handle: null, minWidth: 10, minHeight: 10, minLeft: 0, maxLeft: 9999, minTop: 0, maxTop: 9999, zIndex: 1, mouseX: 0, mouseY: 0, lastMouseX: 0, lastMouseY: 0, mOffX: 0, mOffY: 0, elmX: 0, elmY: 0, elmW: 0, elmH: 0, allowBlur: true, ondragfocus: null, ondragstart: null, ondragmove: null, ondragend: null, ondragblur: null }; for (var p in props) this[p] = (typeof config[p] == 'undefined') ? props[p] : config[p] }; DragResize.prototype.apply = function(node) { var obj = this; addEvent(node, 'mousedown', function(e) { obj.mouseDown(e) }); addEvent(node, 'mousemove', function(e) { obj.mouseMove(e) }); addEvent(node, 'mouseup', function(e) { obj.mouseUp(e) }) }; DragResize.prototype.select = function(newElement) { with(this) { if (!document.getElementById || !enabled) return; if (newElement && (newElement != element) && enabled) { element = newElement; element.style.zIndex = ++zIndex; if (this.resizeHandleSet) this.resizeHandleSet(element, true); elmX = parseInt(element.style.left); elmY = parseInt(element.style.top); elmW = element.offsetWidth; elmH = element.offsetHeight; if (ondragfocus) this.ondragfocus() } } }; DragResize.prototype.deselect = function(delHandles) { with(this) { if (!document.getElementById || !enabled) return; if (delHandles) { if (ondragblur) this.ondragblur(); if (this.resizeHandleSet) this.resizeHandleSet(element, false); element = null } handle = null; mOffX = 0; mOffY = 0 } }; DragResize.prototype.mouseDown = function(e) { with(this) { if (!document.getElementById || !enabled) return true; var elm = e.target || e.srcElement, newElement = null, newHandle = null, hRE = new RegExp(myName + '-([trmbl]{2})', ''); while (elm) { if (elm.className) { if (!newHandle && (hRE.test(elm.className) || isHandle(elm))) newHandle = elm; if (isElement(elm)) { newElement = elm; break } } elm = elm.parentNode } if (element && (element != newElement) && allowBlur) deselect(true); if (newElement && (!element || (newElement == element))) { if (newHandle) cancelEvent(e); select(newElement, newHandle); handle = newHandle; if (handle && ondragstart) this.ondragstart(hRE.test(handle.className)) } } }; DragResize.prototype.mouseMove = function(e) { with(this) { if (!document.getElementById || !enabled) return true; mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft; mouseY = e.pageY || e.clientY + document.documentElement.scrollTop; var diffX = mouseX - lastMouseX + mOffX; var diffY = mouseY - lastMouseY + mOffY; mOffX = mOffY = 0; lastMouseX = mouseX; lastMouseY = mouseY; if (!handle) return true; var isResize = false; if (this.resizeHandleDrag && this.resizeHandleDrag(diffX, diffY)) { isResize = true } else { var dX = diffX, dY = diffY; if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX)); else if (elmX + elmW + dX > maxLeft) mOffX = (dX - (diffX = maxLeft - elmX - elmW)); if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY)); else if (elmY + elmH + dY > maxTop) mOffY = (dY - (diffY = maxTop - elmY - elmH)); elmX += diffX; elmY += diffY } with(element.style) { left = elmX + 'px'; width = elmW + 'px'; top = elmY + 'px'; height = elmH + 'px' } if (window.opera && document.documentElement) { var oDF = document.getElementById('op-drag-fix'); if (!oDF) { var oDF = document.createElement('input'); oDF.id = 'op-drag-fix'; oDF.style.display = 'none'; document.body.appendChild(oDF) } oDF.focus() } if (ondragmove) this.ondragmove(isResize); cancelEvent(e) } }; DragResize.prototype.mouseUp = function(e) { with(this) { if (!document.getElementById || !enabled) return; var hRE = new RegExp(myName + '-([trmbl]{2})', ''); if (handle && ondragend) this.ondragend(hRE.test(handle.className)); deselect(false) } }; DragResize.prototype.resizeHandleSet = function(elm, show) { with(this) { if (!elm._handle_tr) { for (var h = 0; h < handles.length; h++) { var hDiv = document.createElement('div'); hDiv.className = myName + ' ' + myName + '-' + handles[h]; elm['_handle_' + handles[h]] = elm.appendChild(hDiv) } } for (var h = 0; h < handles.length; h++) { elm['_handle_' + handles[h]].style.visibility = show ? 'inherit' : 'hidden' } } }; DragResize.prototype.resizeHandleDrag = function(diffX, diffY) { with(this) { var hClass = handle && handle.className && handle.className.match(new RegExp(myName + '-([tmblr]{2})')) ? RegExp.$1 : ''; var dY = diffY, dX = diffX, processed = false; if (hClass.indexOf('t') >= 0) { rs = 1; if (elmH - dY < minHeight) mOffY = (dY - (diffY = elmH - minHeight)); else if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY)); elmY += diffY; elmH -= diffY; processed = true } if (hClass.indexOf('b') >= 0) { rs = 1; if (elmH + dY < minHeight) mOffY = (dY - (diffY = minHeight - elmH)); else if (elmY + elmH + dY > maxTop) mOffY = (dY - (diffY = maxTop - elmY - elmH)); elmH += diffY; processed = true } if (hClass.indexOf('l') >= 0) { rs = 1; if (elmW - dX < minWidth) mOffX = (dX - (diffX = elmW - minWidth)); else if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX)); elmX += diffX; elmW -= diffX; processed = true } if (hClass.indexOf('r') >= 0) { rs = 1; if (elmW + dX < minWidth) mOffX = (dX - (diffX = minWidth - elmW)); else if (elmX + elmW + dX > maxLeft) mOffX = (dX - (diffX = maxLeft - elmX - elmW)); elmW += diffX; processed = true } return processed } };
Css
/* Required CSS classes: must be included in all pages using this script */ /* Apply the element you want to drag/resize */ .drsElement { position: absolute; border: 1px solid #333; } /* The main mouse handle that moves the whole element. You can apply to the same tag as drsElement if you want. */ .drsMoveHandle { height: 20px; background-color: #CCC; border-bottom: 1px solid #666; cursor: move; } /* The DragResize object name is automatically applied to all generated corner resize handles, as well as one of the individual classes below. */ .dragresize { position: absolute; width: 5px; height: 5px; font-size: 1px; background: #EEE; border: 1px solid #333; } /* Individual corner classes - required for resize support. These are based on the object name plus the handle ID. */ .dragresize-tl { top: -8px; left: -8px; cursor: nw-resize; } .dragresize-tm { top: -8px; left: 50%; margin-left: -4px; cursor: n-resize; } .dragresize-tr { top: -8px; right: -8px; cursor: ne-resize; } .dragresize-ml { top: 50%; margin-top: -4px; left: -8px; cursor: w-resize; } .dragresize-mr { top: 50%; margin-top: -4px; right: -8px; cursor: e-resize; } .dragresize-bl { bottom: -8px; left: -8px; cursor: sw-resize; } .dragresize-bm { bottom: -8px; left: 50%; margin-left: -4px; cursor: s-resize; } .dragresize-br { bottom: -8px; right: -8px; cursor: se-resize; }
Use
<script type="text/javascript"> //<![CDATA[ // Using DragResize is simple! // You first declare a new DragResize() object, passing its own name and an object // whose keys constitute optional parameters/settings: var dragresize = new DragResize('dragresize', { minWidth: 50, minHeight: 50, minLeft: 20, minTop: 20, maxLeft: 600, maxTop: 600 }); // Optional settings/properties of the DragResize object are: // enabled: Toggle whether the object is active. // handles[]: An array of drag handles to use (see the .JS file). // minWidth, minHeight: Minimum size to which elements are resized (in pixels). // minLeft, maxLeft, minTop, maxTop: Bounding box (in pixels). // Next, you must define two functions, isElement and isHandle. These are passed // a given DOM element, and must "return true" if the element in question is a // draggable element or draggable handle. Here, I'm checking for the CSS classname // of the elements, but you have have any combination of conditions you like: dragresize.isElement = function(elm) { if (elm.className && elm.className.indexOf('drsElement') > -1) return true; }; dragresize.isHandle = function(elm) { if (elm.className && elm.className.indexOf('drsMoveHandle') > -1) return true; }; // You can define optional functions that are called as elements are dragged/resized. // Some are passed true if the source event was a resize, or false if it's a drag. // The focus/blur events are called as handles are added/removed from an object, // and the others are called as users drag, move and release the object's handles. // You might use these to examine the properties of the DragResize object to sync // other page elements, etc. dragresize.ondragfocus = function() { }; dragresize.ondragstart = function(isResize) { }; dragresize.ondragmove = function(isResize) { }; dragresize.ondragend = function(isResize) { }; dragresize.ondragblur = function() { }; // Finally, you must apply() your DragResize object to a DOM node; all children of this // node will then be made draggable. Here, I'm applying to the entire document. dragresize.apply(document); //]]> </script>
HTML
<!-- Here's our draggable elements. All that's required is that they have a relative or absolute CSS 'position', and are matched by the isElement/isHandle methods of a DragResize object. Easy! --> <div class="drsElement" style="left: 50px; top: 150px; width: 250px; height: 120px; background: #CDF; text-align: center"> <div class="drsMoveHandle">Div 0</div> Content </div> <div class="drsElement" style="left: 20px; top: 300px; width: 150px; height: 200px; background: #FDC; text-align: center"> <div class="drsMoveHandle">Div 1</div> Content </div> <div class="drsElement drsMoveHandle" style="left: 150px; top: 280px; width: 50px; height: 100px; background: #DFC; text-align: center"> Div 2 Content </div>comments powered by HyperComments