Skip to content

Instantly share code, notes, and snippets.

@jherax
Last active October 17, 2016 05:07
Show Gist options
  • Save jherax/ad41f92597e6d95bdee1 to your computer and use it in GitHub Desktop.
Save jherax/ad41f92597e6d95bdee1 to your computer and use it in GitHub Desktop.
jQuery: center an element relative to another
(function ($) {
// Reverses the array of matched elements
$.fn.reverse = Array.prototype.reverse;
/**
* Centers an element relative to another.
* @signature: $(selector).center(options)
* @param {Object} options:
* Defines the options with the following properties:
* - of {String, Element, jQuery}: element to which center against.
* - prefixId {String}: the prefix to build the class name for the boundary elements.
* @return {jQuery}
*/
$.fn.center = function(options) {
var target, position = 'fixed';
options = $.extend({
prefixId: "jqcenter"
}, options);
if (options.of === 'parent') {
target = this.parent();
target.css("position", "relative");
position = 'absolute';
} else if (options.of) {
target = $(options.of).first();
target.css("position", "relative");
this.restoreBoundaries();
this.saveBoundaries(options.prefixId);
this.appendTo(target);
position = 'absolute';
}
return this.each(function(i, dom) {
var elem = $(dom);
elem.data('originalCSS', JSON.stringify({
'position': elem.css('position'),
'left': elem.css('left'),
'top': elem.css('top'),
'margin-left': elem.css('margin-left'),
'margin-top': elem.css('margin-top')
}));
elem.css({
'position': position,
'left': '50%',
'top': '50%',
'margin-left': -elem.outerWidth() / 2 + 'px',
'margin-top': -elem.outerHeight() / 2 + 'px'
});
});
};
/**
* Stores the current location of the set of matched elements taking into account its boundary/adjacent elements.
* @signature: $(selector).saveBoundaries(prefix)
* @param {String} prefix: the prefix to build the class name for the boundary elements.
* @return {jQuery}
*/
$.fn.saveBoundaries = function(prefix) {
prefix = prefix ? prefix + "-" : "";
return this.each(function(i, dom) {
var $elem = $(dom),
id = prefix + "jqboundary" + i;
$elem.data("jqboundary", id);
$elem.parent().addClass(id + '-parent');
$elem.prev().addClass(id + '-prev');
$elem.next().addClass(id + '-next');
});
};
/**
* Restores the set of matched elements to its original location stored by $.saveBoundaries()
* @signature: $(selector).restoreBoundaries()
* @return {jQuery}
*/
$.fn.restoreBoundaries = function() {
return this.each(function(i, dom) {
var $elem = $(dom),
id = $elem.data("jqboundary"),
parent = id + '-parent',
prev = id + '-prev',
next = id + '-next',
originalCSS = $elem.data('originalCSS');
if (originalCSS) $elem.css($.parseJSON(originalCSS));
if (!id) return true; //continue
$elem.removeData("jqboundary");
$("[class*=" + id + "]").reverse().each(function() {
var boundary = $(this);
if (boundary.hasClass(next)) return !boundary.before($elem);
if (boundary.hasClass(prev)) return !boundary.after($elem);
if (boundary.hasClass(parent)) return !boundary.append($elem);
}).removeClass([parent, prev, next].join(" "));
});
};
})(window.jQuery);
var elem = $("#loading").show();
//center the element in the middle of screen
elem.center();
//restore to its original position
elem.restoreBoundaries();
//center the element relative to its parent
elem.center({ of: "parent" });
elem.restoreBoundaries();
//center the element relative to another element
elem.center({ of: "#other-wrapper" });
elem.restoreBoundaries();
//center two elements at the same time while avoiding collisions
var uinfo = $("#user-info"),
ubadges = $("#user-badges");
uinfo.center({
of: "#leftPanel",
prefixId: "userInfo"
});
ubadges.center({
of: "#rightPanel",
prefixId: "userBadges"
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment