最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery UI position relative to two elements - Stack Overflow

programmeradmin4浏览0评论

Is it possible to specify jQuery UI position, where X coordinate is relative to element1 and Y coordinate is relative to element2?

Example 1: I want to pop-up a dialog, so that it is centered horizontally, but vertically it is centered on some other element.

Example 2: I have two items in my DOM, and I want to postion the third in the outer corner of these two. I know I can pick the position of each of them, and use x from one and y from the other, but it would look so much nicer to do something like

jQuery('#UpperRight').postion({ 
    my : 'right top',
    at : 'right',
    of : '#rightMostItem',    
    at : 'top',
    of : '#topMostItem'
}) // double parameters don't work of course

or

jQuery('#UpperRight').position({ 
    my : 'right IGNORE',
    at : 'right IGNORE',
    of : '#rightMostItem'})
 .postion({ 
    my : 'IGNORE top',
    at : 'IGNORE top',
    of : '#topMostItem'
}); // where IGNORE overrides the default center

All attempts so far have been trapped with 'center' being the default, not allowed to use 'my current position in one direction' as basis. Any good ideas are very welle!

Is it possible to specify jQuery UI position, where X coordinate is relative to element1 and Y coordinate is relative to element2?

Example 1: I want to pop-up a dialog, so that it is centered horizontally, but vertically it is centered on some other element.

Example 2: I have two items in my DOM, and I want to postion the third in the outer corner of these two. I know I can pick the position of each of them, and use x from one and y from the other, but it would look so much nicer to do something like

jQuery('#UpperRight').postion({ 
    my : 'right top',
    at : 'right',
    of : '#rightMostItem',    
    at : 'top',
    of : '#topMostItem'
}) // double parameters don't work of course

or

jQuery('#UpperRight').position({ 
    my : 'right IGNORE',
    at : 'right IGNORE',
    of : '#rightMostItem'})
 .postion({ 
    my : 'IGNORE top',
    at : 'IGNORE top',
    of : '#topMostItem'
}); // where IGNORE overrides the default center

All attempts so far have been trapped with 'center' being the default, not allowed to use 'my current position in one direction' as basis. Any good ideas are very welle!

Share Improve this question edited Apr 28, 2015 at 8:11 Salman Arshad 272k84 gold badges443 silver badges534 bronze badges asked Jun 23, 2013 at 21:01 FtLieFtLie 7734 silver badges14 bronze badges 2
  • Could you show an example fiddle ? Hard to understand what you try to position and how without some visuals. – rusln Commented Jun 25, 2013 at 14:35
  • 1 +1 This is a great question! I have the same problem. I tried to generalize it a bit so that it gets more attention! PS: the IGNORE idea is exactly what I was thinking about! It would be great if there was such a solution. – Tomas Commented Apr 7, 2014 at 20:46
Add a ment  | 

3 Answers 3

Reset to default 5 +50

This is a quick jquery plugin that does what you want if i understand your question correctly.

http://jsfiddle/S4N5g/5/

plugin code:

$.fn.positionRelative = function(config) {
    var element = this;
    var config = config || {};
    var x = config.x || false;
    var y = config.y || false;    
    var of = config.of || false;

    var css = {}, positionX, positionY;
    
    if (x !== false) {
        
        var offsetX = of.offset().left;
        if (x === 'left') {
            positionX = offsetX;
        } else if(x === 'center') {
            
            var elWidth = element.width();
            var elOffsetWidth = elWidth / 2;
            
            positionX = offsetX + (of.width() /  2);
            positionX = positionX - elOffsetWidth;
            
        } else if(x === 'right') {
            positionX = offsetX + of.width();
        }
        css['left'] = positionX + 'px';
    }

    if (y !== false) {
        var offsetY = of.offset().top;
        
        if (y === 'top') {
            positionY = offsetY;
        } else if(y === 'center') {
            
            var elHeight = element.height();
            var elOffsetHeight = elHeight / 2;
            
            positionY = offsetY + (of.height() /  2);
            positionY = positionY - elOffsetHeight;
            
        } else if(y === 'bottom') {
            positionY = offsetY + of.height();
        }        
        css['top'] = positionY + 'px';        
    }

    css['position'] = 'absolute';
    element.css(css);
    return this;
}

Usage:

//Usage
$('.popup').positionRelative({
    x: 'center',
    of: $('.element1')
}).positionRelative({
    y: 'center',
    of: $('.element2')
});

You can also use the options left, right or center for x and top, bottom, center for y.

Regarding the revised question:

Is it possible to specify jQuery UI position, where X coordinate is relative to element1 and Y coordinate is relative to element2?

It is possible to achieve the desired results manually using .offset(), .outerWidth() and .css() functions as follows:

  • It is pretty straightforward to grab the x and y coordinates of reference elements using offset function

  • You can then calculate the horizontal center, vertical center, right and bottom coordinates of reference elements by adding width/height (see below)

  • Once you have the reference coordinates, align the target element with these coordinates (see below)

Remaining coordinates of reference element given its left, top, width and height:

horizontal center = left + width / 2
  vertical center = top  + height / 2
            right = left + width
           bottom = top  + height

Align target element corners with given x and y coordinates using CSS:

             align left with x => left: x
              align top with y => top:  y
            align right with x => left: x - width
           align bottom with y => top:  y - height
align horizontal center with x => left: x - width / 2
  align vertical center with y => top:  y - height / 2

Here is example code that aligns horizontal center/vertical center of an element with horizontal center of element 1 and vertical center of element 2:

var x1 = $("#div-1").offset().left + Math.floor($("#div-1").outerWidth() / 2);
var y1 = $("#div-2").offset().top + Math.floor($("#div-2").outerHeight() / 2);
var x2 = x1 - Math.floor($("#dialog").outerWidth() / 2);
var y2 = y1 - Math.floor($("#dialog").outerHeight() / 2);
$("#dialog").css({
    left: x2,
    top: y2
});

And here is the demo.


Given the above information, it is possible to write a generic function of your own.

Your requirements are very specific to this unique situation.

I don't have a ready-to-use solution for you, but a suggestion how to tackle the problem.

My suggestion is to implement a custom jQuery function (for example position2) that will calculate the position according to your desired options. Since jQuery UI code is available for everyone to browse through (and grab), you can look at the position function implementation and copy most of the code to your new jQuery function.

Important! You can't use same property name in the options object.

The usage of this new function will look something like that:

$("#element").position2({
    my: "right top",
    atX: "right",
    ofX: "#rightMostItem",
    atY: "top",
    ofY: "#topMostItem"
});

I know that this solution is not the easiest, but I doubt if there's something built already that tackles your requirements.

Oh... and if you choose to implement it, don't forget to post your code here for others to use.

发布评论

评论列表(0)

  1. 暂无评论