All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.resources.jquery.position.js Maven / Gradle / Ivy

There is a newer version: 4.3.7.Final
Show newest version
/**
 * @fileOverview jQuery setPosition Plugin to place elements on the page
 * @author Pavel Yaschenko, 05.2010
 * @version 0.5
 */

// draft examples of usage
// jQuery('#tooltip').setPosition('#aaa',{from:'bottom-left', to:'auto-auto'});
// jQuery('#bbb').bind("click",function(e){jQuery('#tooltip').setPosition(e);});
// TODO: clear code
// TODO: optimization

// jQuery(target).setPosition(source,[params])
// source:
//			jQuery selector
//			object {id:}
//			object {left:,top:,width:,height} // all properties are optimal
//			jQuery object
//			dom element
//			event
//
//	params:
//			type: string // position type
//			collision: string // not implemented
//			offset: array [x,y] // implemented only for noPositionType
//			from: string // place target relative of source
//			to: string // direction for target

	/**
	  * @name jQuery
	  * @namespace jQuery 
	  * */

(function($) {
	/**
     * Place DOM element relative to another element or using position parameters. Elements with style.display='none' also supported.
     * 
     * @example jQuery('#tooltip').setPosition('#myDiv',{from:'LB', to:'AA'});
     * @example jQuery('#myClickDiv').bind("click",function(e){jQuery('#tooltip').setPosition(e);});
     *
     * @function
     * @name jQuery#setPosition
     * 
     * @param {object} source - object that provides information about new position. 

* accepts: *

    *
  • jQuery selector or object
  • *
  • object with id: {id:'myDiv'}
  • *
  • object with region settings: {left:0, top:0, width:100, height:100}
  • *
  • DOM Element
  • *
  • Event object
  • *
*

* @param {object} params - position parameters: *
* @param {string} [params.type] - position type that defines positioning and auto positioning rules ["TOOLTIP","DROPDOWN"]
* @param {string} [params.collision] - not implemented yet
* @param {array} [params.offset] - provides array(2) with x and y for manually position definition
* affects only if "type", "from" and "to" not defined
* @param {string} [params.from] - place target relative of source // draft definition
* @param {string} [params.to] - direction for target // draft definition
* * * @return {jQuery} jQuery wrapped DOM elements * */ $.fn.setPosition = function(source, params) { var stype = typeof source; if (stype == "object" || stype == "string") { var rect = {}; if (stype == "string" || source.nodeType || source instanceof jQuery || typeof source.length!="undefined") { rect = getElementRect(source); } else if (source.type) { rect = getPointerRect(source); } else if (source.id) { rect = getElementRect(document.getElementById(source.id)); } else { rect = source; } var params = params || {}; var def = params.type || params.from || params.to ? $.PositionTypes[params.type || defaultType] : {noPositionType:true}; var options = $.extend({}, defaults, def, params); if (!options.noPositionType) { if (options.from.length>2) { options.from = positionDefinition[options.from.toLowerCase()]; } if (options.to.length>2) { options.to = positionDefinition[options.to.toLowerCase()]; } } return this.each(function() { element = $(this); //alert(rect.left+" "+rect.top+" "+rect.width+" "+rect.height); position(rect, element, options); }); } return this; }; var defaultType = "TOOLTIP"; var defaults = { collision: "", offset: [0,0] }; var re = /^(left|right)-(top|buttom|auto)$/i; // TODO: make it private var positionDefinition = { 'top-left':'LT', 'top-right':'RT', 'bottom-left':'LB', 'bottom-right':'RB', 'top-auto':'AT', 'bottom-auto':'AB', 'auto-left':'LA', 'auto-right':'RA', 'auto-auto':'AA' }; $.PositionTypes = { // horisontal constants: L-left, R-right, C-center, A-auto // vertical constants: T-top, B-bottom, M-middle, A-auto // for auto: list of joinPoint-Direction pairs TOOLTIP: {from:"AA", to:"AA", auto:["RTRT", "RBRT", "LTRT", "RTLT", "LTLT", "LBLT", "RTRB", "RBRB", "LBRB", "RBLB"]}, DROPDOWN:{from:"AA", to:"AA", auto:["LBRB", "LTRT", "RBLB", "RTLT"]}, DDMENUGROUP:{from:"AA", to:"AA", auto:["RTRB", "RBRT", "LTLB", "LBLT"]} }; /** * Add or replace position type rules for auto positioning. * Does not fully determinated with parameters yet, only draft version. * * @function * @name jQuery.addPositionType * @param {string} type - name of position rules * @param {object} option - options of position rules * */ $.addPositionType = function (type, options) { // TODO: change [options] to [from, to, auto] /*var obj = {}; if (match=from.match(re))!=null ) { obj.from = [ match[1]=='right' ? 'R' : 'L', match[2]=='bottom' ? 'B' : 'T']; } if (match=to.match(re))!=null ) { obj.to = [ match[1]=='right' ? 'R' : match[1]=='left' ? 'L' : 'A', match[2]=='bottom' ? 'B' : match[2]=='top' ? 'T' : 'A']; }*/ $.PositionTypes[type] = options; } function getPointerRect (event) { var e = $.event.fix(event); return {width: 0, height: 0, left: e.pageX, top: e.pageY}; }; function getElementRect (element) { var jqe = $(element); var offset = jqe.offset(); var rect = {width: jqe.outerWidth(), height: jqe.outerHeight(), left: Math.floor(offset.left), top: Math.floor(offset.top)}; if (jqe.length>1) { var width, height, offset; var e; for (var i=1;i rect.width) rect.width = width - d; } else { rect.width += d; } var d = rect.top - offset.top; if (d<0) { if (height-d > rect.height) rect.height = height -d; } else { rect.height += d; } if (offset.left < rect.left) rect.left = offset.left; if (offset.top < rect.top) rect.top = offset.top; } } return rect; }; function checkCollision (elementRect, windowRect) { // return 0 if elementRect in windowRect without collision if (elementRect.left >= windowRect.left && elementRect.top >= windowRect.top && elementRect.right <= windowRect.right && elementRect.bottom <= windowRect.bottom) return 0; // return collision squire var rect = {left: (elementRect.left>windowRect.left ? elementRect.left : windowRect.left), top: (elementRect.top>windowRect.top ? elementRect.top : windowRect.top)}; rect.right = elementRect.right=0 && oy>=0 && theBest.squares)) { ox=theBest.x; oy=theBest.y } } return {left:ox, top:oy}; } function position (rect, element, options) { var width = element.width(); var height = element.height(); rect.width = rect.width || 0; rect.height = rect.height || 0; var left = parseInt(element.css('left'),10); if (isNaN(left) || left==0) { left = 0; element.css('left', '0px'); } if (isNaN(rect.left)) rect.left = left; var top = parseInt(element.css('top'),10); if (isNaN(top) || top==0) { top = 0; element.css('top', '0px'); } if (isNaN(rect.top)) rect.top = top; var pos = {}; if (options.noPositionType) { pos.left = rect.left + rect.width + options.offset[0]; pos.top = rect.top + options.offset[1]; } else { var jqw = $(window); var winRect = {left:jqw.scrollLeft(), top:jqw.scrollTop()}; winRect.right = winRect.left + jqw.width(); winRect.bottom = winRect.top + jqw.height(); pos = calculatePosition(rect, options.offset, winRect, {width:width, height:height}, options); } // jQuery does not support to get offset for hidden elements var hideElement=false; var eVisibility; var e; if (element.css("display")=="none") { hideElement=true; e = element.get(0); eVisibility = e.style.visibility; e.style.visibility = 'hidden'; e.style.display = 'block'; } var elementOffset = element.offset(); if (hideElement) { e.style.visibility = eVisibility; e.style.display = 'none'; } pos.left += left - Math.floor(elementOffset.left); pos.top += top - Math.floor(elementOffset.top); if (left!=pos.left) { element.css('left', (pos.left + 'px')); } if (top!=pos.top) { element.css('top', (pos.top + 'px')); } }; })(jQuery);




© 2015 - 2024 Weber Informatics LLC | Privacy Policy