2012-04-19 11 views
17

क्या कोई भी ट्विटर बूटस्ट्रैप के पॉपओवर घटक के विस्तार के बारे में जानता है जो स्क्रीन पर पॉपओवर प्रदर्शित करने के लिए प्लेसमेंट विकल्प को गतिशील रूप से बदलता है?आप कैसे सुनिश्चित कर सकते हैं ट्विटर बूटस्ट्रैप पॉपओवर विंडो दिखाई दे रहे हैं?

+0

संभव डुप्लिकेट [ट्विटर बूटस्ट्रैप पॉपओवर नियुक्ति मुद्दा] (http://stackoverflow.com/questions/8839387/twitter-bootstrap-popover-placement-issue) नहीं एक सटीक डुप्लिकेट, लेकिन इतने पास बात करने के। समस्या का शेष गणित का विषय है। –

उत्तर

24

प्लेसमेंट एक स्ट्रिंग के बजाय एक फ़ंक्शन हो सकता है। परियोजना यहाँ पर GitHub मुद्दों में से एक में ऑटो प्लेसमेंट का एक उदाहरण wleeper द्वारा बूटस्ट्रैप का नवीनतम संस्करण को वसा द्वारा लिखित और उसके बाद पोर्ट है: https://github.com/twitter/bootstrap/issues/345

यहाँ के CoffeeScript संकलन का परिणाम है जावास्क्रिप्ट:

$("a[rel=popover]").popover({ 
    placement: function(tip, element) { 
    var $element, above, actualHeight, actualWidth, below, boundBottom, boundLeft, boundRight, boundTop, elementAbove, elementBelow, elementLeft, elementRight, isWithinBounds, left, pos, right; 
    isWithinBounds = function(elementPosition) { 
     return boundTop < elementPosition.top && boundLeft < elementPosition.left && boundRight > (elementPosition.left + actualWidth) && boundBottom > (elementPosition.top + actualHeight); 
    }; 
    $element = $(element); 
    pos = $.extend({}, $element.offset(), { 
     width: element.offsetWidth, 
     height: element.offsetHeight 
    }); 
    actualWidth = 283; 
    actualHeight = 117; 
    boundTop = $(document).scrollTop(); 
    boundLeft = $(document).scrollLeft(); 
    boundRight = boundLeft + $(window).width(); 
    boundBottom = boundTop + $(window).height(); 
    elementAbove = { 
     top: pos.top - actualHeight, 
     left: pos.left + pos.width/2 - actualWidth/2 
    }; 
    elementBelow = { 
     top: pos.top + pos.height, 
     left: pos.left + pos.width/2 - actualWidth/2 
    }; 
    elementLeft = { 
     top: pos.top + pos.height/2 - actualHeight/2, 
     left: pos.left - actualWidth 
    }; 
    elementRight = { 
     top: pos.top + pos.height/2 - actualHeight/2, 
     left: pos.left + pos.width 
    }; 
    above = isWithinBounds(elementAbove); 
    below = isWithinBounds(elementBelow); 
    left = isWithinBounds(elementLeft); 
    right = isWithinBounds(elementRight); 
    if (above) { 
     return "top"; 
    } else { 
     if (below) { 
     return "bottom"; 
     } else { 
     if (left) { 
      return "left"; 
     } else { 
      if (right) { 
      return "right"; 
      } else { 
      return "right"; 
      } 
     } 
     } 
    } 
    } 
}); 

यह एक स्थिति को छोड़कर मेरे लिए अच्छी तरह से काम कर रहा है: यदि आइटम ऊपरी दाएँ कोने में है वहाँ पॉपओवर कि विकल्पों में से एक है प्रकट करने के लिए के लिए कोई अच्छी जगह है और यह आंशिक रूप से बंद प्रकट होता है स्क्रीन।

+4

यह एक अच्छा जवाब है लेकिन पूरी तरह से समस्या का समाधान नहीं करता है। टूलटिप की चौड़ाई और ऊंचाई को 'वास्तविक विड्थ' और 'वास्तविक हाइट' में हार्डकोड किया गया है और इसे प्रस्तुत करने से पहले टूलटिप के आकार को गतिशील रूप से प्राप्त करने का कोई तरीका नहीं है। –

+0

@ BjörnLindqvist यह एक अच्छा मुद्दा है। मैं थोड़ी देर के लिए इसके बारे में सोच रहा हूं लेकिन यह आपके पॉपअप से मेल खाने के लिए मूल्यों को समायोजित करने के अलावा हल करने के लिए एक कठिन समस्या की तरह लगता है (माना जाता है कि यह एक आम आकार है)। कोई इसे छुपा आईफ्रेम में प्रस्तुत कर सकता है या आकार निर्धारित करने के लिए कुछ अन्य हाइजिंग कर सकता है लेकिन मैं ऐसा करने का एक साफ तरीका नहीं सोच सकता। – Cymen

+0

यह एक अच्छा समाधान है यदि आपको यह सुनिश्चित करने के लिए ट्विटर बूस्टर पंपोवर को फ्लिप/फिर से उन्मुख करने की आवश्यकता है। –

12

ऐसे समाधान में रूचि रखने वाले लोगों के लिए जो डिफ़ॉल्ट प्लेसमेंट लेते हैं (data-placement तत्व पर विशेषता का उपयोग करके), मैंने साइमेन से शानदार जवाब अनुकूलित किया है।

मैंने यह भी सुनिश्चित किया है कि कोई सीमाएं अनावश्यक रूप से गणना नहीं की जाती हैं, इसलिए यह थोड़ा अधिक प्रदर्शनकारी होना चाहिए। की

$('[data-toggle="popover"]').each(function() { 
    var trigger = $(this); 
    trigger.popover({ 
     animation: true, 
     delay: { show: 0, hide: 0 }, 
     html: true, 
     trigger: 'hover focus', 
     placement: getPlacementFunction(trigger.attr("data-placement"), 283, 117) 
    }); 
}); 

var getPlacementFunction = function (defaultPosition, width, height) { 
    return function (tip, element) { 
     var position, top, bottom, left, right; 

     var $element = $(element); 
     var boundTop = $(document).scrollTop(); 
     var boundLeft = $(document).scrollLeft(); 
     var boundRight = boundLeft + $(window).width(); 
     var boundBottom = boundTop + $(window).height(); 

     var pos = $.extend({}, $element.offset(), { 
      width: element.offsetWidth, 
      height: element.offsetHeight 
     }); 

     var isWithinBounds = function (elPos) { 
      return boundTop < elPos.top && boundLeft < elPos.left && boundRight > (elPos.left + width) && boundBottom > (elPos.top + height); 
     }; 

     var testTop = function() { 
      if (top === false) return false; 
      top = isWithinBounds({ 
       top: pos.top - height, 
       left: pos.left + pos.width/2 - width/2 
      }); 
      return top ? "top" : false; 
     }; 

     var testBottom = function() { 
      if (bottom === false) return false; 
      bottom = isWithinBounds({ 
       top: pos.top + pos.height, 
       left: pos.left + pos.width/2 - width/2 
      }); 
      return bottom ? "bottom" : false; 
     }; 

     var testLeft = function() { 
      if (left === false) return false; 
      left = isWithinBounds({ 
       top: pos.top + pos.height/2 - height/2, 
       left: pos.left - width 
      }); 
      return left ? "left" : false; 
     }; 

     var testRight = function() { 
      if (right === false) return false; 
      right = isWithinBounds({ 
       top: pos.top + pos.height/2 - height/2, 
       left: pos.left + pos.width 
      }); 
      return right ? "right" : false; 
     }; 

     switch (defaultPosition) { 
      case "top": 
       if (position = testTop()) return position; 
      case "bottom": 
       if (position = testBottom()) return position; 
      case "left": 
       if (position = testLeft()) return position; 
      case "right": 
       if (position = testRight()) return position; 
      default: 
       if (position = testTop()) return position; 
       if (position = testBottom()) return position; 
       if (position = testLeft()) return position; 
       if (position = testRight()) return position; 
       return defaultPosition; 
     } 
    } 
}; 
+1

यह उत्कृष्ट था, और यह न्यूनतम अपडेट के साथ काफी अच्छा काम किया। धन्यवाद! – JazzyWhit

+0

यह काम बूटस्ट्रैप 2 पर या केवल 3 के लिए करता है? – isapir

+0

नहीं कह सका, आपको इसे आजमा देना होगा –

संबंधित मुद्दे