【问题标题】:How to slide tabs in and out together like a carousel如何像旋转木马一样一起滑入和滑出标签
【发布时间】:2016-03-12 05:39:35
【问题描述】:

我正在尝试使 jQuery UI 选项卡中的幻灯片看起来好像它们彼此相邻并且有些连接。我想我可以通过同时运行显示和隐藏动画来实现这一点。

目前 jQuery 会先滑出当前面板,然后再滑出下一个。如何在滑出当前面板的同时滑入下一个面板?

$("#tabs").tabs({
hide:{effect:"slide", direction:"right"},
show:{effect:"slide", direction:"left"}
});

http://jsfiddle.net/CnEUh/2372/

我想同时启动hide:show: 效果,而不是一个接一个

【问题讨论】:

  • 我不明白你在问什么。如果不想要滑动效果,可以使用fadeIn/fadeOut效果吗?
  • 我正在尝试同时显示和隐藏选项卡幻灯片,以使其看起来彼此相邻。我不想使用淡入淡出效果。
  • 请注意,考虑到 JQuery UI 方法,这甚至是可能的。
  • 必须有办法。
  • 似乎你最好使用轮播,这正是这样做的。如果您愿意,您可以将控件设置为选项卡。

标签: javascript jquery css user-interface


【解决方案1】:

这是基于我原始评论的版本。

这保留了 jQuery 的标签系统,但隐藏了现有的标签。新的slidingTabs div 包含滑动选项卡,因此可以设置动画。

更新

根据请求,初始内容保持原样。

function makeTabsIntoSlidingTabs($tabs) {
  $tabs.find("div").wrapAll("<div style='display:none' />");
  $tabs.append("<div class='slidingTabs' />");
  $tabs.children("div").first().find("div").each(function(i) {
    $tabs.find(".slidingTabs").append($("<div />").addClass("tab").html($(this).html()));
  });

  $tabs.tabs({
    activate: function(event, ui) {
      var tab = $tabs.tabs("option", "active");
      $tabs.find(".slidingTabs div").first().animate({
        marginLeft: (tab * -100) + '%'
      }, 400, function() {});
    }
  });
}

makeTabsIntoSlidingTabs($("#tabs"));
.slidingTabs {
  white-space: nowrap;
  overflow-x: hidden;
}
.slidingTabs .tab {
  width: 100%;
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" />


<div id="tabs">
  <ul>
    <li><a href="#tabs-1">Tab 1</a>
    </li>
    <li><a href="#tabs-2">Tab 2</a>
    </li>
    <li><a href="#tabs-3">Tab 3</a>
    </li>
  </ul>
  <div id="tabs-1">
    <p>Content for Tab 1</p>
  </div>
  <div id="tabs-2">
    <p>Content for Tab 2</p>
  </div>
  <div id="tabs-3">
    <p>Content for Tab 3</p>
  </div>
</div>

【讨论】:

  • 每张幻灯片之间有一点间距。我尝试用 float:left 替换 display:inline-block 但这会破坏它。
  • @Shabb - 已修复。原因是因为每个 div 之间的空白。只要一个 div 结尾和另一个 div 开头之间没有间隙,那么就不会有间隙。
  • 似乎是一个不错的解决方案,虽然我会看看是否有更好的方法,主要是因为我不想更改 HTML 标记。
  • @Shabb - 无需修改原始内容的新版本。
【解决方案2】:

我认为改变 jQuery 小部件行为的正确方法是扩展它。

这样解决方案是可扩展的,为自定义留出空间,同时允许选项卡保留 ui.widget,保留 jQuery 的样式和状态控制。

$(document).ready(function() {
  // Clean whitespaces before creating tabs
  $('#tabs').cleanWhitespace();

  /* retains most of $.ui.tabs options, but now since both
   * hide & show animations are combined there's a
   * shared direction & duration
   */
  $("#tabs").customSlideTabs({
    direction: "left",
    duration: 500
  });
});


$.widget("nameSpace.customSlideTabs", $.ui.tabs, {
  _toggle: function(event, eventData) {
    var that = this,
      toShow = eventData.newPanel,
      toHide = eventData.oldPanel;

    this.running = true;

    var container = $(toHide.parent());
    var originalContainerOverflow = container.css("overflow");

    function complete() {
      container.css("overflow", originalContainerOverflow);

      eventData.newTab.closest("li").addClass("ui-tabs-active ui-state-active");
      eventData.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active");

      that.running = false;
      that._trigger("activate", event, eventData);
    }

    // start out by hiding, then showing, then completing
    if (toHide.length && toShow.length) {
      if (!this.options.duration) this.options.duration = 300;

      container.css({
        "overflow": "hidden",
        "white-space": "nowrap"
      });

      var fromX, toX;

      if (this.options.direction == "right") {
        toHide.appendTo(container);
        fromX = "-100%";
        toX = 0;
      } else {
        toShow.appendTo(container);
        fromX = 0;
        toX = "-100%";
      }

      toShow.css({
        "width": "100%",
        "box-sizing": "border-box",
        "display": "inline-block",
        "vertical-align": "top",
        "position": "relative",
        "left": fromX,
        "white-space": "wrap"
      });
      toHide.css({
        "width": "100%",
        "box-sizing": "border-box",
        "display": "inline-block",
        "vertical-align": "top",
        "position": "relative",
        "left": fromX,
        "white-space": "wrap"
      });

      toShow.animate({
        "left": toX
      }, {
        duration: that.options.duration,
        complete: function() {
          toShow.attr("style", "display: block;");
        }
      });

      toHide.animate({
        "left": toX
      }, {
        duration: that.options.duration,
        complete: function() {
          toHide.attr("style", "display: none;");
          complete();
        }
      });
    } else {
      toHide.hide();
      toShow.show();
      complete();
    }

    toHide.attr({
      "aria-expanded": "false",
      "aria-hidden": "true"
    });
    eventData.oldTab.attr("aria-selected", "false");
    // If we're switching tabs, remove the old tab from the tab order.
    // If we're opening from collapsed state, remove the previous tab from the tab order.
    // If we're collapsing, then keep the collapsing tab in the tab order.
    if (toShow.length && toHide.length) {
      eventData.oldTab.attr("tabIndex", -1);
    } else if (toShow.length) {
      this.tabs.filter(function() {
          return $(this).attr("tabIndex") === 0;
        })
        .attr("tabIndex", -1);
    }

    toShow.attr({
      "aria-expanded": "true",
      "aria-hidden": "false"
    });
    eventData.newTab.attr({
      "aria-selected": "true",
      tabIndex: 0
    });
  }
});

// Gratitues http://stackoverflow.com/a/2587356/1645830
$.fn.cleanWhitespace = function() {
  textNodes = this.contents().filter(
      function() {
        return (this.nodeType == 3 && !/\S/.test(this.nodeValue));
      })
    .remove();
  return this;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

<div id="tabs">
  <ul>
    <li><a href="#tabs-1">Tab 1</a>
    </li>
    <li><a href="#tabs-2">Tab 2</a>
    </li>
    <li><a href="#tabs-3">Tab 3</a>
    </li>
  </ul>
  <div id="tabs-1" class="tab">
    <p>Content for Tab 1</p>
  </div>
  <div id="tabs-2" class="tab">
    <p>Content for Tab 2</p>
    <p>Content for Tab 2</p>
  </div>
  <div id="tabs-3" class="tab">
    <p>Content for Tab 3</p>
  </div>
</div>
<div id="tabid"></div>

这绝不是完整的,因为它只支持左右滑动而不是 jQuery 的全套动画,但我认为这是一个很好的基础。

【讨论】:

  • 这将是一个 20 行的 JS 代码,没有 jQuery 的选项卡 + 一些 CSS 样式。你的 JS 代码野兽对于处理标签这样的小组件来说实在是太多了。
  • 好吧,我只是在回答 OP 提出的问题。他明确表示他想继续使用 jQuery 选项卡,而我展示了我所知道的最佳解决方案:使用 jQuery 建议的方法。如果你认为类似于 jQuery 的选项卡功能是 20 行 js 和“一些”CSS,那么你要么是前端大神,要么显然不知道自己在说什么。
  • 好吧。这里不需要神。真正简单的架构解决方案,JS 管理类,CSS 管理转换。
  • 好吧,这个离题的谈话持续了足够长的时间。我已经像其他人一样提出了我的解决方案。欢迎您也提供您的。
【解决方案3】:

试试这个。希望这是你需要的。我已经使用 css 过渡来实现幻灯片效果。

$(document).ready(function() {
$("#tabs").tabs({
  beforeActivate: function(event, ui) {
    var index = ui.newTab.find('a').attr('href');
    var currentPage = $(index).index();
    //530 is the width of the frame or you can say the overall width including padding and margin for the content tabs.
    $('.inner').css('left', '-' + (currentPage) * 530 + 'px');
  },
});
 
});
body {
  background-color: #eef;
}

#tabs {
  width: 95%;
  margin-left: auto;
  margin-right: auto;
  margin-top: 10px;
}

#maindiv {
  position: relative;
  overflow: hidden;
  width: 530px;
}

.inner {
  position: relative;
  display: inline-flex;
  height: 100%;
  transition: -webkit-transition: left .6s ease-in-out;
  transition: left .6s ease-in-out;
}

#tabs-1,
#tabs-2,
#tabs-3 {
  outline: solid 5px red;
  outline-offset: -5px;
  float: left;
  display: block !important;
  width: 480px;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

<div id="tabs">
  <ul>
    <li><a href="#tabs-1">Tab 1</a>
    </li>
    <li><a href="#tabs-2">Tab 2</a>
    </li>
    <li><a href="#tabs-3">Tab 3</a>
    </li>
  </ul>
  <div id="maindiv">
    <div class="inner" style="left:0px;">
      <div id="tabs-1">
        <p>Content for Tab 1</p>
      </div>
      <div id="tabs-2">
        <p>Content for Tab 2</p>
      </div>
      <div id="tabs-3">
        <p>Content for Tab 3</p>
      </div>
    </div>
  </div>
</div>
<div id="tabid"></div>

你可以查看 js fiddle Here.

【讨论】:

    【解决方案4】:

    这可能不是您要寻找的,但您始终可以寻找 jqueryui 库为您提供之外的其他解决方案。

    在这个例子中,我已经移除了幻灯片效果,我已经将你的 tabcontent divs 包装到一个带有 nowrap 的容器中,并将它们显示为内联块,因此即使你不这样做,它们也会并排站立'看不到它们(父级处为overflow:hidden),然后当您单击选项卡和 css 转换时,只需很少的 jquery 即可在此新容器中添加和删除类。

    丑得像地狱恕我直言,但这是解决方法的一个例子

    $("#tabs").tabs({
        hide:{
    
      },
        show:{
    
      }
    });
    $('#ui-id-1').click(function() {
        $('.container').removeClass("move1");
        $('.container').removeClass("move2");
    });
    $('#ui-id-2').click(function() {
        $('.container').addClass("move1");
        $('.container').removeClass("move2");    
    });
    $('#ui-id-3').click(function() {
        $('.container').addClass("move2");
    }); 
    

    JSFIDDLE

    【讨论】:

    • 它看起来可行,但方法对我来说似乎很奇怪。移动幻灯片而不是将它们滑出并不是我想要的。谢谢。
    【解决方案5】:

    不改变tabs js脚本是不可能达到这个效果的。您可以使用beforeActivate 方法的解决方法。例如:

    $("#tabs").tabs({
        hide:{effect:"slide", direction:"right"},
        beforeActivate: function( event, ui ){ui.newPanel.show("slide", { direction: "left" });}
    });
    

    但是标签定位存在问题。我为这个问题编写了快速解决方法,但我认为使用一些自定义 js 是更好的解决方案。 jsFiddle

    $("#tabs").tabs({
      hide: {
        effect: "slide",
        direction: "right"
      },
      beforeActivate: function(event, ui) {
        setTimeout(function() {
          ui.newPanel.css({
            'position': 'absolute',
            'width': '100%',
            'top': ui.oldPanel.offset().top - 11
          });
          ui.newPanel.show("slide", {
            direction: "left"
          }, function() {
            ui.newPanel.css({
              'position': 'relative',
              'width': 'auto',
              'top': 0
            });
          });
        }, 15)
      }
    });
    body {
      background-color: #eef;
    }
    #tabs {
      width: 95%;
      margin-left: auto;
      margin-right: auto;
      margin-top: 10px;
      position: relative;
      overflow: hidden;
    }
    #tabs-1,
    #tabs-2,
    #tabs-3 {
      outline: solid 5px red;
      outline-offset: -5px;
    }
    <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
    <div id="tabs">
      <ul>
        <li><a href="#tabs-1">Tab 1</a>
        </li>
        <li><a href="#tabs-2">Tab 2</a>
        </li>
        <li><a href="#tabs-3">Tab 3</a>
        </li>
      </ul>
      <div id="tabs-1">
        <p>Content for Tab 1
          <br/>
        </p>
      </div>
      <div id="tabs-2">
        <p>Content for Tab 2</p>
      </div>
      <div id="tabs-3">
        <p>Content for Tab 3</p>
      </div>
    </div>
    <div id="tabid"></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 2019-01-17
      • 2022-12-20
      相关资源
      最近更新 更多