javascript - 为什么 mouseleave 和 mouseout 不能与 Chrome 上的 bootstrap 选项卡显示事件一起使用?

标签 javascript jquery html twitter-bootstrap

我一直致力于定制 this bootstrap responsive tabs例子。我想要的是当用户将鼠标悬停在左/右箭头图标上时像 slider 一样循环选项卡。除此之外,如果用户一直将鼠标悬停在左/右箭头图标上,我还希望 slider 保持循环。我为此编写了以下代码:

(function() {


  function changeTab() {

    console.log("mouseenterd on ", $(this));

    if ($(this).closest("li").hasClass("next") && !$(this).closest("li").hasClass("hovered")) {
      $(this).closest(".nav-tabs").children("li").removeClass("hovered");
      $(this).tab('show');
    } else if ($(this).closest("li").hasClass("prev") && !$(this).closest("li").hasClass("hovered")) {
      $(this).closest(".nav-tabs").children("li").removeClass("hovered");
      $(this).tab('show');
    }
  }

  function outOfHover() {

    console.log("mouseleave on ", $(this));

    if ($(this).closest("li").hasClass("hovered")) {
      $(this).closest(".nav-tabs").children("li").removeClass("hovered");
    }

  }




  $('[data-toggle="tab"], [data-toggle="pill"]').on('mouseleave', outOfHover); //removes class hovered
  $('[data-toggle="tab"], [data-toggle="pill"]').on('mouseenter', changeTab); //runs bootstrap tabs like slider

  var triggerClickTab;
  var triggerClickCarousel;

  function triggerClick(that) {
    $(that).tab('show');
    console.log("show triggered " + " ", $(that));
  }

  $('[data-toggle="tab"], [data-toggle="pill"]').on('mouseenter', function() {
    var that = this;
    triggerClickTab = setInterval(triggerClick, 1650, that);
  });

  $('[data-toggle="tab"], [data-toggle="pill"]').on('mouseleave', function() {
    clearInterval(triggerClickTab);
  });



  $("#myCarousel .carousel-control").on('mouseenter', function() {

    if ($(this).hasClass("left")) {
      $("#myCarousel").carousel('prev');
    } else if ($(this).hasClass("right")) {
      $("#myCarousel").carousel('next');
    }

    var that = this;
    triggerClickCarousel = setInterval(triggerClick, 1650, that);
  });

  $("#myCarousel .carousel-control").on('click', function() {

    clearInterval(triggerClickCarousel);

    var that = this;
    triggerClickCarousel = setInterval(triggerClick, 1650, that)
  });

  $("#myCarousel .carousel-control").on('mouseleave', function() {
    clearInterval(triggerClickCarousel);
  });

  /* end if Condition for non-touch device finsihes here */

  $(document).on('show.bs.tab', '.nav-tabs [data-toggle="pill"], .nav-tabs [data-toggle="tab"]', function(e) {
    var $target = $(e.target);
    var $tabs = $target.closest('.nav-tabs');
    var $current = $target.closest('li');
    var $parent = $current.closest('li.dropdown');
    $current = $parent.length > 0 ? $parent : $current;
    var $next = $current.next();
    var $prev = $current.prev();

    var updateDropdownMenu = function($el, position) {
      $el
        .find('.dropdown-menu')
        .removeClass('pull-left pull-center pull-right')
        .addClass('pull-' + position);
    };

    $tabs.find('>li').removeClass('hovered');

    if ($current.hasClass("next")) {
      $next.addClass('hovered');

    } else if ($current.hasClass("prev")) {
      $prev.addClass('hovered');
    }

    $tabs.find('>li').removeClass('next prev');
    $prev.addClass('prev');
    $next.addClass('next');

    updateDropdownMenu($prev, 'left');
    updateDropdownMenu($current, 'center');
    updateDropdownMenu($next, 'right');
  });



}());
/**
 * Responsive Bootstrap Tabs by @hayatbiralem
 * 15 May 2015
 */

@media screen and (max-width: 479px) {
  .nav-tabs-responsive > li {
    display: none;
    width: 23%;
  }
  .nav-tabs-responsive > li > a {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    word-wrap: normal;
    width: 100%;
    width: 100%;
    text-align: center;
    vertical-align: top;
  }
  .nav-tabs-responsive > li.active {
    width: 54%;
  }
  .nav-tabs-responsive > li.active:first-child {
    margin-left: 23%;
  }
  .nav-tabs-responsive > li.active,
  .nav-tabs-responsive > li.prev,
  .nav-tabs-responsive > li.next {
    display: block;
  }
  .nav-tabs-responsive > li.prev,
  .nav-tabs-responsive > li.next {
    -webkit-transform: scale(0.9);
    transform: scale(0.9);
  }
  .nav-tabs-responsive > li.next > a,
  .nav-tabs-responsive > li.prev > a {
    -webkit-transition: none;
    transition: none;
  }
  .nav-tabs-responsive > li.next > a .text,
  .nav-tabs-responsive > li.prev > a .text {
    display: none;
  }
  .nav-tabs-responsive > li.next > a:after,
  .nav-tabs-responsive > li.next > a:after,
  .nav-tabs-responsive > li.prev > a:after,
  .nav-tabs-responsive > li.prev > a:after {
    position: relative;
    top: 1px;
    display: inline-block;
    font-family: 'Glyphicons Halflings';
    font-style: normal;
    font-weight: 400;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  .nav-tabs-responsive > li.prev > a:after {
    content: "\e079";
  }
  .nav-tabs-responsive > li.next > a:after {
    content: "\e080";
  }
  .nav-tabs-responsive > li.dropdown > a > .caret {
    display: none;
  }
  .nav-tabs-responsive > li.dropdown > a:after {
    content: "\e114";
  }
  .nav-tabs-responsive > li.dropdown.active > a:after {
    display: none;
  }
  .nav-tabs-responsive > li.dropdown.active > a > .caret {
    display: inline-block;
  }
  .nav-tabs-responsive > li.dropdown .dropdown-menu.pull-xs-left {
    left: 0;
    right: auto;
  }
  .nav-tabs-responsive > li.dropdown .dropdown-menu.pull-xs-center {
    right: auto;
    left: 50%;
    -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);
  }
  .nav-tabs-responsive > li.dropdown .dropdown-menu.pull-xs-right {
    left: auto;
    right: 0;
  }
}
/**
 * Demo Styles
 */

.wrapper {
  padding: 15px 0;
}
.bs-example-tabs .nav-tabs {
  margin-bottom: 15px;
}
@media (max-width: 479px) {
  #narrow-browser-alert {
    display: none;
  }
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="wrapper">
  <div class="container">
    <div id="narrow-browser-alert" class="alert alert-info text-center">
      <strong>Heads up!</strong>
      <br>Narrow your browser!</div>
    <div class="bs-example bs-example-tabs" role="tabpanel" data-example-id="togglable-tabs">
      <ul id="myTab" class="nav nav-tabs nav-tabs-responsive" role="tablist">
        <li role="presentation" class="active">
          <a href="#home" id="home-tab" role="tab" data-toggle="tab" aria-controls="home" aria-expanded="true">
            <span class="text">Home</span>
          </a>
        </li>
        <li role="presentation" class="next">
          <a href="#profile" role="tab" id="profile-tab" data-toggle="tab" aria-controls="profile">
            <span class="text">Profile</span>
          </a>
        </li>
        <li role="presentation">
          <a href="#samsa" role="tab" id="samsa-tab" data-toggle="tab" aria-controls="samsa">
            <span class="text">Metamorfoz by Franz Kafka</span>
          </a>
        </li>
        <li role="presentation">
          <a href="#samsa2" role="tab" id="samsa-tab" data-toggle="tab" aria-controls="samsa">
            <span class="text">Nup</span>
          </a>
        </li>
        <li role="presentation">
          <a href="#samsa3" role="tab" id="samsa-tab" data-toggle="tab" aria-controls="samsa">
            <span class="text">haha lol</span>
          </a>
        </li>
      </ul>
      <div id="myTabContent" class="tab-content">
        <div role="tabpanel" class="tab-pane fade in active" id="home" aria-labelledby="home-tab">
          <p>
            Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater
            eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.
          </p>
        </div>
        <div role="tabpanel" class="tab-pane fade" id="profile" aria-labelledby="profile-tab">
          <p>
            Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo
            enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio
            cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.
          </p>
        </div>

        <div role="tabpanel" class="tab-pane fade" id="samsa" aria-labelledby="samsa-tab">
          <p>
            One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.
          </p>
          <p>
            He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.
          </p>
        </div>
        <div role="tabpanel" class="tab-pane fade" id="samsa2" aria-labelledby="samsa-tab">
          <p>
            He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.
          </p>
        </div>
        <div role="tabpanel" class="tab-pane fade" id="samsa3" aria-labelledby="samsa-tab">
          <p>
            One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.
          </p>
          <p>
            He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.
          </p>
        </div>
      </div>
    </div>
  </div>
</div>

由于媒体查询,代码无法在 stackoverflow 上正常运行。请尝试这个具有完全相同代码并且工作正常的 fiddle :https://jsfiddle.net/hhtm1on3/ 请缩小输出的宽度,直到您看到左/右箭头版本的选项卡。

jsfiddle 代码在 firefox 浏览器中运行正常,但在 chrome 浏览器中运行不正常。当触发特定事件时,我在控制台中添加了注释。正如您在 firefox 上看到的那样 mouseleave 在显示每个选项卡后一直触发,但不是 chrome。 mouseout 事件也是如此。

问题:

  1. 为什么 mouseleave 和 mouseout 不能与 Chrome 上的 bootstrap tab show 事件一起使用?
  2. 解决这个问题的方法是什么?

最佳答案

众所周知,如果光标不移动,Chrome 不会处理某些鼠标事件。与 UI 重绘优化有关。

一种解决方法是在每个间隔回调上强制重绘 UI。有很多方法可以强制重绘,一种是重绘元素本身,例如:

function triggerClick(that) {                    
    $(that).tab('show').hide().show(0); // force a repaint
    console.log("show triggered " + " ", $(that));
}

参见:-updated jsFiddle-

关于javascript - 为什么 mouseleave 和 mouseout 不能与 Chrome 上的 bootstrap 选项卡显示事件一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40865281/

相关文章:

javascript - 即使在滚动后也能获得 div 的正确位置

javascript - Bootstrap 警报显示一次后不会隐藏

javascript - 如何通过jsonp读取cookie?

html - CSS Flexbox 图像不保留纵横比

javascript - jQuery 只需要改变元素中的文本内容

javascript - KML 标记失去了颜色(但仅在 js api 中)

javascript - 通过 jquery/jscript 重命名 WordPress 文件夹中的文件

javascript - 用变量预填充 HTML 值?

html - 使用 Bootstrap 时如何将图像设置为容器的背景

javascript - 使用 javascript 插件包含页脚