ฉันจะทำให้ Bootstrap popovers มีชีวิตอยู่ได้อย่างไรในขณะที่ถูกโฉบ


114

ฉันใช้ Bootstrap popover เพื่อสร้างการ์ดโฮเวอร์ที่แสดงข้อมูลผู้ใช้และฉันกำลังเรียกใช้มันเมื่อวางเมาส์เหนือปุ่ม ฉันต้องการให้ป๊อปโอเวอร์นี้มีชีวิตอยู่ในขณะที่ป๊อปโอเวอร์นั้นถูกวางไว้ แต่มันจะหายไปทันทีที่ผู้ใช้หยุดวางเมาส์เหนือปุ่ม ฉันจะทำเช่นนี้ได้อย่างไร?

$('#example').popover({
    html : true,
    trigger : 'manual',
    content : function() {
        return '<div class="box">Popover</div>';
    }
});

$(document).on('mouseover', '#example', function(){
    $('#example').popover('show');
});

$(document).on('mouseleave', '#example', function(){
    $('#example').popover('hide');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>

<a href="#" id="example" class="btn btn-danger" rel="popover" >hover for popover</a>


คุณต้องการให้สิ่งที่มีชีวิตอยู่? ฉันวางเมาส์เหนือปุ่มและเปิดค้างไว้?
David Chase

อ่านคำถามบรรทัดสุดท้าย
vikas devde

คำตอบ:


172

ทดสอบด้วยข้อมูลโค้ดด้านล่าง:

การปรับเปลี่ยนเล็กน้อย (จากโซลูชันที่ vikas จัดเตรียมไว้ให้) เพื่อให้เหมาะกับกรณีการใช้งานของฉัน

  1. เปิดป๊อปโอเวอร์ในเหตุการณ์โฮเวอร์สำหรับปุ่มป๊อปโอเวอร์
  2. เปิดหน้าต่างป๊อปโอเวอร์ไว้เมื่อวางเมาส์เหนือกล่องป๊อปโอเวอร์
  3. ปิดป๊อปโอเวอร์บนเมาส์ลีฟสำหรับปุ่มป็อปโอเวอร์หรือกล่องป็อปโอเวอร์

$(".pop").popover({
    trigger: "manual",
    html: true,
    animation: false
  })
  .on("mouseenter", function() {
    var _this = this;
    $(this).popover("show");
    $(".popover").on("mouseleave", function() {
      $(_this).popover('hide');
    });
  }).on("mouseleave", function() {
    var _this = this;
    setTimeout(function() {
      if (!$(".popover:hover").length) {
        $(_this).popover("hide");
      }
    }, 300);
  });
<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap-css@*" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
  <script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script data-require="bootstrap@*" data-semver="3.2.0" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js"></script>

  <link rel="stylesheet" href="style.css" />

</head>

<body>
  <h2 class='text-primary'>Another Great "KISS" Bootstrap Popover example!</h2>
  <p class='text-muted'>KISS = Keep It Simple S....</p>

  <p class='text-primary'>Goal:</p>
  <ul>
    <li>Open popover on hover event for the popover button</li>
    <li>Keep popover open when hovering over the popover box</li>
    <li>Close popover on mouseleave for either the popover button, or the popover box.</li>
  </ul>

  <button type="button" class="btn btn-danger pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    HOVER OVER ME
    </button>
  <br><br>
  <button type="button" class="btn btn-info pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    HOVER OVER ME... Again!
    </button><br><br>
  <button type="button" class="btn btn-success pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    Okay one more time... !
    </button>
  <br><br>
  <p class='text-info'>Hope that helps you... Drove me crazy for a while</p>
  <script src="script.js"></script>
</body>

</html>


นี้ทำงานได้อย่างสมบูรณ์แบบที่ฉันไม่แจ้งให้ทราบว่ามีการขาดหายไปในตัวคุณที่สอง; $(_this).popover("hide")แต่ขอบคุณมันเรียบง่ายและสะอาดมาก!
แพะรับบาป

3
คำตอบนี้น่าทึ่งมาก ใช้งานได้ดีใน BS3 เมื่อพฤษภาคม 2015 ^^
เสื่อมสภาพใน

1
ฉันใช้มันในตารางและฉันเพิ่มcontainer: 'body'ตัวเลือกเพราะมันทำให้เซลล์เปลี่ยนไป ตอบโจทย์มาก!
Alexander Derck

ป๊อปโอเวอร์จะถูกซ่อนหากคุณป้อนแล้วกลับไปที่องค์ประกอบทริกเกอร์ทั้งหมดก่อน 300 มิลลิวินาที ในการแก้ไขให้ตรวจสอบว่าทั้งป็อปโอเวอร์และทริกเกอร์ของมันคือ: วางเมาส์ก่อนซ่อนใน setTimeout ฉันยังใช้ setTimeout และวิธีการเดียวกันกับเมาส์ที่ปล่อยให้ป๊อปโอเวอร์เองเพื่อแก้ไขการกะพริบ
rzb

อย่าลืมตั้งค่าanimation:falseเพื่อแก้ไขการสั่นไหว - ตรวจสอบในลิงค์ Plunker ที่ฉันมีด้านบน มันทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน
OkezieE

84

ฉันได้หาวิธีแก้ไขปัญหานี้อีกครั้ง ... นี่คือรหัส

    $('.selector').popover({
        html: true,
        trigger: 'manual',
        container: $(this).attr('id'),
        placement: 'top',
        content: function () {
            $return = '<div class="hover-hovercard"></div>';
        }
    }).on("mouseenter", function () {
        var _this = this;
        $(this).popover("show");
        $(this).siblings(".popover").on("mouseleave", function () {
            $(_this).popover('hide');
        });
    }).on("mouseleave", function () {
        var _this = this;
        setTimeout(function () {
            if (!$(".popover:hover").length) {
                $(_this).popover("hide")
            }
        }, 100);
    });

6
สิ่งสำคัญคือต้องเพิ่มanimation: falseมิฉะนั้นการเลื่อนเมาส์ไปที่ลิงก์ซ้ำ ๆ จะทำให้ทำงานไม่ถูกต้อง
jasop

5
ฉันมีการแก้ไขโค้ดของคุณ @vikas ( gist.github.com/Nitrodist/7913848 ) เล็กน้อย ตรวจสอบเงื่อนไขอีกครั้งหลังจากผ่านไป 50ms เพื่อไม่ให้ติดค้างอยู่ นั่นคือมันจะตรวจสอบซ้ำทุก ๆ 50ms อย่างต่อเนื่อง
Nitrodist

2
สิ่งนี้จะปรับให้เข้ากับองค์ประกอบสดที่เพิ่งเพิ่มลงในเอกสารได้อย่างไร
williamsowen

28

นี่คือสิ่งที่ฉันทำ: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/

บางครั้งในขณะที่เลื่อนเมาส์จากทริกเกอร์ป็อปโอเวอร์ไปยังเนื้อหาป็อปโอเวอร์จริงในแนวทแยงมุมคุณจะวางเมาส์เหนือองค์ประกอบด้านล่าง ฉันต้องการจัดการสถานการณ์ดังกล่าว - ตราบใดที่คุณเข้าถึงเนื้อหาที่ป๊อปโอเวอร์ก่อนที่จะหมดเวลาคุณก็ปลอดภัย (ป๊อปโอเวอร์จะไม่หายไป) ต้องมีdelayตัวเลือก

โดยพื้นฐานแล้วแฮ็คนี้จะแทนที่leaveฟังก์ชันPopover แต่เรียกแบบเดิม (ซึ่งจะเริ่มจับเวลาเพื่อซ่อนป๊อปโอเวอร์) จากนั้นจะแนบ Listener แบบครั้งเดียวเข้ากับmouseenterองค์ประกอบเนื้อหา popover

หากเมาส์เข้าสู่ป็อปโอเวอร์ตัวจับเวลาจะถูกล้าง จากนั้นมันจะฟังเป็นmouseleaveป๊อปโอเวอร์และถ้ามันถูกทริกเกอร์มันจะเรียกใช้ฟังก์ชันลาเดิมเพื่อให้มันเริ่มซ่อนตัวจับเวลา

var originalLeave = $.fn.popover.Constructor.prototype.leave;
$.fn.popover.Constructor.prototype.leave = function(obj){
  var self = obj instanceof this.constructor ?
    obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
  var container, timeout;

  originalLeave.call(this, obj);

  if(obj.currentTarget) {
    container = $(obj.currentTarget).siblings('.popover')
    timeout = self.timeout;
    container.one('mouseenter', function(){
      //We entered the actual popover – call off the dogs
      clearTimeout(timeout);
      //Let's monitor popover content instead
      container.one('mouseleave', function(){
        $.fn.popover.Constructor.prototype.leave.call(self, self);
      });
    })
  }
};

5
การค้นหาคอนเทนเนอร์สามารถปรับปรุงได้โดยใช้container = self.$tip;วิธีนี้ป๊อปโอเวอร์สามารถพบได้เมื่อcontainerตั้งค่าคุณสมบัติ มีซออยู่ที่นี่: jsfiddle.net/dennis_c/xJc65
dbroeks

3
@pferrel ฉันได้แก้ไขปัญหานี้ในทางแยกของซอของ@Wojtek_Kruszewski : jsfiddle.net/HugeHugh/pN26dดูส่วนที่ตรวจสอบif (!thisTip.is(':visible'))ก่อนที่จะโทรoriginalShow()
H Dog

1
หากป็อปโอเวอร์เริ่มต้นด้วยตัวเลือกcontainer: 'body',โซลูชันนี้จะไม่ทำงานตามที่คาดไว้ ตัวแปรความต้องการที่จะถูกแทนที่ด้วยcontainer self.$tipตรวจสอบคำตอบของฉันสำหรับรายละเอียดเพิ่มเติม: stackoverflow.com/a/28731847/439427
Rubens Mariuzzo

1
สุกใส ซึ่งใช้ได้กับเมื่อใช้พารามิเตอร์ "ตัวเลือก" ซึ่งแตกต่างจากคำตอบอื่น ๆ
jetlej

1
นี่เป็นรุ่นปรับปรุงซึ่งการแก้ไขข้อผิดพลาดเมื่อออกเดินเรื่องและใส่ปลายยังคง hided มันและยังแก้ไขสถานการณ์เมื่อปลายที่แนบมากับร่างกายjsfiddle.net/Zf3m7/1499
ZoltánTamási

14

ฉันคิดว่าวิธีง่ายๆคือ:

$('.popover').each(function () {
                    var $this = $(this);
                    $this.popover({
                        trigger: 'hover',
                        content: 'Content Here',
                        container: $this
                    })
                });

ด้วยวิธีนี้ป๊อปโอเวอร์ถูกสร้างขึ้นภายในองค์ประกอบเป้าหมายเอง ดังนั้นเมื่อคุณเลื่อนเมาส์ไปที่หน้าต่างที่โผล่ขึ้นมามันจะยังอยู่เหนือองค์ประกอบ Bootstrap 3.3.2 ทำงานได้ดีกับสิ่งนี้ เวอร์ชันเก่าอาจมีปัญหาบางอย่างกับภาพเคลื่อนไหวดังนั้นคุณอาจต้องการปิดใช้งาน "animation: false"


ฉันรู้ว่ากระทู้นี้เก่า แต่นี่เป็นวิธีที่ดีที่สุดและสะอาดที่สุดในความคิดของฉันและควรได้รับการจัดอันดับให้สูงขึ้น ข้อแม้เดียวคือสิ่งนี้จะแตกถ้าคุณวางตำแหน่งที่โผล่ขึ้นมา (ในทางที่แปลก) "ห่าง" จากองค์ประกอบทริกเกอร์ แต่ตราบใดที่ระยะห่างระหว่างทั้งสองเป็นศูนย์ (เช่นมันทับซ้อนกัน) สิ่งนี้จะทำงานได้อย่างสวยงามและไม่ต้องใช้ JS ที่กำหนดเองใด ๆ ขอบคุณ!
JohnGalt

นั่นคือทางออกที่ดีที่สุดสะอาดและง่ายที่สุด น่าจะติดอันดับสูงกว่านี้! ฉันเพิ่มdelay: { "hide": 400 }เพื่อเพิ่มความล่าช้าก่อนซ่อนและใช้งานได้ดี! 👍
coorasse

14

ผมใช้ชุดไกไปhoverและให้ชุดภาชนะไป#elementและในที่สุดก็เพิ่มตำแหน่งของการที่จะboxright

นี่ควรเป็นการตั้งค่าของคุณ:

$('#example').popover({
    html: true,
    trigger: 'hover',
    container: '#example',
    placement: 'right',
    content: function () {
        return '<div class="box"></div>';
    }
});

และ#examplecss ต้องการposition:relative;ตรวจสอบ jsfiddle ด้านล่าง:

https://jsfiddle.net/9qn6pw4p/1/

แก้ไข

ซอนี้มีทั้งลิงค์ที่ใช้งานได้โดยไม่มีปัญหา http://jsfiddle.net/davidchase03/FQE57/4/


อืมมันใช้งานได้ฉันสามารถใช้ jquery ajax ในcontentตัวเลือกเพื่อนำเนื้อหาจากฝั่งเซิร์ฟเวอร์.. จะใช้งานได้หรือฉันต้องทำงานพิเศษเพื่อสิ่งนั้น
vikas devde

@vikasdevde ใช่คุณสามารถใช้ajaxในเนื้อหา แต่คุณต้องตั้งค่าเพื่อให้ใช้งานได้ ... โปรดทำเครื่องหมายคำตอบที่ถูกต้องหากแก้ไขได้OP.. เพื่อให้ผู้อื่นได้รับประโยชน์
David Chase

แต่ถ้าเราใช้ลิงค์เป็นคอนเทนเนอร์แล้ว popover ทั้งหมดจะกลายเป็นลิงค์ .... ลอง
ดู

ถ้าคุณใส่ลิงค์ในกล่องมันจะยังคงลิงค์ออก .. ถูกต้อง?
David Chase

2
ไม่มีงานของ jsfiddle สำหรับฉัน Chrome 20 มี.ค. 2557
อ้างอิง

7

นี่คือวิธีที่ฉันทำกับ bootstrap popover ด้วยความช่วยเหลือของบิตอื่น ๆ ในเน็ต รับชื่อและเนื้อหาแบบไดนามิกจากผลิตภัณฑ์ต่างๆที่แสดงบนไซต์ ผลิตภัณฑ์หรือป๊อปโอเวอร์แต่ละรายการจะได้รับรหัสที่ไม่ซ้ำกัน Popover จะหายไปเมื่อออกจากผลิตภัณฑ์ ($ this .pop) หรือ popover หมดเวลาใช้ซึ่งจะแสดงป๊อปโอเวอร์จนกว่าจะออกจากผลิตภัณฑ์แทนที่จะเป็นป๊อปโอเวอร์

$(".pop").each(function () {
        var $pElem = $(this);
        $pElem.popover(
            {
                html: true,
                trigger: "manual",
                title: getPopoverTitle($pElem.attr("id")),
                content: getPopoverContent($pElem.attr("id")),
                container: 'body',
                animation:false
            }
        );
    }).on("mouseenter", function () {
        var _this = this;
        $(this).popover("show");
        console.log("mouse entered");
        $(".popover").on("mouseleave", function () {
            $(_this).popover('hide');
        });
    }).on("mouseleave", function () {
        var _this = this;
        setTimeout(function () {
            if (!$(".popover:hover").length) {
                $(_this).popover("hide");
            }
        }, 100);
    });
    function getPopoverTitle(target) {
        return $("#" + target + "_content > h3.popover-title").html();
    };

    function getPopoverContent(target) {
        return $("#" + target + "_content > div.popover-content").html();
    };

สิ่งนี้จะใช้ได้เช่นกันหากป๊อปโอเวอร์ไม่ใช่ลูกขององค์ประกอบเป้าหมาย +1
Taha Paksu

6

นี่คือวิธีแก้ปัญหาที่ฉันคิดขึ้นซึ่งดูเหมือนว่าจะทำงานได้ดีในขณะเดียวกันก็อนุญาตให้คุณใช้การใช้งาน Bootstrap ตามปกติเพื่อเปิดป๊อปโอเวอร์ทั้งหมด

ต้นฉบับซอ: https://jsfiddle.net/eXpressive/hfear592/

ถามคำถามนี้:

<a href="#" id="example" class="btn btn-danger" rel="popover" >hover for popover</a>

$('#example').popover({
    html : true,
    trigger : 'hover',
    content : function() {
        return '<div class="box"></div>';
    }
}).on('hide.bs.popover', function () {
    if ($(".popover:hover").length) {
      return false;
    }                
}); 

$('body').on('mouseleave', '.popover', function(){
    $('.popover').popover('hide');
});

2

ฉันยอมรับว่าวิธีที่ดีที่สุดคือใช้วิธีที่David Chase , Cu Ly และคนอื่น ๆ มอบให้ซึ่งวิธีที่ง่ายที่สุดในการทำเช่นนี้คือการใช้container: $(this)คุณสมบัติดังต่อไปนี้:

$(selectorString).each(
  var $this = $(this);
  $this.popover({
    html: true,
    placement: "top",
    container: $this,
    trigger: "hover",
    title: "Popover",
    content: "Hey, you hovered on element"
  });
);

ผมอยากจะชี้ให้เห็นว่าที่นี่ popover ในกรณีนี้จะสืบทอดคุณสมบัติทั้งหมดขององค์ประกอบปัจจุบัน ตัวอย่างเช่นหากคุณทำสิ่งนี้สำหรับ.btnองค์ประกอบ (bootstrap) คุณจะไม่สามารถเลือกข้อความภายในป๊อปโอเวอร์ได้ แค่อยากจะบันทึกว่าตั้งแต่ฉันใช้เวลาพอสมควรในการต่อสู้กับเรื่องนี้


1

คำตอบของ Vikas ทำงานได้อย่างสมบูรณ์แบบสำหรับฉันที่นี่ฉันยังเพิ่มการรองรับสำหรับการหน่วงเวลา (แสดง / ซ่อน)

var popover = $('#example');
var options = {
    animation : true,
    html: true,
    trigger: 'manual',
    placement: 'right',
    delay: {show: 500, hide: 100}
};   
popover
    .popover(options)
    .on("mouseenter", function () {

        var t = this;
        var popover = $(this);    
        setTimeout(function () {

            if (popover.is(":hover")) {

                popover.popover("show");
                popover.siblings(".popover").on("mouseleave", function () {
                    $(t).popover('hide');
                });
            }
        }, options.delay.show);
    })
    .on("mouseleave", function () {
        var t = this;
        var popover = $(this);

        setTimeout(function () {
            if (popover.siblings(".popover").length && !popover.siblings(".popover").is(":hover")) {
                $(t).popover("hide")
            }
        }, options.delay.hide);
    });     

โปรดให้ความสนใจฉันเปลี่ยน:

if (!$(".popover:hover").length) {

ด้วย:

if (popover.siblings(".popover").length && !popover.siblings(".popover").is(":hover")) {

เพื่อให้อ้างอิงตรงกับที่เปิดป๊อปโอเวอร์นั้นและไม่อ้างอิงอื่น ๆ (ตั้งแต่ตอนนี้ด้วยความล่าช้าอาจเปิดได้มากกว่า 1 ในเวลาเดียวกัน)


ความคิดเห็นที่ฉันทำในตอนท้ายไม่ถูกต้องจริง ๆ เมื่อใช้ container: body ถ้ายังคงต้องใช้วิธีแก้ปัญหาของ Vikas สำหรับหนึ่งบรรทัด
user1993198

1

คำตอบที่เลือกใช้งานได้แต่จะล้มเหลวหากป็อปโอเวอร์เริ่มต้นด้วยbodyas the container

$('a').popover({ container: 'body' });

วิธีแก้ปัญหาตามคำตอบที่เลือกคือรหัสต่อไปนี้ที่ต้องวางไว้ก่อนใช้ป๊อปโอเวอร์

var originalLeave = $.fn.popover.Constructor.prototype.leave;
$.fn.popover.Constructor.prototype.leave = function(obj) {
    var self = obj instanceof this.constructor ? obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type);
    originalLeave.call(this, obj);

    if (obj.currentTarget) {
        self.$tip.one('mouseenter', function() {
            clearTimeout(self.timeout);
            self.$tip.one('mouseleave', function() {
                $.fn.popover.Constructor.prototype.leave.call(self, self);
            });
        })
    }
};

การเปลี่ยนแปลงเพียงเล็กน้อยโดยใช้self.$tipแทนการข้ามผ่าน DOM โดยคาดว่า popover จะเป็นพี่น้องขององค์ประกอบเสมอ


0

สิ่งเดียวกันสำหรับคำแนะนำเครื่องมือ:

สำหรับฉันวิธีแก้ปัญหาต่อไปนี้ใช้งานได้เพราะไม่ได้เพิ่มผู้ฟังเหตุการณ์ใน 'mouseenter' ทุกตัวและเป็นไปได้ที่จะเลื่อนกลับไปที่องค์ประกอบคำแนะนำเครื่องมือซึ่งช่วยให้คำแนะนำเครื่องมือมีชีวิตอยู่

$ ->

  $('.element').tooltip({
    html: true,
    trigger: 'manual'
  }).
  on 'mouseenter', ->
    clearTimeout window.tooltipTimeout
    $(this).tooltip('show') unless $('.tooltip:visible').length > 0
  .
  on 'mouseleave', ->
    _this = this
    window.tooltipTimeout = setTimeout ->
      $(_this).tooltip('hide')
    , 100

$(document).on 'mouseenter', '.tooltip', ->
  clearTimeout window.tooltipTimeout

$(document).on 'mouseleave', '.tooltip', ->
  trigger = $($(this).siblings('.element')[0])
  window.tooltipTimeout = setTimeout ->
    trigger.tooltip('hide')
  , 100

0

วิธีนี้ใช้ได้ผลดีสำหรับฉัน: (ตอนนี้มันกันกระสุนได้) ;-)

function enableThumbPopover() {
    var counter;

    $('.thumbcontainer').popover({
        trigger: 'manual',
        animation: false,
        html: true,
        title: function () {
            return $(this).parent().find('.thumbPopover > .title').html();
        },
        content: function () {
            return $(this).parent().find('.thumbPopover > .body').html();
        },
        container: 'body',
        placement: 'auto'
    }).on("mouseenter",function () {
        var _this = this; // thumbcontainer

        console.log('thumbcontainer mouseenter')
        // clear the counter
        clearTimeout(counter);
        // Close all other Popovers
        $('.thumbcontainer').not(_this).popover('hide');

        // start new timeout to show popover
        counter = setTimeout(function(){
            if($(_this).is(':hover'))
            {
                $(_this).popover("show");
            }
            $(".popover").on("mouseleave", function () {
                $('.thumbcontainer').popover('hide');
            });
        }, 400);

    }).on("mouseleave", function () {
        var _this = this;

        setTimeout(function () {
            if (!$(".popover:hover").length) {
                if(!$(this).is(':hover'))
                {
                    $(_this).popover('hide');
                }
            }
        }, 200);
    });
}

0
        $(function() {
            $("[data-toggle = 'popover']").popover({
                placement: 'left',
                html: true,
                trigger: "  focus",
            }).on("mouseenter", function() {
                var _this = this;
                $(this).popover("show");
                $(this).siblings(".popover").on("mouseleave", function() {
                    $(_this).popover('hide');
                });
            }).on("mouseleave", function() {
                var _this = this;
                setTimeout(function() {
                    if (!$(".popover:hover").length) {
                        $(_this).popover("hide")
                    }
                }, 100);
            });
        }); 

0

ฉันพบว่าmouseleaveไฟจะไม่ทำงานเมื่อมีสิ่งแปลก ๆ เกิดขึ้นเช่นโฟกัสของหน้าต่างเปลี่ยนกะทันหันจากนั้นผู้ใช้กลับมาที่เบราว์เซอร์ ในกรณีเช่นนี้mouseleaveจะไม่เริ่มทำงานจนกว่าเคอร์เซอร์จะไปและออกจากองค์ประกอบอีกครั้ง

การแก้ปัญหานี้ฉันมากับอาศัยอยู่mouseenterบนwindowวัตถุดังนั้นมันจะหายไปเมื่อเมาส์ถูกย้ายไปที่ใดบนหน้าเว็บ

สิ่งนี้ได้รับการออกแบบมาเพื่อทำงานกับการมีองค์ประกอบหลายอย่างในหน้าเว็บที่จะเรียกใช้ (เช่นในตาราง)

var allMenus = $(".menus");
allMenus.popover({
    html: true,
    trigger: "manual",
    placement: "bottom",
    content: $("#menuContent")[0].outerHTML
}).on("mouseenter", (e) => {
    allMenus.not(e.target).popover("hide");
    $(e.target).popover("show");
    e.stopPropagation();
}).on("shown.bs.popover", () => {
    $(window).on("mouseenter.hidepopover", (e) => {
        if ($(e.target).parents(".popover").length === 0) {
            allMenus.popover("hide");
            $(window).off("mouseenter.hidepopover");
        }
    });
});

0

จะมีความยืดหยุ่นมากขึ้นด้วยhover():

$(".my-popover").hover(
    function() {  // mouse in event
        $this = $(this);
        $this.popover({
            html: true,
            content: "Your content",
            trigger: "manual",
            animation: false
            });
        $this.popover("show");
        $(".popover").on("mouseleave", function() {
            $this.popover("hide");
        });
    },
    function() {  // mouse out event
        setTimeout(function() {
            if (!$(".popover:hover").length) {
                $this.popover("hide");
            }
        }, 100);
    } 
)

0

เรียบง่าย :)

$('[data-toggle="popover"]').popover( { "container":"body", "trigger":"focus", "html":true });
$('[data-toggle="popover"]').mouseenter(function(){
    $(this).trigger('focus');
});

0

เมื่อเร็ว ๆ นี้ฉันต้องการให้สิ่งนี้ทำงานร่วมกับ KO และโซลูชันข้างต้นทำงานได้ไม่ดีเมื่อมีความล่าช้าในการแสดงและซ่อน ด้านล่างควรแก้ไขปัญหานี้ ขึ้นอยู่กับวิธีการทำงานของคำแนะนำเครื่องมือ bootstrap หวังว่านี่จะช่วยใครบางคนได้

var options = {
                delay: { show: 1000, hide: 50 },
                trigger: 'manual',                      
                html: true
            };
var $popover = $(element).popover(options);

$popover.on('mouseenter', function () { // This is entering the triggering element
    var self = this;

    clearTimeout(self.timeout);
    self.hoverState = 'in';

    self.timeout = setTimeout(function () {
        if (self.hoverState == 'in') {
            $(self).popover("show");

            $(".popover, .popover *").on('mouseover', function () { // This is moving over the popover
                clearTimeout(self.timeout);
            });                                                                 

            $(".popover").on('mouseleave', function () { // This is leaving the popover
                self.timeout = setTimeout(function () {
                    if (self.hoverState == 'out') {
                        $(self).popover('hide');
                    }
                }, options.delay.hide);
            });
        }
    }, options.delay.show);
}).on('mouseleave', function (event) { // This is leaving the triggering element
    var self = this;

    clearTimeout(self.timeout);
    self.hoverState = 'out';

    self.timeout = setTimeout(function () {                             
        if (self.hoverState == 'out') {
            $(self).popover('hide');
        }

    }, options.delay.hide);
});

-1

นี่คือรหัสของฉันสำหรับแสดงคำแนะนำเครื่องมือพลศาสตร์ที่มีความล่าช้าและโหลดโดย ajax

$(window).on('load', function () {
    generatePopovers();
    
    $.fn.dataTable.tables({ visible: true, api: true }).on('draw.dt', function () {
        generatePopovers();
    });
});

$(document).ajaxStop(function () {
    generatePopovers();
});

function generatePopovers() {
var popover = $('a[href*="../Something.aspx"]'); //locate the elements to popover

popover.each(function (index) {
    var poplink = $(this);
    if (poplink.attr("data-toggle") == null) {
        console.log("RENDER POPOVER: " + poplink.attr('href'));
        poplink.attr("data-toggle", "popover");
        poplink.attr("data-html", "true");
        poplink.attr("data-placement", "top");
        poplink.attr("data-content", "Loading...");
        poplink.popover({
            animation: false,
            html: true,
            trigger: 'manual',
            container: 'body',
            placement: 'top'
        }).on("mouseenter", function () {
            var thispoplink = poplink;
            setTimeout(function () {
                if (thispoplink.is(":hover")) {
                    thispoplink.popover("show");
                    loadDynamicData(thispoplink); //load data by ajax if you want
                    $('body .popover').on("mouseleave", function () {
                        thispoplink.popover('hide');
                    });
                }
            }, 1000);
        }).on("mouseleave", function () {
            var thispoplink = poplink;
            setTimeout(function () {
                if (!$("body").find(".popover:hover").length) {
                    thispoplink.popover("hide");
                }
            }, 100);
        });
    }
});

function loadDynamicData(popover) {
    var params = new Object();
    params.somedata = popover.attr("href").split("somedata=")[1]; //obtain a parameter to send
    params = JSON.stringify(params);
    //check if the content is not seted
    if (popover.attr("data-content") == "Loading...") {
        $.ajax({
            type: "POST",
            url: "../Default.aspx/ObtainData",
            data: params,
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            success: function (data) {
                console.log(JSON.parse(data.d));
                var dato = JSON.parse(data.d);
                if (dato != null) {
                    popover.attr("data-content",dato.something); // here you can set the data returned
                    if (popover.is(":hover")) {
                        popover.popover("show"); //use this for reload the view
                    }
                }
            },

            failure: function (data) {
                itShowError("- Error AJAX.<br>");
            }
        });
    }
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.