Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing scroll when using URI hash to identify tab

I'm using JQuery UI to make tabs in my application. I needed the tabs to be linkable (direct link that opens the page and selects the correct tab). This is done by using a hash tag/fragmented identifier. But I have a issue when the content above the tabs and inside the tabs is very long.

When clicking the tabs, the page scrolls down to the start of the tab. This is not what I want.

I'm using Jquery 1.7.1 and Jquery UI 1.8.16.

The javascript/Jquery code is a standard Jquery UI tabs with the addition to the event "tabsshow". This is suggested in Changing location.hash with jquery ui tabs (Stackoverflow question) and JQuery UI Tabs: Updating URL with hash while clicking the tab (blog - Tech Diary by 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;
    });
});

The following HTML can be used to test the behavior

<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>

When opening the page with the following URL, one should have tab 1 opened and not scroll down to where the tab starts. The same goes for clicking on one of the tabs.

file.html#tab_1
like image 963
HNygard Avatar asked Dec 24 '11 12:12

HNygard


3 Answers

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_', '');
});
like image 158
Mottie Avatar answered Nov 20 '22 17:11

Mottie


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_", "");
  },
});
like image 41
JamesWilson Avatar answered Nov 20 '22 17:11

JamesWilson


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/

like image 5
leclaeli Avatar answered Nov 20 '22 17:11

leclaeli