# . The browser perceives this transition within the page, and quietly ignores the situation when there is no necessary anchor on the page, simply updating the address and history . This is exactly what we need. If you keep the state of the page inside the anchor, then you can return to it through the bookmark and you can use Back / Forward transitions (!). In this case, the base URL of the page will not change and the page will not reload.mail.google.com/mail/?shva=1 #inbox/12c5f14c01a5473c12c5f14c01a5473c is some kind of internal letter ID. document.location.hash = '#myAnchor'; <a href="#myAnchor">My Link</a> ).
grails-app/views/layouts/main.gsp <html> <head> <title><g:layoutTitle default="Grails" /></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="${resource(dir:'css',file:'main.css')}" /> <g:layoutHead /> <g:javascript library="jquery"/> <g:javascript library="application" /> </head> <body> ... %{-- --}% <div class="navbar"> <div class="navitem"> <a href="#do/receipts" class="navlink"></a> <div class="spinner" /> </div> <div class="navitem"> <a href="#do/buy" class="navlink"> </a> <div class="spinner" /> </div> <div class="navitem"> <a href="#do/feedback" class="navlink"></a> <div class="spinner" /> </div> </div> %{-- --}% <div id="pageContent"> <g:layoutBody /> </div> ... </body> </html> web-app/js/application.js // var currentState = ''; function buildURL(anchor) { return document.location.toString().substr(0, document.location.toString().indexOf('#')) + anchor.substr(1); } function clickNavLink() { // ? var href = $(this).attr('href'); // if (href == currentState) { return false; } if (document.location.hash != href) { document.location.hash = href; } // var link = this; // $(this).parent().find('.busy').show(); $(this).hide(); var targetURL = buildURL(href); currentState = href; // , $.ajax({ context:$('#pageContent'), url:targetURL, dataType:'html', method:'GET', complete: function() { // . $(link).show(); updateNavLinks(); }, success: function(data) { // "" . $('#pageContent').html(data); } }); return true; } // , / function updateNavLinks() { $('a.navlink').each(function(i) { var href = $(this).attr('href'); $(this).parent().find('.busy').hide(); if (href == currentState) { $(this).addClass('disabled'); } else { $(this).removeClass('disabled'); } }); } // . . jQuery(document).ready(function() { $('a.navlink').each(function() { $(this).click(clickNavLink); }); }); /my-app/#do/receipts => /my-app/do/receipts disabled . In CSS (which I will not give), this class will be displayed in a different color so that you can see which link is current (visited).grails-app/controllers/DoSomethingController.groovy class DoSomethingController { def receipts = { [receipts:[' ', '']] } def buy = { [places:[' ', ' â„–1']] } def feedback = { [feedback:['',' ',' , !']] } } grails-app/views/doSomething/receipts.gsp <%-- --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <meta name="layout" content="main" /> </head> <body> <h1> </h1> <ul> <g:each in="${receipts}" var="receipt"> <li>${receipt.encodeAsHTML()}</li> </g:each> </ul> </body> </html> grails-app/conf/UrlMappings.groovy class UrlMappings { static mappings = { "/do/$action?/$id?" { controller = 'doSomething' } } } Source: https://habr.com/ru/post/108611/
All Articles