【问题标题】:Preventing scroll when using URI hash to identify tab使用 URI 哈希标识选项卡时防止滚动
【发布时间】:2011-12-24 12:31:14
【问题描述】:

我正在使用 JQuery UI 在我的应用程序中创建选项卡。我需要标签是可链接的(打开页面并选择正确标签的直接链接)。这是通过使用哈希标签/fragmented identifier 来完成的。但是当标签上方和标签内的内容很长时间时,我有一个问题。

单击选项卡时,页面会向下滚动到选项卡的开头。这不是我想要的。

我正在使用 Jquery 1.7.1 和 Jquery UI 1.8.16。

javascript/Jquery 代码是标准的 Jquery UI 选项卡,除了事件“tabsshow”。这是在Changing location.hash with jquery ui tabs(Stackoverflow 问题)和JQuery UI Tabs: Updating URL with hash while clicking the tab(博客 - Robin 的技术日记)中提出的建议

$(document).ready(function() {
    $("#tabs").tabs();

    /**
     * Add hash to URL of the current page
     * 
     * http://chwang.blogspot.com/2010/02/jquery-ui-tabs-updating-url-with-hash.html
     * https://stackoverflow.com/questions/570276/changing-location-hash-with-jquery-ui-tabs
     */
    $("#tabs").bind('tabsshow',function(event, ui) {
        window.location.hash = ui.tab.hash;
    });
});

以下 HTML 可用于测试行为

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<div style="height: 400px;">Some other content</div>
<div id="tabs" class="ui-tabs ui-widget ui-widget-content ui-corner-all">
    <ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">
        <li class="ui-state-default ui-corner-top"><a href="#tab_1"><span>Tab 1</span></a></li>
        <li class="ui-state-default ui-corner-top"><a href="#tab_100"><span>Tab 100</span></a></li>
        <li class="ui-state-default ui-corner-top ui-tabs-selected ui-state-active"><a href="#tab_1000"><span>Tab 1000</span></a></li>
    </ul>

    <div id="tab_1" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide">
        <table style="height: 1000px"><tr><td>Hello. This is tab 1</td></tr></table>
    </div>


    <div id="tab_100" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide">
        <table style="height: 1000px"><tr><td>Hello. This is tab 100.</td></tr></table>
    </div>


    <div id="tab_1000" class="ui-tabs-panel ui-widget-content ui-corner-bottom"><h2>Heading</h2>
        <table style="height: 1000px"><tr><td>Hello. This is tab 1000.</td></tr></table>
    </div>
</div>

使用以下 URL 打开页面时,应该打开标签 1,而不是向下滚动到标签开始的位置。单击其中一个选项卡也是如此。

file.html#tab_1

【问题讨论】:

标签: jquery jquery-ui tabs jquery-ui-tabs fragment-identifier


【解决方案1】:

这可能不是最好的方法,但是如果您在创建选项卡后重命名所有 ID,则使用原始 ID 添加哈希将不会滚动页面。我使用这种方法是因为即使禁用了 javascript,哈希也会将用户带到正确的 ID。这是下面代码的a demo

$("#tabs").tabs({
    create: function(event, ui) {
        // get tab plugin data
        var tabs = $('#tabs').data('tabs'),
            // tabs.anchors contains all of the tab anchors
            links = tabs.anchors;
        // tabs.panels contains each tab
        tabs.panels.each(function(i){
            // just adding a "mod_" prefix to every ID/hash
            this.id = 'mod_' + this.id;
            links[i].hash = '#' + this.id;
        });
    }
});

/**
 * Add hash to URL of the current page
 * 
 * http://chwang.blogspot.com/2010/02/jquery-ui-tabs-updating-url-with-hash.html
 * http://stackoverflow.com/questions/570276/changing-location-hash-with-jquery-ui-tabs
 */
$("#tabs").bind('tabsshow', function(event, ui) {
    // remove the prefix from the ID, so we're showing the original ID in the hash
    window.location.hash = ui.tab.hash.replace('mod_', '');
});

【讨论】:

    【解决方案2】:

    正如其他人所提到的,来自@Mottie 的代码可能曾经在旧版本的 jQuery UI 上工作过,但这肯定已经停止工作了。 jQuery UI Tabs api 自编写以来已经发生了很大变化,所以这里是一个更新版本,至少可以与 jQuery 1.10.2 一起使用

    在这里演示:http://jsfiddle.net/xsx5u5g2/

    var $tabs = $("#tabs");
    $tabs.tabs({
      create: function(event, ui) {
        // Adjust hashes to not affect URL when clicked.
        var widget = $tabs.data("uiTabs");
        widget.panels.each(function(i){
          this.id = "uiTab_" + this.id; // Prepend a custom string to tab id.
          widget.anchors[i].hash = "#" + this.id;
          $(widget.tabs[i]).attr("aria-controls", this.id);
        });
      },
      activate: function(event, ui) {
        // Add the original "clean" tab id to the URL hash.
        window.location.hash = ui.newPanel.attr("id").replace("uiTab_", "");
      },
    });
    

    【讨论】:

    • 我对此做了一个修改。我不希望在页面加载/创建时重命名 ID。我希望它在用户第一次单击选项卡时发生。这可确保添加书签的 URL 正常工作。我将 ID 重命名拆分为一个单独的函数,然后将其包装为“仅运行一次”构造,并将其添加为“激活”内的第一行。 davidwalsh.name/javascript-once
    【解决方案3】:

    我正在使用 jQuery 1.11.1。这对我很有效。

    $("#tabs").tabs(); //initialize tabs
    $(function() {
        $("#tabs").tabs({
            activate: function(event, ui) {
                var scrollTop = $(window).scrollTop(); // save current scroll position
                window.location.hash = ui.newPanel.attr('id'); // add hash to url
                $(window).scrollTop(scrollTop); // keep scroll at current position
            }
        });
    });
    

    jQuery UI tabs, update url when clicking on a different tab

    感谢Jeff B 指点我这里http://jsfiddle.net/jtbowden/ZsUBz/44/

    【讨论】:

    • 对我来说也很完美。对于 jQuery 版本 1.12.4。谢谢!
    【解决方案4】:

    您必须在不滚动页面的情况下更改窗口哈希。这里已经有一个关于 SO - Modifying document.location.hash without page scrolling 的问题。

    所需的更改是:

    $("#tabs").bind('tabsshow',function(event, ui) {
        setHashWithoutScroll(ui.tab.hash);
    });
    

    setHashWithoutScroll 函数可以从上述链接中获取。

    function setHashWithoutScroll(hash) {
        hash = hash.replace( /^#/, '' );
        var fx, node = $( '#' + hash );
        if ( node.length ) {
          node.attr( 'id', '' );
          fx = $( '<div></div>' )
                  .css({
                      position:'absolute',
                      visibility:'hidden',
                      top: $(document).scrollTop() + 'px'
                  })
                  .attr( 'id', hash )
                  .appendTo( document.body );
        }
        document.location.hash = hash;
        if ( node.length ) {
          fx.remove();
          node.attr( 'id', hash );
        }
    }
    

    接受的答案向我抛出了一个错误 - jQuery UI Tabs: Mismatching fragment identifier。所以我不得不使用这个。

    【讨论】:

    • 这不能修复带有“#tab-id”的入站链接,加载页面中途向下滚动
    【解决方案5】:

    我刚刚在我的 javascript 中添加了以下内容:

        $('#tabs').tabs();
        // Direct links to the tabs, e.g. /my-page#tab-id can cause browsers
        // to scroll down to half-way down the page, which is ugly. We override that here.
        // (This can cause a brief FOUC effect where the page first displays then scrolls up)
        window.scrollTop = '0';
        window.scrollTo(0,0);
    

    在 MSIE 中,我得到一个简短的 FOUC 效果,因为页面加载时部分向下滚动,然后滑动到顶部。

    在 Firefox 中,这可以正常工作,没有任何可见的 FOUC。

    在 Chrome 中,这根本不起作用——请参阅 scrollTop does not work in Chrome, nor do suggested workarounds

    【讨论】:

      【解决方案6】:

      这个简单的方法对我有用:

      /* Prevent scroll to tab on click */
      $(document).ready(function(){
        $("a.ui-tabs-anchor").click(function(e){
            e.preventDefault();
            return false;
        });
      });
      

      【讨论】:

        【解决方案7】:

        我尝试了@mottie 解决方案,但现在无法正常工作(2 年后)。
        它会触发错误:TypeError: tabs is undefined

        以下是我可以接受的解决方案:

        // preventing scroll
        // $("#tabs li a[href^='#tab']").bind('click',function(e){ // less general but better
        $("#tabs li a").bind('click',function(e){
            $("html, body").animate({ scrollTop: 0 });
        });
        

        【讨论】:

          【解决方案8】:

          这个页面上有很多答案,在我看来,大多数都把一个简单的问题复杂化了。

          基本上,来自 david-thomas 的解决方案是最简单和最有效的。本质上,您要做的只是阻止选项卡链接(&lt;a&gt; 标记)上的默认链接行为。

          同样的答案适用于引导选项卡,您必须在其中指定点击处理程序

             $('.nav-tabs a').click(function(e){
                  e.preventDefault();
                  $(this).tab('show');
              });
          

          【讨论】:

          • 感谢您富有洞察力和有用的评论。很抱歉我的回答让您的申请从高处倾倒......
          猜你喜欢
          • 2013-03-31
          • 2016-04-09
          • 1970-01-01
          • 1970-01-01
          • 2015-06-09
          • 1970-01-01
          • 1970-01-01
          • 2011-09-09
          • 2019-09-30
          相关资源
          最近更新 更多