Preventing scroll when using URI hash to identify tab

僤鯓⒐⒋嵵緔 提交于 2019-11-28 13:23:27

This may not be the best method, but if you rename all of the ID's after the tabs have been created, then adding a hash with the original ID won't scroll the page. I used this method because even with javascript disabled, the hash will take the user to the correct ID. Here is a demo of the code below:

$("#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_', '');
});

As others have mentioned the code from @Mottie might have once worked on older versions of jQuery UI, but this has definitely stopped working. The jQuery UI Tabs api has changed quite a bit since that was written so here is an updated version that works with at least jQuery 1.10.2

Demo here: 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_", "");
  },
});
eleclair

I'm using jQuery 1.11.1. This workes nicely for me.

$("#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

Thanks to Jeff B for pointing me here http://jsfiddle.net/jtbowden/ZsUBz/44/

manish_s

You have to change the window hash without scrolling the page. Here is already a question on SO - Modifying document.location.hash without page scrolling.

The changes required are:

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

The setHashWithoutScroll function can be taken from the above mentioned link.

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 );
    }
}

The accepted answer throws an error to me - jQuery UI Tabs: Mismatching fragment identifier. So I had to use this one.

Rich

I just added the following to my 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);

In MSIE, I get a brief FOUC effect as the page loads scrolled part-way-down, then flicks to the top.

In Firefox, this works fine without any visible FOUC.

In Chrome, this doesn't work at all -- see scrollTop does not work in Chrome, nor do suggested workarounds

This simple method worked for me:

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

I tried @mottie solution but is not working now (2 years after).
It triggers an error: TypeError: tabs is undefined.

Following is an acceptable solution for me:

// 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 });
});

There are many answers on this page, and in my mind, most are overcomplicating a simple issue.

Basically, the solution from david-thomas is the simplest and most effective. Essentially, all you want to be doing is preventing the default link behaviour on a tab link (<a> tag).

The same answer applies to the bootstrap tabs, where you have to specify the click handler

   $('.nav-tabs a').click(function(e){
        e.preventDefault();
        $(this).tab('show');
    });
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!