Reputation: 3489
I've got a draggable within my Pointer
object in which I want to refer back to a method within my Pointer
from the drag stop. However I run into a scope issue. Now I suppose I can use $.proxy()
. But I still need the $(this)
inside the drag stop to get the width and height(right?)
Can anyone tell me how I can call this.snapToClosestTile()
(one of last rows in code) within my draggable.stop()
?
function Pointer (obj) {
this.element = obj;
this.getSnapX = function () {
var newOffsetX = null;
for (var i in board.tiles) {
var tile = board.tiles[i];
var offsetX = tile.offset().left;
//Compensate a quarter of the width of the object. If the pointer overlaps with 25% or less; it snaps closer to where the pointers' center is.
var objOffsetX = this.element.offset().left - (this.element.width()*0.25);
if (lastOffsetX != null) {
if (objOffsetX >= lastOffsetX && objOffsetX < offsetX) {
newOffsetX = tile.offset().left;
return newOffsetX;
}
}
//Save a last offset to determine that the object is between the last known offset and the current offset.
this.lastOffsetX = offsetX;
}
return newOffsetX;
}
this.getSnapY = function () {
var newOffsetY = null;
for (var i in board.tiles) {
var tile = board.tiles[i];
var offsetY = tile.offset().top;
//Compensate a quarter of the height of the object. If the pointer overlaps with 25% or less; it snaps closer to where the pointers' center is.
var objOffsetY = this.element.offset().top - (this.element.height()*0.25);
if (lastOffsetY != null) {
if (objOffsetY >= lastOffsetY && objOffsetY < offsetY) {
newOffsetY = tile.offset().top;
return newOffsetY;
}
}
//Save a last offset to determine that the object is between the last known offset and the current offset.
this.lastOffsetY = offsetY;
}
return lastOffsetY;
}
this.lastOffsetY = null;
this.lastOffsetX = null;
this.snapToClosestTile = function (obj) {
var newOffsetX = this.getSnapX();
var newOffsetY = this.getSnapY();
//When snap positions are found, set the object to those positions. If not, use the drag-start data to reset the pointer to the initial drag-position
if (newOffsetX != null && newOffsetY != null) {
this.element.offset({left: newOffsetX, top: newOffsetY});
} else {
this.element.offset({left: jQuery(this).data('startX'), top: jQuery(this).data('startY')});
}
}
this.element.draggable({
containment: '.board_container',
start: function () {
//Set all pointers to z-index 1, than higher the current to 2 to always be on top
jQuery('.pointer').css('z-index', 1);
jQuery(this).css('z-index', 2);
//Set a start position in the data of the element to reset it to that place when the stop is out of bounds
jQuery(this).data('startX', jQuery(this).offset().left);
jQuery(this).data('startY', jQuery(this).offset().top);
},
stop: function (e, obj) {
//The dragged item is contained to the parent. The parent is as high as the board
//However; the container is wider than the board(because of the pointer list)
//Therefore there should be a check to verify that the dragged item was dragged inside the #board div's perimeter.
//If not; Reset it to its startX and startY defined in the start above.
//And while we're at it; check the top aswell. It never hurts i suppose.
var objectMaxPositionLeft = board.offset.maxPosX - jQuery(this).width();
var currentPositionLeft = obj.offset.left;
var objectMaxPositionTop = board.offset.maxPosX - jQuery(this).height();
var currentPositionTop = obj.offset.top;
if (currentPositionLeft > objectMaxPositionLeft || currentPositionTop > objectMaxPositionTop) {
jQuery(this).offset({left: jQuery(this).data('startX'), top: jQuery(this).data('startY')});
}
this.snapToClosestTile(jQuery(this));
}
});
}
Upvotes: 1
Views: 90
Reputation: 20731
In most cases you define a variable with a copy of this
:
function Pointer()
{
var that = this;
this.blah = function()
{
...snip...
that.foo(); // that represents 'this' inside Pointer()
...snip...
};
this.element.draggable({
stop: function()
{
...snip...
that.foo(); // also works here
...snip...
}
});
this.foo = function()
{
...snip...
};
}
This is assuming Pointer() is a valid constructor, of course... otherwise this
may not mean what you think inside of Pointer().
Update to answer the question about prototype:
function Pointer()
{
}
Pointer.prototype.blah = function() { ... };
Pointer.prototype.foo = function() { ... };
...
Then you can create an instance of the Pointer declaration with:
var ptr = new Pointer();
The advantage, if you need 10 different Pointer objects, is that all those prototype functions do not get duplicated. If you have really large objects, that can become important. It also allows you to inherit an object from another.
I have a working example in the file named editor.js here:
https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/plugins/editor/
If you scroll down a bit, you'll see the tree of classes that I use. And also I verify my code with the Google Closure Compiler. It helps a lot avoid many basic mistakes.
Upvotes: 2