2016-10-22 42 views
1

jQuery的不使用CSS很好地工作「改造:規模()」 (但與「轉換:轉換()」,它工作正常)jQuery的定位與CSS3「改造:規模」

請看看在這個簡單的例子:

$(document).ready(function() { 
 

 
    $('#root').dblclick(function() { 
 
    $('#box').position({ 
 
     my: 'right bottom', 
 
     at: 'right bottom', 
 
     of: $('#root') 
 
    }); 
 
    }) 
 

 
    $('#box').draggable({ 
 
    containment: $('#root'), 
 
    }); 
 

 
});
body { 
 
    position: relative; 
 
    margin: 0; 
 
} 
 
#root { 
 
    position: absolute; 
 
    top: 20px; 
 
    left: 20px; 
 
    width: 500px; 
 
    height: 500px; 
 
    border: solid 2px red; 
 
    transform-origin: 0 0 0; 
 
    transform: scale(0.5); 
 
} 
 
#box { 
 
    position: absolute; 
 
    top: 100px; 
 
    left: 50px; 
 
    display: inline-block; 
 
    width: 50px; 
 
    height: 50px; 
 
    background: red; 
 
    border: solid 1px black; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> 
 

 
drag red box :) 
 
<br/>double click in square to position box 
 
<div id="root"> 
 
    <div id="box"></div> 
 
</div>

根節點進行縮放,becouse在我真正的應用程序我使用全屏模式,我需要適應的內容窗口分辨率。 但是,當我縮放父元素,jQuery UI可拖動和jQuery位置無法正常工作。

當然問題是如何使它正常工作?

有很多類似的問題,但我沒有找到正確的答案。

回答

0

我把我的內容爲iframe和我申請轉型iframe廣告 - 它工作正常:)

編輯:以前我的解決方案的版本變成是馬車。但是,如果有人想檢查我保存片斷

/* 
 
* jQuery UI FIX 
 
* Take focus on window.transformScale 
 
*/ 
 

 
/* 
 
* Offset fix 
 
*/ 
 
(function() { 
 

 
function getWindow(elem) { return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView; } 
 

 
jQuery.fn.offset = function(options) { 
 

 
\t // Preserve chaining for setter 
 
\t if (arguments.length) { 
 
\t \t return options === undefined ? 
 
\t \t \t this : 
 
\t \t \t this.each(function(i) { 
 
\t \t \t \t jQuery.offset.setOffset(this, options, i); 
 
\t \t \t }); 
 
\t } 
 

 
\t var docElem, win, rect, doc, 
 
\t \t elem = this[ 0 ]; 
 

 
\t if (!elem) { 
 
\t \t return; 
 
\t } 
 

 
\t // Support: IE <=11 only 
 
\t // Running getBoundingClientRect on a 
 
\t // disconnected node in IE throws an error 
 
\t if (!elem.getClientRects().length) { 
 
\t \t return { top: 0, left: 0 }; 
 
\t } 
 

 
\t var transform = $(document.body).css('transform'); 
 
\t $(document.body).css('transform', 'none'); 
 

 
\t rect = elem.getBoundingClientRect(); 
 

 
\t $(document.body).css('transform', transform); 
 

 
\t // Make sure element is not hidden (display: none) 
 
\t if (rect.width || rect.height) { 
 
\t \t doc = elem.ownerDocument; 
 
\t \t win = getWindow(doc); 
 
\t \t docElem = doc.documentElement; 
 

 
\t \t return { 
 
\t \t \t top: rect.top + (win.pageYOffset - docElem.clientTop)/window.transformScale, 
 
\t \t \t left: rect.left + (win.pageXOffset - docElem.clientLeft)/window.transformScale, 
 
\t \t }; 
 
\t } 
 

 
\t // Return zeros for disconnected and hidden elements (gh-2310) 
 
\t return rect; 
 
}; 
 

 
})(); 
 

 

 
/* 
 
* Position fix 
 
*/ 
 
(function() { 
 

 
var cachedScrollbarWidth, 
 
\t max = Math.max, 
 
\t abs = Math.abs, 
 
\t rhorizontal = /left|center|right/, 
 
\t rvertical = /top|center|bottom/, 
 
\t roffset = /[\+\-]\d+(\.[\d]+)?%?/, 
 
\t rposition = /^\w+/, 
 
\t rpercent = /%$/, 
 
\t _position = $.fn.position; 
 

 
function getOffsets(offsets, width, height) { 
 
\t return [ 
 
\t \t parseFloat(offsets[ 0 ]) * (rpercent.test(offsets[ 0 ]) ? width/100 : 1), 
 
\t \t parseFloat(offsets[ 1 ]) * (rpercent.test(offsets[ 1 ]) ? height/100 : 1) 
 
\t ]; 
 
} 
 

 
function parseCss(element, property) { 
 
\t return parseInt($.css(element, property), 10) || 0; 
 
} 
 

 
function getDimensions(elem) { 
 
\t var raw = elem[ 0 ]; 
 
\t if (raw.nodeType === 9) { 
 
\t \t return { 
 
\t \t \t width: elem.width()/window.transformScale, 
 
\t \t \t height: elem.height()/window.transformScale, 
 
\t \t \t offset: { top: 0, left: 0 } 
 
\t \t }; 
 
\t } 
 
\t if ($.isWindow(raw)) { 
 
\t \t return { 
 
\t \t \t width: elem.width()/window.transformScale, 
 
\t \t \t height: elem.height()/window.transformScale, 
 
\t \t \t offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 
 
\t \t }; 
 
\t } 
 
\t if (raw.preventDefault) { 
 
\t \t return { 
 
\t \t \t width: 0, 
 
\t \t \t height: 0, 
 
\t \t \t offset: { top: raw.pageY, left: raw.pageX } 
 
\t \t }; 
 
\t } 
 
\t return { 
 
\t \t width: elem.outerWidth()/window.transformScale, 
 
\t \t height: elem.outerHeight()/window.transformScale, 
 
\t \t offset: elem.offset() 
 
\t }; 
 
} 
 

 
jQuery.fn.position = function(options) { 
 
\t if (!options || !options.of) { 
 
\t \t return _position.apply(this, arguments); 
 
\t } 
 

 
\t // Make a copy, we don't want to modify arguments 
 
\t options = $.extend({}, options); 
 

 
\t var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 
 
\t \t target = $(options.of), 
 
\t \t within = $.position.getWithinInfo(options.within), 
 
\t \t scrollInfo = $.position.getScrollInfo(within), 
 
\t \t collision = (options.collision || "flip").split(" "), 
 
\t \t offsets = {}; 
 

 
\t dimensions = getDimensions(target); 
 
\t if (target[ 0 ].preventDefault) { 
 

 
\t \t // Force left top to allow flipping 
 
\t \t options.at = "left top"; 
 
\t } 
 
\t targetWidth = dimensions.width; 
 
\t targetHeight = dimensions.height; 
 
\t targetOffset = dimensions.offset; 
 

 
\t // Clone to reuse original targetOffset later 
 
\t basePosition = $.extend({}, targetOffset); 
 

 
\t // Force my and at to have valid horizontal and vertical positions 
 
\t // if a value is missing or invalid, it will be converted to center 
 
\t $.each([ "my", "at" ], function() { 
 
\t \t var pos = (options[ this ] || "").split(" "), 
 
\t \t \t horizontalOffset, 
 
\t \t \t verticalOffset; 
 

 
\t \t if (pos.length === 1) { 
 
\t \t \t pos = rhorizontal.test(pos[ 0 ]) ? 
 
\t \t \t \t pos.concat([ "center" ]) : 
 
\t \t \t \t rvertical.test(pos[ 0 ]) ? 
 
\t \t \t \t \t [ "center" ].concat(pos) : 
 
\t \t \t \t \t [ "center", "center" ]; 
 
\t \t } 
 
\t \t pos[ 0 ] = rhorizontal.test(pos[ 0 ]) ? pos[ 0 ] : "center"; 
 
\t \t pos[ 1 ] = rvertical.test(pos[ 1 ]) ? pos[ 1 ] : "center"; 
 

 
\t \t // Calculate offsets 
 
\t \t horizontalOffset = roffset.exec(pos[ 0 ]); 
 
\t \t verticalOffset = roffset.exec(pos[ 1 ]); 
 
\t \t offsets[ this ] = [ 
 
\t \t \t horizontalOffset ? horizontalOffset[ 0 ] : 0, 
 
\t \t \t verticalOffset ? verticalOffset[ 0 ] : 0 
 
\t \t ]; 
 

 
\t \t // Reduce to just the positions without the offsets 
 
\t \t options[ this ] = [ 
 
\t \t \t rposition.exec(pos[ 0 ])[ 0 ], 
 
\t \t \t rposition.exec(pos[ 1 ])[ 0 ] 
 
\t \t ]; 
 
\t }); 
 

 
\t // Normalize collision option 
 
\t if (collision.length === 1) { 
 
\t \t collision[ 1 ] = collision[ 0 ]; 
 
\t } 
 

 
\t if (options.at[ 0 ] === "right") { 
 
\t \t basePosition.left += targetWidth; 
 
\t } else if (options.at[ 0 ] === "center") { 
 
\t \t basePosition.left += targetWidth/2; 
 
\t } 
 

 
\t if (options.at[ 1 ] === "bottom") { 
 
\t \t basePosition.top += targetHeight; 
 
\t } else if (options.at[ 1 ] === "center") { 
 
\t \t basePosition.top += targetHeight/2; 
 
\t } 
 

 
\t atOffset = getOffsets(offsets.at, targetWidth, targetHeight); 
 
\t basePosition.left += atOffset[ 0 ]; 
 
\t basePosition.top += atOffset[ 1 ]; 
 

 
\t return this.each(function() { 
 
\t \t var collisionPosition, using, 
 
\t \t \t elem = $(this), 
 
\t \t \t elemWidth = elem.outerWidth()/window.transformScale, 
 
\t \t \t elemHeight = elem.outerHeight()/window.transformScale, 
 
\t \t \t marginLeft = parseCss(this, "marginLeft"), 
 
\t \t \t marginTop = parseCss(this, "marginTop"), 
 
\t \t \t collisionWidth = elemWidth + marginLeft + parseCss(this, "marginRight") + 
 
\t \t \t \t scrollInfo.width, 
 
\t \t \t collisionHeight = elemHeight + marginTop + parseCss(this, "marginBottom") + 
 
\t \t \t \t scrollInfo.height, 
 
\t \t \t position = $.extend({}, basePosition), 
 
\t \t \t myOffset = getOffsets(offsets.my, elem.outerWidth()/window.transformScale, elem.outerHeight()/window.transformScale); 
 

 
\t \t if (options.my[ 0 ] === "right") { 
 
\t \t \t position.left -= elemWidth; 
 
\t \t } else if (options.my[ 0 ] === "center") { 
 
\t \t \t position.left -= elemWidth/2; 
 
\t \t } 
 

 
\t \t if (options.my[ 1 ] === "bottom") { 
 
\t \t \t position.top -= elemHeight; 
 
\t \t } else if (options.my[ 1 ] === "center") { 
 
\t \t \t position.top -= elemHeight/2; 
 
\t \t } 
 

 
\t \t position.left += myOffset[ 0 ]; 
 
\t \t position.top += myOffset[ 1 ]; 
 

 
\t \t collisionPosition = { 
 
\t \t \t marginLeft: marginLeft, 
 
\t \t \t marginTop: marginTop 
 
\t \t }; 
 

 
\t \t $.each([ "left", "top" ], function(i, dir) { 
 
\t \t \t if (jQuery.ui.position[ collision[ i ] ]) { 
 
\t \t \t \t jQuery.ui.position[ collision[ i ] ][ dir ](position, { 
 
\t \t \t \t \t targetWidth: targetWidth, 
 
\t \t \t \t \t targetHeight: targetHeight, 
 
\t \t \t \t \t elemWidth: elemWidth, 
 
\t \t \t \t \t elemHeight: elemHeight, 
 
\t \t \t \t \t collisionPosition: collisionPosition, 
 
\t \t \t \t \t collisionWidth: collisionWidth, 
 
\t \t \t \t \t collisionHeight: collisionHeight, 
 
\t \t \t \t \t offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 
 
\t \t \t \t \t my: options.my, 
 
\t \t \t \t \t at: options.at, 
 
\t \t \t \t \t within: within, 
 
\t \t \t \t \t elem: elem 
 
\t \t \t \t }); 
 
\t \t \t } 
 
\t \t }); 
 

 
\t \t if (options.using) { 
 

 
\t \t \t // Adds feedback as second argument to using callback, if present 
 
\t \t \t using = function(props) { 
 
\t \t \t \t var left = targetOffset.left - position.left, 
 
\t \t \t \t \t right = left + targetWidth - elemWidth, 
 
\t \t \t \t \t top = targetOffset.top - position.top, 
 
\t \t \t \t \t bottom = top + targetHeight - elemHeight, 
 
\t \t \t \t \t feedback = { 
 
\t \t \t \t \t \t target: { 
 
\t \t \t \t \t \t \t element: target, 
 
\t \t \t \t \t \t \t left: targetOffset.left, 
 
\t \t \t \t \t \t \t top: targetOffset.top, 
 
\t \t \t \t \t \t \t width: targetWidth, 
 
\t \t \t \t \t \t \t height: targetHeight 
 
\t \t \t \t \t \t }, 
 
\t \t \t \t \t \t element: { 
 
\t \t \t \t \t \t \t element: elem, 
 
\t \t \t \t \t \t \t left: position.left, 
 
\t \t \t \t \t \t \t top: position.top, 
 
\t \t \t \t \t \t \t width: elemWidth, 
 
\t \t \t \t \t \t \t height: elemHeight 
 
\t \t \t \t \t \t }, 
 
\t \t \t \t \t \t horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 
 
\t \t \t \t \t \t vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 
 
\t \t \t \t \t }; 
 
\t \t \t \t if (targetWidth < elemWidth && abs(left + right) < targetWidth) { 
 
\t \t \t \t \t feedback.horizontal = "center"; 
 
\t \t \t \t } 
 
\t \t \t \t if (targetHeight < elemHeight && abs(top + bottom) < targetHeight) { 
 
\t \t \t \t \t feedback.vertical = "middle"; 
 
\t \t \t \t } 
 
\t \t \t \t if (max(abs(left), abs(right)) > max(abs(top), abs(bottom))) { 
 
\t \t \t \t \t feedback.important = "horizontal"; 
 
\t \t \t \t } else { 
 
\t \t \t \t \t feedback.important = "vertical"; 
 
\t \t \t \t } 
 
\t \t \t \t options.using.call(this, props, feedback); 
 
\t \t \t }; 
 
\t \t } 
 

 
\t \t elem.offset($.extend(position, { using: using })); 
 
\t }); 
 
}; 
 

 
})(); 
 

 

 
/* 
 
* Draggable fix 
 
*/ 
 
(function() { 
 

 
jQuery.ui.draggable.prototype._refreshOffsets = function(event) { 
 
\t this.offset = { 
 
\t \t top: this.positionAbs.top - this.margins.top, 
 
\t \t left: this.positionAbs.left - this.margins.left, 
 
\t \t scroll: false, 
 
\t \t parent: this._getParentOffset(), 
 
\t \t relative: this._getRelativeOffset() 
 
\t }; 
 

 
\t this.offset.click = { 
 
\t \t left: event.pageX/window.transformScale - this.offset.left, 
 
\t \t top: event.pageY/window.transformScale - this.offset.top 
 
\t }; 
 
}; 
 

 
jQuery.ui.draggable.prototype._generatePosition = function(event, constrainPosition) { 
 

 
\t var containment, co, top, left, 
 
\t \t o = this.options, 
 
\t \t scrollIsRootNode = this._isRootNode(this.scrollParent[ 0 ]), 
 
\t \t pageX = event.pageX/window.transformScale, 
 
\t \t pageY = event.pageY/window.transformScale; 
 

 
\t // Cache the scroll 
 
\t if (!scrollIsRootNode || !this.offset.scroll) { 
 
\t \t this.offset.scroll = { 
 
\t \t \t top: this.scrollParent.scrollTop(), 
 
\t \t \t left: this.scrollParent.scrollLeft() 
 
\t \t }; 
 
\t } 
 

 
\t /* 
 
\t * - Position constraining - 
 
\t * Constrain the position to a mix of grid, containment. 
 
\t */ 
 

 
\t // If we are not dragging yet, we won't check for options 
 
\t if (constrainPosition) { 
 
\t \t if (this.containment) { 
 
\t \t \t if (this.relativeContainer) { 
 
\t \t \t \t co = this.relativeContainer.offset(); 
 
\t \t \t \t containment = [ 
 
\t \t \t \t \t this.containment[ 0 ] + co.left, 
 
\t \t \t \t \t this.containment[ 1 ] + co.top, 
 
\t \t \t \t \t this.containment[ 2 ] + co.left, 
 
\t \t \t \t \t this.containment[ 3 ] + co.top 
 
\t \t \t \t ]; 
 
\t \t \t } else { 
 
\t \t \t \t containment = this.containment; 
 
\t \t \t } 
 

 
\t \t \t var width = 0; 
 
\t \t \t var height = 0; 
 
\t \t \t if(window.transformScale != 1) 
 
\t \t \t { 
 
\t \t \t \t var width = this.helper.outerWidth(); 
 
\t \t \t \t var height = this.helper.outerHeight(); 
 
\t \t \t } 
 

 
\t \t \t if (pageX - this.offset.click.left < containment[ 0 ]) { 
 
\t \t \t \t pageX = containment[ 0 ] + this.offset.click.left; 
 
\t \t \t } 
 
\t \t \t if (pageY - this.offset.click.top < containment[ 1 ]) { 
 
\t \t \t \t pageY = containment[ 1 ] + this.offset.click.top; 
 
\t \t \t } 
 
\t \t \t if (pageX - this.offset.click.left + width > containment[ 2 ]) { 
 
\t \t \t \t pageX = containment[ 2 ] + this.offset.click.left - width; 
 
\t \t \t } 
 
\t \t \t if (pageY - this.offset.click.top + height > containment[ 3 ]) { 
 
\t \t \t \t pageY = containment[ 3 ] + this.offset.click.top - height; 
 
\t \t \t } 
 
\t \t } 
 

 
\t \t if (o.grid) { 
 

 
\t \t \t //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 
 
\t \t \t // argument errors in IE (see ticket #6950) 
 
\t \t \t top = o.grid[ 1 ] ? this.originalPageY + Math.round((pageY - 
 
\t \t \t \t this.originalPageY)/o.grid[ 1 ]) * o.grid[ 1 ] : this.originalPageY; 
 
\t \t \t pageY = containment ? ((top - this.offset.click.top >= containment[ 1 ] || 
 
\t \t \t \t top - this.offset.click.top > containment[ 3 ]) ? 
 
\t \t \t \t \t top : 
 
\t \t \t \t \t ((top - this.offset.click.top >= containment[ 1 ]) ? 
 
\t \t \t \t \t \t top - o.grid[ 1 ] : top + o.grid[ 1 ])) : top; 
 

 
\t \t \t left = o.grid[ 0 ] ? this.originalPageX + 
 
\t \t \t \t Math.round((pageX - this.originalPageX)/o.grid[ 0 ]) * o.grid[ 0 ] : 
 
\t \t \t \t this.originalPageX; 
 
\t \t \t pageX = containment ? ((left - this.offset.click.left >= containment[ 0 ] || 
 
\t \t \t \t left - this.offset.click.left > containment[ 2 ]) ? 
 
\t \t \t \t \t left : 
 
\t \t \t \t \t ((left - this.offset.click.left >= containment[ 0 ]) ? 
 
\t \t \t \t \t \t left - o.grid[ 0 ] : left + o.grid[ 0 ])) : left; 
 
\t \t } 
 

 
\t \t if (o.axis === "y") { 
 
\t \t \t pageX = this.originalPageX; 
 
\t \t } 
 

 
\t \t if (o.axis === "x") { 
 
\t \t \t pageY = this.originalPageY; 
 
\t \t } 
 
\t } 
 

 
\t return { 
 
\t \t top: (
 

 
\t \t \t // The absolute mouse position 
 
\t \t \t pageY - 
 

 
\t \t \t // Click offset (relative to the element) 
 
\t \t \t this.offset.click.top - 
 

 
\t \t \t // Only for relative positioned nodes: Relative offset from element to offset parent 
 
\t \t \t this.offset.relative.top - 
 

 
\t \t \t // The offsetParent's offset without borders (offset + border) 
 
\t \t \t this.offset.parent.top + 
 
\t \t \t (this.cssPosition === "fixed" ? 
 
\t \t \t \t -this.offset.scroll.top : 
 
\t \t \t \t (scrollIsRootNode ? 0 : this.offset.scroll.top)) 
 
\t \t), 
 
\t \t left: (
 

 
\t \t \t // The absolute mouse position 
 
\t \t \t pageX - 
 

 
\t \t \t // Click offset (relative to the element) 
 
\t \t \t this.offset.click.left - 
 

 
\t \t \t // Only for relative positioned nodes: Relative offset from element to offset parent 
 
\t \t \t this.offset.relative.left - 
 

 
\t \t \t // The offsetParent's offset without borders (offset + border) 
 
\t \t \t this.offset.parent.left + 
 
\t \t \t (this.cssPosition === "fixed" ? 
 
\t \t \t \t -this.offset.scroll.left : 
 
\t \t \t \t (scrollIsRootNode ? 0 : this.offset.scroll.left)) 
 
\t \t) 
 
\t }; 
 

 
}; 
 

 
jQuery.ui.draggable.prototype._mouseStart = function(event) { 
 

 
\t var o = this.options; 
 

 
\t //Create and append the visible helper 
 
\t this.helper = this._createHelper(event); 
 

 
\t this._addClass(this.helper, "ui-draggable-dragging"); 
 

 
\t //Cache the helper size 
 
\t this._cacheHelperProportions(); 
 

 
\t //If ddmanager is used for droppables, set the global draggable 
 
\t if (jQuery.ui.ddmanager) { 
 
\t \t jQuery.ui.ddmanager.current = this; 
 
\t } 
 

 
\t /* 
 
\t * - Position generation - 
 
\t * This block generates everything position related - it's the core of draggables. 
 
\t */ 
 

 
\t //Cache the margins of the original element 
 
\t this._cacheMargins(); 
 

 
\t //Store the helper's css position 
 
\t this.cssPosition = this.helper.css("position"); 
 
\t this.scrollParent = this.helper.scrollParent(true); 
 
\t this.offsetParent = this.helper.offsetParent(); 
 
\t this.hasFixedAncestor = this.helper.parents().filter(function() { 
 
\t \t \t return $(this).css("position") === "fixed"; 
 
\t \t }).length > 0; 
 

 
\t //The element's absolute position on the page minus margins 
 
\t this.positionAbs = this.element.offset(); 
 
\t this._refreshOffsets(event); 
 

 
\t //Generate the original position 
 
\t this.originalPosition = this.position = this._generatePosition(event, false); 
 
\t this.originalPageX = event.pageX/window.transformScale; 
 
\t this.originalPageY = event.pageY/window.transformScale; 
 

 
\t //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 
 
\t (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 
 

 
\t //Set a containment if given in the options 
 
\t this._setContainment(); 
 

 
\t //Trigger event + callbacks 
 
\t if (this._trigger("start", event) === false) { 
 
\t \t this._clear(); 
 
\t \t return false; 
 
\t } 
 

 
\t //Recache the helper size 
 
\t this._cacheHelperProportions(); 
 

 
\t //Prepare the droppable offsets 
 
\t if (jQuery.ui.ddmanager && !o.dropBehaviour) { 
 
\t \t jQuery.ui.ddmanager.prepareOffsets(this, event); 
 
\t } 
 

 
\t // Execute the drag once - this causes the helper not to be visible before getting its 
 
\t // correct position 
 
\t this._mouseDrag(event, true); 
 

 
\t // If the ddmanager is used for droppables, inform the manager that dragging has started 
 
\t // (see #5003) 
 
\t if (jQuery.ui.ddmanager) { 
 
\t \t jQuery.ui.ddmanager.dragStart(this, event); 
 
\t } 
 

 
\t return true; 
 

 
}; 
 

 
jQuery.ui.draggable.prototype._mouseDrag = function(event, noPropagation) { 
 

 
\t // reset any necessary cached properties (see #5009) 
 
\t if (this.hasFixedAncestor) { 
 
\t \t this.offset.parent = this._getParentOffset(); 
 
\t } 
 

 
\t //Compute the helpers position 
 
\t this.position = this._generatePosition(event, true); 
 
\t this.positionAbs = this._convertPositionTo("absolute"); 
 

 
\t //Call plugins and callbacks and use the resulting position if something is returned 
 
\t if (!noPropagation) { 
 
\t \t var ui = this._uiHash(); 
 
\t \t if (this._trigger("drag", event, ui) === false) { 
 
\t \t \t this._mouseUp(new $.Event("mouseup", event)); 
 
\t \t \t return false; 
 
\t \t } 
 
\t \t this.position = ui.position; 
 
\t } 
 

 
\t this.helper[ 0 ].style.left = this.position.left + "px"; 
 
\t this.helper[ 0 ].style.top = this.position.top + "px"; 
 

 
\t if (jQuery.ui.ddmanager) { 
 
\t \t jQuery.ui.ddmanager.drag(this, event); 
 
\t } 
 

 
\t return false; 
 
}; 
 

 
})();
body { 
 
\t position: \t relative; 
 
\t margin: \t \t 0; 
 
\t transform-origin: \t 0 0 0; 
 
} 
 

 
#root { 
 
\t position: \t fixed; 
 
\t top: \t \t 20px; 
 
\t left: \t \t 20px; 
 

 
\t width: \t \t 500px; 
 
\t height: \t \t 500px; 
 

 
\t border: \t \t solid 2px green; 
 

 
} 
 

 
#box { 
 
\t position: \t absolute; 
 
\t top: \t \t 100px; 
 
\t left: \t \t 50px; 
 

 
\t display: \t inline-block; 
 
\t width: \t \t 50px; 
 
\t height: \t \t 50px; 
 

 
\t background: \t yellow; 
 
\t border: \t \t solid 2px black; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> 
 
<script> 
 
/* 
 
* EXAMPLE CODE 
 
*/ 
 
// this variable is required to make extension work 
 
window.transformScale = 0.5; 
 

 
$(document).ready(function() { 
 
    $(document.body).attr('style', 'transform: scale('+ window.transformScale +')'); 
 

 
    $('#root').dblclick(function() { 
 
    $('#box').position({ 
 
     my: 'right bottom', 
 
     at: 'right bottom', 
 
     of: $('#root') 
 
    }); 
 
    }) 
 

 
    $('#box').draggable({ 
 
    containment: $('#root'), 
 
    }); 
 

 
}); 
 
</script> 
 

 
<div id="root"> 
 
    <div id="box"></div> 
 
</div>

3

我適於this answer通過Martii Laine佔殼和用於雙擊定位:

$(document).ready(function() { 
 

 
    var $root = $('#root'); 
 
    var $box = $('#box'); 
 
    
 
    var minLeft = parseFloat($root.css("paddingLeft")); 
 
    var minTop = parseFloat($root.css("paddingTop")); 
 
    var maxLeft = minLeft + $root.width() - $box.outerWidth(); 
 
    var maxTop = minTop + $root.height() - $box.outerHeight(); 
 

 
    $root.dblclick(function() { 
 
     $box.css({ 
 
      left: maxLeft, 
 
      top: maxTop 
 
     }); 
 
    }) 
 
    
 
    var zoom = 0.5; 
 
    var click = { x: 0, y: 0 }; 
 
    
 
    $box.draggable({ 
 
     start: function (event) { 
 
      click.x = event.clientX; 
 
      click.y = event.clientY; 
 
     }, 
 
     
 
     drag: function (event, ui) { 
 
      var original = ui.originalPosition; 
 
      var left = (event.clientX - click.x + original.left)/zoom; 
 
      var top = (event.clientY - click.y + original.top)/zoom; 
 
      ui.position = { 
 
       left: Math.max(minLeft, Math.min(maxLeft, left)), 
 
       top: Math.max(minTop, Math.min(maxTop, top)) 
 
      }; 
 
     } 
 
    }); 
 
});
body 
 
{ 
 
    position: relative; 
 
    margin: 0; 
 
} 
 

 
#root 
 
{ 
 
    position: absolute; 
 
    top: 20px; 
 
    left: 20px; 
 
    width: 500px; 
 
    height: 500px; 
 
    border: solid 2px red; 
 
    transform-origin: 0 0 0; 
 
    transform: scale(0.5); 
 
} 
 

 
#box 
 
{ 
 
    position: absolute; 
 
    top: 100px; 
 
    left: 50px; 
 
    display: inline-block; 
 
    width: 50px; 
 
    height: 50px; 
 
    background: red; 
 
    border: solid 1px black; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> 
 

 
drag red box :) 
 
<br/>double click in square to position box 
 
<div id="root"> 
 
    <div id="box"></div> 
 
</div>

如果其他比對需要時雙擊在根DIV,所述代碼:

$root.dblclick(function() { 
    $box.css({ 
     left: maxLeft, 
     top: maxTop 
    }); 
}) 

可以修改如下:

left: minLeft,     // Left aligned 
left: maxLeft,     // Right aligned 
left: (minLeft + maxLeft)/2, // Centered (horizontally) 

top: minTop,     // At the top 
top: maxTop,     // At the Bottom 
top: (minTop + maxTop)/2,  // Centered (vertically) 
+0

+0.5用於拖動 - 但它仍然是不完美的。您的位置解決方案是不可接受的,cuz設置可能會有所不同Thx任何方式 – l00k

+0

告訴我它是如何變化的,我可以調整代碼。 – ConnorsFan

+0

它可能是左,中,右,上,下。我還需要全面的功能與碰撞檢測,fliping等 – l00k