JQuery के साथ एक तत्व को दूसरे के सापेक्ष कैसे रखें?


354

मेरे पास एक छिपा हुआ DIV है जिसमें एक टूलबार जैसा मेनू है।

मेरे पास कई DIV हैं जो मेनू को तब दिखाने में सक्षम होते हैं जब माउस उनके ऊपर मंडराता है।

क्या कोई अंतर्निहित फ़ंक्शन है जो मेनू को DIV को सक्रिय (माउस होवर) DIV के शीर्ष दाईं ओर ले जाएगा? मैं कुछ ऐसा ढूंढ रहा हूं$(menu).position("topright", targetEl);


1
stackoverflow.com/questions/8400876/… पर एक नज़र डालें जो बहुत अधिक समस्याओं को संबोधित करता है जो हो सकती हैं
Toskan

कृपया देखें "क्या सवालों को" शीर्षक में "टैग" शामिल होना चाहिए? , जहां सर्वसम्मति "नहीं, वे नहीं होनी चाहिए"!
एंड्रियास नीडेरमेयर

@ अंपुल हां, शैली में थोड़ा अंतर है। इस प्रश्न का प्रारंभिक शीर्षक jQuery के साथ उपसर्ग किया गया था : जिसे प्रोत्साहित नहीं किया गया है। आमतौर पर, प्रश्न के अतिरिक्त टैगिंग के कारण, जो उपसर्ग को बेकार कर देता है। यदि शीर्षक में प्रौद्योगिकी की आवश्यकता है, तो इसे एक वास्तविक वाक्य में कैद किया जाना चाहिए , न कि केवल एक उपसर्ग - क्योंकि यही वह है जो टैग के लिए हैं।
एंड्रियास नीडेरमेयर

जवाबों:


203

नोट: इसके लिए jQuery UI (न केवल jQuery) की आवश्यकता है।

अब आप उपयोग कर सकते हैं:

$("#my_div").position({
    my:        "left top",
    at:        "left bottom",
    of:        this, // or $("#otherdiv")
    collision: "fit"
});

तेजी से स्थिति के लिए ( jQuery यूआई / स्थिति )।

आप यहाँ jQuery UI डाउनलोड कर सकते हैं


1
मैं पॉज़िटॉन प्लगइन का उपयोग करने की कोशिश कर रहा हूं, लेकिन किसी कारण से मैं इसे काम नहीं कर पा रहा हूं :(
सलमान ए

मेरे लिए भी काम नहीं करता है। शरीर के ऊपर एक सरल ठोस रंग की स्थिति के लिए इसका उपयोग करने का प्रयास करने के परिणामस्वरूप यह 17 पिक्सेल से ऊपरी बाईं ओर बंद हो गया।
बैंगन जेफ

46
ध्यान दें कि यह उत्तर jQueryUI पर निर्भर करता है, न कि केवल jQuery पर। यह समझा सकता है कि यह आपके लिए कुछ काम क्यों नहीं कर रहा है।
बस्टबंस

398

tl; dr: (इसे यहाँ आज़माएं )

यदि आपके पास निम्न HTML है:

<div id="menu" style="display: none;">
   <!-- menu stuff in here -->
   <ul><li>Menu item</li></ul>
</div>

<div class="parent">Hover over me to show the menu here</div>

तो आप निम्न जावास्क्रिप्ट कोड का उपयोग कर सकते हैं:

$(".parent").mouseover(function() {
    // .position() uses position relative to the offset parent, 
    var pos = $(this).position();

    // .outerWidth() takes into account border and padding.
    var width = $(this).outerWidth();

    //show the menu directly over the placeholder
    $("#menu").css({
        position: "absolute",
        top: pos.top + "px",
        left: (pos.left + width) + "px"
    }).show();
});

लेकिन यह काम नहीं करता है!

यह तब तक काम करेगा जब तक मेनू और प्लेसहोल्डर में एक ही ऑफसेट अभिभावक हो। यदि वे नहीं करते हैं, और आपके पास सीएसएस नियमों का पालन नहीं होता है, तो ध्यान दें कि डोम #menuतत्व में उपयोग कहां है :

$(this).append($("#menu"));

लाइन के ठीक पहले जो स्थिति रखता है #menu तत्व को है।

लेकिन यह अभी भी काम नहीं करता है!

आपके पास कुछ अजीब लेआउट हो सकते हैं जो इस दृष्टिकोण के साथ काम नहीं करते हैं। उस स्थिति में, बस jQuery.ui की स्थिति प्लगइन का उपयोग करें (जैसा कि नीचे एक उत्तर में उल्लेख किया गया है ), जो प्रत्येक बोधगम्य घटना को संभालता है। ध्यान दें कि आपको show()कॉल करने से पहले मेनू तत्व पर जाना होगा position({...}); प्लगइन छिपे हुए तत्वों को स्थान नहीं दे सकता है।

2012 में 3 साल बाद अपडेट नोट:

(मूल समाधान यहाँ संग्रहीत है )

इसलिए, यह पता चला है कि मेरे पास यहां की मूल विधि आदर्श से बहुत दूर थी। विशेष रूप से, यह विफल होगा अगर:

  • मेनू का ऑफसेट अभिभावक प्लेसहोल्डर का ऑफसेट अभिभावक नहीं है
  • प्लेसहोल्डर के पास बॉर्डर / पैडिंग है

सौभाग्य से, jQuery ने 1.2.6 में तरीकों ( position()और outerWidth()) को वापस लाया, जो कि बाद के मामले में सही मूल्यों को खोजना आसान बनाते हैं। पूर्व मामले के लिए,append लिए, प्लेसहोल्डर के मेनू तत्व को आईएनजी काम करता है (लेकिन नेस्टिंग के आधार पर सीएसएस नियमों को तोड़ देगा)।


168
वाह यह अजीब है: मुझे दूसरे दिन यह करना पड़ा, याद नहीं कैसे, इसे googled और मिल गया ... यह जवाब! होगा प्यार SOF।
जैकब

17
हेह - मुझे वही हुआ है जो मेरे साथ हुआ - याद नहीं है कि कैसे कुछ करना है, और स्टैक ओवरफ्लो पर अपना जवाब मिला।
हर्ब कॉडिल

16
मुझे लगता है कि आपके मेनू डिव स्टाइल को डिस्प्ले का उपयोग करना चाहिए: डिस्प्ले के बजाय: छिपा हुआ।
गाबे

6
यह तब ठीक से काम नहीं करेगा जब मेनू के कंटेनर में स्थिति हो: रिश्तेदार (या विरासत के अलावा कुछ भी), स्थिति के बाद से: निरपेक्ष उस की कुंजी देगा, और .offset पृष्ठ के ऊपरी-बाएँ से कुंजी करेगा।
माइक कूपर

3
आपके मेनू को jQuery के .offset () कैसे तैनात किया जाता है इसके आधार पर .position () के लिए एक ड्रॉप-इन प्रतिस्थापन के रूप में उपयोग किया जा सकता है। api.jquery.com/offset
डैनी सी

16

मेरे लिए अंत में यही काम आया।

var showMenu = function(el, menu) {
    //get the position of the placeholder element  
    var pos = $(el).offset();    
    var eWidth = $(el).outerWidth();
    var mWidth = $(menu).outerWidth();
    var left = (pos.left + eWidth - mWidth) + "px";
    var top = 3+pos.top + "px";
    //show the menu directly over the placeholder  
    $(menu).css( { 
        position: 'absolute',
        zIndex: 5000,
        left: left, 
        top: top
    } );

    $(menu).hide().fadeIn();
};

6

यहाँ एक jQuery फ़ंक्शन है जो मैंने लिखा है कि मुझे स्थिति तत्वों में मदद करता है।

यहाँ एक उदाहरण है:

$(document).ready(function() {
  $('#el1').position('#el2', {
    anchor: ['br', 'tr'],
    offset: [-5, 5]
  });
});

ऊपर दिया गया कोड # el2 के शीर्ष-दाईं ओर # el1 के निचले-दाएं को संरेखित करता है। ['cc', 'cc'] # el1 # # 2 में केंद्र होगा। सुनिश्चित करें कि # el1 में स्थिति का सीएसएस है: पूर्ण और z- सूचकांक: 10000 (या वास्तव में बड़ी संख्या) इसे शीर्ष पर रखने के लिए।

ऑफसेट विकल्प आपको एक निर्दिष्ट संख्या में पिक्सेल द्वारा निर्देशांक को कुतरने की अनुमति देता है।

स्रोत कोड नीचे है:

jQuery.fn.getBox = function() {
  return {
    left: $(this).offset().left,
    top: $(this).offset().top,
    width: $(this).outerWidth(),
    height: $(this).outerHeight()
  };
}

jQuery.fn.position = function(target, options) {
  var anchorOffsets = {t: 0, l: 0, c: 0.5, b: 1, r: 1};
  var defaults = {
    anchor: ['tl', 'tl'],
    animate: false,
    offset: [0, 0]
  };
  options = $.extend(defaults, options);

  var targetBox = $(target).getBox();
  var sourceBox = $(this).getBox();

  //origin is at the top-left of the target element
  var left = targetBox.left;
  var top = targetBox.top;

  //alignment with respect to source
  top -= anchorOffsets[options.anchor[0].charAt(0)] * sourceBox.height;
  left -= anchorOffsets[options.anchor[0].charAt(1)] * sourceBox.width;

  //alignment with respect to target
  top += anchorOffsets[options.anchor[1].charAt(0)] * targetBox.height;
  left += anchorOffsets[options.anchor[1].charAt(1)] * targetBox.width;

  //add offset to final coordinates
  left += options.offset[0];
  top += options.offset[1];

  $(this).css({
    left: left + 'px',
    top: top + 'px'
  });

}

3

बहुत ज्यादा उलझना क्यों? समाधान बहुत सरल है

सीएसएस:

.active-div{
position:relative;
}

.menu-div{
position:absolute;
top:0;
right:0;
display:none;
}

jQuery:

$(function(){
    $(".active-div").hover(function(){
    $(".menu-div").prependTo(".active-div").show();
    },function(){$(".menu-div").hide();
})

यह काम करता है, भले ही,

  • दो तलाक कहीं और रखे
  • ब्राउज़र पुनः आकार

अगर मैं प्लेसहोल्डर का अनुकरण करना चाहता हूँ और इसे इनपुट के ऊपर दिखाना चाहता हूँ तो यह तरीका काम नहीं करता है
tibalt

यह तब काम नहीं करता जब मैं दो तत्वों को जोड़ना चाहता हूं जो भाई-बहन हैं या पूरी तरह से असंबंधित हैं, जो बहुत आम है।
ओरियम

3

आप jQuery प्लगइन positionCalculator का उपयोग कर सकते हैं

उस प्लगइन में टकराव से निपटने (फ्लिप) को भी शामिल किया गया है, इसलिए टूलबार जैसा मेनू एक दृश्य स्थिति पर रखा जा सकता है।

$(".placeholder").on('mouseover', function() {
    var $menu = $("#menu").show();// result for hidden element would be incorrect
    var pos = $.PositionCalculator( {
        target: this,
        targetAt: "top right",
        item: $menu,
        itemAt: "top left",
        flip: "both"
    }).calculate();

    $menu.css({
        top: parseInt($menu.css('top')) + pos.moveBy.y + "px",
        left: parseInt($menu.css('left')) + pos.moveBy.x + "px"
    });
});

उस मार्कअप के लिए:

<ul class="popup" id="menu">
    <li>Menu item</li>
    <li>Menu item</li>
    <li>Menu item</li>
</ul>

<div class="placeholder">placeholder 1</div>
<div class="placeholder">placeholder 2</div>

यहाँ फिडेल है: http://jsfiddle.net/QrrpB/1657/


कंसोल लिखते हैं अनिर्धारित लाइन के लिए एक फ़ंक्शन नहीं है: var pos = $ .PositionCalculator ({क्या आप इस समस्या को हल करने में मदद कर सकते हैं?
अलेक्जेंडर बेलोव

@AlexandrBelov: मुझे लगता है, आपने प्लगइन को लोड नहीं किया है। इससे पहले कि आप इसका उपयोग कर सकें, आपको प्लगइन पॉजिशनकैलकुलर के जेएस-फाइल को लोड करना होगा।
टिलिंडिग

2

कुछ इस तरह?

$(menu).css("top", targetE1.y + "px"); 
$(menu).css("left", targetE1.x - widthOfMenu + "px");

2

यह मेरे लिए काम करता है:

var posPersonTooltip = function(event) {
var tPosX = event.pageX - 5;
var tPosY = event.pageY + 10;
$('#personTooltipContainer').css({top: tPosY, left: tPosX});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.