¿Cómo deshabilitar el anclaje "jump" al cargar una página?


Creo que esto puede no ser posible, voy a tratar de explicar lo mejor que pueda. Tengo una página que contiene pestañas (jquery powered), controlado por lo siguiente:

Estoy usando este código, como lo proporcionó otro usuario de una pregunta anterior.

<script type="text/javascript">
    $(function() {

     $('html, body').animate({scrollTop:0}); // this is my "fix"

        var tabContent = $(".tab_content");
        var tabs = $("#menu li");
        var hash = window.location.hash;
     tabContent.not(hash).hide();
        if(hash=="") {
      $('#tab1').fadeIn();
     }
        tabs.find('[href=' + hash + ']').parent().addClass('active');

        tabs.click(function() {
            $(this).addClass('active').siblings().removeClass('active');
            tabContent.hide();
            var activeTab = $(this).find("a").attr("href");

            $(activeTab).fadeIn();
           return false;
        });

    });
</script>

Este código funciona muy bien cuando visito la página "pestañas" directamente.

Sin embargo, necesito enlazar a pestañas individuales desde otras páginas, así que para hacer esto, el código obtiene el window.location.hash y luego muestra la pestaña apropiada.

La página no "jump" to the anchor because of"return false".

Sin embargo, este evento solo se activa en un evento de clic. por lo tanto, si visito mis "pestañas" desde cualquier otra página, se activa el efecto "salto". Para combatir esto me desplazo automáticamente a la parte superior de la página, pero preferiría que esto no sucediera.

¿Hay alguna forma de simular "return false" cuando se carga la página, evitando que se produzca el "salto" de anclaje?

Espero que esto sea lo suficientemente claro.

Gracias

Author: Rubens Mariuzzo, 2010-09-07

14 answers

¿No funciona tu arreglo? No estoy seguro de si entiendo la pregunta correctamente - ¿tiene una página de demostración? Puedes probar:

if (location.hash) {
  setTimeout(function() {

    window.scrollTo(0, 0);
  }, 1);
}

Editar: probado y funciona en Firefox, IE y Chrome en Windows.
Editar 2: mover setTimeout() dentro del bloque if, props @vsync.

 129
Author: dave1010,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-10 08:07:09

Vea mi respuesta aquí: Respuesta de Stackoverflow

El truco es simplemente eliminar el hashtag LO antes posible y almacenar su valor para su propio uso:

Es importante que no pongas esa parte del código en la ventana $() o window ().load () funciona como si fuera demasiado tarde y el navegador ya se ha movido a la etiqueta.

// store the hash (DON'T put this code inside the $() function, it has to be executed 
// right away before the browser can start scrolling!
var target = window.location.hash,
    target = target.replace('#', '');

// delete hash so the page won't scroll to it
window.location.hash = "";

// now whenever you are ready do whatever you want
// (in this case I use jQuery to scroll to the tag after the page has loaded)
$(window).on('load', function() {
    if (target) {
        $('html, body').animate({
            scrollTop: $("#" + target).offset().top
        }, 700, 'swing', function () {});
    }
});
 28
Author: Larzan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-18 11:55:53

Hay otras formas de rastrear en qué pestaña se encuentra; tal vez establecer una cookie, o un valor en un campo oculto, etc, etc.

Yo diría que si no desea que la página salte de carga, sería mejor usar una de estas otras opciones en lugar del hash, porque la razón principal para usar el hash en lugar de ellos es permitir exactamente lo que desea bloquear.

Otro punto - la página no saltará si sus enlaces hash no coinciden con los nombres de las etiquetas en el documento, así que tal vez si quieres seguir usando el hash podrías manipular el contenido para que las etiquetas tengan un nombre diferente. Si usa un prefijo consistente, aún podrá usar Javascript para saltar entre ese prefijo.

Espero que eso ayude.

 11
Author: Spudley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-07 13:43:18

Usé la solución de dave1010, pero estaba un poco nerviosa cuando la puse dentro del $().función lista. Así que hice esto: (no dentro del $().listo)

    if (location.hash) {               // do the test straight away
        window.scrollTo(0, 0);         // execute it straight away
        setTimeout(function() {
            window.scrollTo(0, 0);     // run it a bit later also for browser compatibility
        }, 1);
    }
 11
Author: lopsided,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-12 18:58:13
  1. El navegador salta a <element id="abc" /> si hay http://site.com/#abc hash en la dirección y el elemento con id="abc" es visible. Por lo tanto, solo debe ocultar el elemento por defecto: <element id="anchor" style="display: none" />. Si no hay ningún elemento visible con id = hash en la página, el navegador no saltará.

  2. Cree un script que compruebe el hash en la url y, a continuación, encuentre y muestre el elemento prrpopriate (que está oculto de forma predeterminada).

  3. Desactivar el comportamiento predeterminado "hash-like link" por enlazar un evento onclick a un enlace y especificar return false; como resultado del evento onclick.

Cuando implementé tabs, escribí algo así:

    <script>
    $(function () {         
        if (location.hash != "") {
            selectPersonalTab(location.hash);
        }
        else {
            selectPersonalTab("#cards");
        }
    });

    function selectPersonalTab(hash) {
        $("#personal li").removeClass("active");
        $("a[href$=" + hash + "]").closest("li").addClass("active");
        $("#personaldata > div").hide();
        location.hash = hash;
        $(hash).show();
    }

    $("#personal li a").click(function (e) {
        var t = e.target;
        if (t.href.indexOf("#") != -1) {
            var hash = t.href.substr(t.href.indexOf("#"));
            selectPersonalTab(hash);
            return false;
        }
    });
</script>
 8
Author: Sergei Smirnov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-30 14:59:03

Dirty CSS solo soluciona que se desplace hacia arriba cada vez que se usa el ancla (no es útil si todavía desea usar anclas para saltos de desplazamiento, muy útil para enlaces profundos):

.elementsWithAnchorIds::before {
   content: "";
   display: block;
   height: 9999px;
   margin-top: -9999px; //higher thin page height
}
 3
Author: anotheryou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-23 17:31:32

Ninguna de las respuestas no funciona lo suficientemente bien para mí, veo que la página salta para anclar y luego para arriba para algunas soluciones, algunas respuestas no funcionan en absoluto, pueden ser cosas cambiadas durante años. Espero que mi función ayude a alguien.

/**
 * Prevent automatic scrolling of page to anchor by browser after loading of page.
 * Do not call this function in $(...) or $(window).on('load', ...),
 * it should be called earlier, as soon as possible.
 */
function preventAnchorScroll() {
    var scrollToTop = function () {
        $(window).scrollTop(0);
    };
    if (window.location.hash) {
        // handler is executed at most once
        $(window).one('scroll', scrollToTop);
    }

    // make sure to release scroll 1 second after document readiness
    // to avoid negative UX
    $(function () {
        setTimeout(
            function () {
                $(window).off('scroll', scrollToTop);
            },
            1000
        );
    });
}
 3
Author: kdmitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-02 13:55:09

Si bien la respuesta aceptada funciona bien, encontré que a veces, especialmente en páginas que contienen imágenes grandes, la barra de desplazamiento saltará salvajemente usando

 window.scrollTo(0, 0);

Que puede ser bastante molesto para el usuario.

La solución que decidí al final es en realidad bastante simple, y eso es usar un ID diferente en el objetivo al utilizado en location.hash

Eg:

Aquí está el enlace en alguna otra página

<a href="/page/with/tabs#tab2">Some info found in tab2 on tabs page</a>

Así que, por supuesto, si hay un elemento con un ID de tab2 en la página de pestañas, la ventana saltará a ella al cargarse.

Así que puedes añadir algo al ID para evitarlo:

<div id="tab2-noScroll">tab2 content</div>

Y luego puedes añadir "-noScroll" a location.hash en javascript:

<script type="text/javascript">
    $(function() {

        var tabContent = $(".tab_content");
        var tabs = $("#menu li");
        var hash = window.location.hash;


     tabContent.not(hash + '-noScroll').hide();                           
        if(hash=="") {       //^ here
      $('#tab1-noScroll').fadeIn();
     }
        tabs.find('[href=' + hash + ']').parent().addClass('active');

        tabs.click(function() {
            $(this).addClass('active').siblings().removeClass('active');
            tabContent.hide();
            var activeTab = $(this).find("a").attr("href") + '-noScroll'; 
                                                               //^ and here

            $(activeTab).fadeIn();
           return false;
        });

    });
</script>
 2
Author: andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-17 13:08:26

Creo que he encontrado una manera de pestañas de interfaz de usuario sin rehacer la funcionalidad. Hasta ahora no he encontrado ningún problema.

    $( ".tabs" ).tabs();
    $( ".tabs" ).not(".noHash").bind("tabsshow", function(event, ui) { 
        window.location.hash = "tab_"+ui.tab.hash.replace(/#/,"");
        return false;
    });

    var selectedTabHash = window.location.hash.replace(/tab_/,"");
    var index = $( ".tabs li a" ).index($(".tabs li a[href='"+selectedTabHash+"']"));
    $( ".tabs" ).not(".noHash").tabs('select', index);

Todo dentro de un evento listo. Antepone "tab_" para el hash pero funciona tanto cuando se hace clic como cuando se carga la página con hash.

 1
Author: JRomero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-09 14:23:55

Otro enfoque

Intente comprobar si la página se ha desplazado y solo entonces restablezca la posición:

var scrolled = false;

$(window).scroll(function(){
  scrolled = true;
});

if ( window.location.hash && scrolled ) {
  $(window).scrollTop( 0 );
}

Heres una demo

 0
Author: hitautodestruct,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-16 15:14:28

No tuve mucho éxito con los métodos anteriores setTimeout en Firefox.

En lugar de un setTimeout, he usado una función onload:

window.onload = function () {
    if (location.hash) {
        window.scrollTo(0, 0);
    }
};

Sigue siendo muy defectuoso, por desgracia.

 0
Author: bozdoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 19:38:06

No he tenido ningún éxito consistente con estas soluciones.

Aparentemente debido al hecho de que el salto ocurre antes de Javascript = > referencia ( http://forum.jquery.com/topic/preventing-anchor-jump )

Mi solución es colocar todos los anclajes en la parte superior por defecto con CSS.

.scroll-target{position:fixed;top:0;left:0;}

Luego use jquery para desplazarse hasta el padre del ancla de destino, o un hermano(tal vez una etiqueta em vacía)

<a class="scroll-target" name="section3"></a><em>&nbsp</em>

Jquery ejemplo de desplazamiento para cuando se introduce la URL con hash
(la página no debe estar ya cargada en la ventana / pestaña, esto cubre enlaces de otras fuentes / externas)

setTimeout(function() {
    if (window.location.hash) {               
        var hash = window.location.hash.substr(1);   
        var scrollPos = $('.scroll-target[name="'+hash+'"]').siblings('em').offset().top; 
        $("html, body").animate({ scrollTop: scrollPos }, 1000);    
    }
}, 1);

También querrá evitar los clics de anclaje predeterminados mientras está en la página y luego desplazarse a sus objetivos

<a class="scroll-to" href="#section3">section three</a>

Y jquery

$('a.scroll-to').click(function(){
    var target = $(this).attr('href').substr(1);
    var scrollPos = $('.scroll-target[name="'+target+'"]').siblings('em').offset().top; 
    $("html, body").animate({ scrollTop: scrollPos }, 1000);
    return false;
});

Lo bueno de este método es que los destinos de etiquetas de anclaje permanecen estructuralmente al lado del contenido relevante, aunque su posición CSS está en la parte superior.

Esto debería significar que los rastreadores de motores de búsqueda no tendrán un problema.

Saludos, espero que esto ayude
Gray

 0
Author: grayskale.com,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-29 21:48:24

Intente esto para evitar que el cliente realice cualquier tipo de desplazamiento vertical en hashchanged (dentro de su controlador de eventos):

var sct = document.body.scrollTop;
document.location.hash = '#next'; // or other manipulation
document.body.scrollTop = sct;

(redibujado del navegador)

 0
Author: andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-17 19:23:03

Resuelto mi promlem haciendo esto:

// navbar height 
var navHeigth = $('nav.navbar').height();    

// Scroll to anchor function
var scrollToAnchor = function(hash) {
  // If got a hash
  if (hash) {
    // Scroll to the top (prevention for Chrome)
    window.scrollTo(0, 0);
    // Anchor element
    var term = $(hash);

    // If element with hash id is defined
    if (term) {

      // Get top offset, including header height
      var scrollto = term.offset().top - navHeigth;

      // Capture id value
      var id = term.attr('id');
      // Capture name value
      var name = term.attr('name');

      // Remove attributes for FF scroll prevention
      term.removeAttr('id').removeAttr('name');
      // Scroll to element
      $('html, body').animate({scrollTop:scrollto}, 0);

      // Returning id and name after .5sec for the next scroll
      setTimeout(function() {
        term.attr('id', id).attr('name', name);
      }, 500);
    }
  }
};

// if we are opening the page by url
if (location.hash) {
  scrollToAnchor(location.hash);
}

// preventing default click on links with an anchor
$('a[href*="#"]').click(function(e) {
  e.preventDefault();
  // hash value
  var hash = this.href.substr(this.href.indexOf("#"));
  scrollToAnchor(hash);
});`
 0
Author: xottabych007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-14 12:20:05