加载页面时如何禁用锚“跳转”?

我认为这可能是不可能的,将尽力解释,我可以。 我有一个包含选项卡(jquery 驱动)的页面,由以下内容控制:

我正在使用这段代码,由前一个问题中的另一个用户提供。

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

当我直接访问“选项卡”页面时,这段代码工作得很好。

但是,我需要从其他页面链接到单独的选项卡-所以这样做,代码获取 window.location.hash,然后显示适当的选项卡。

页面不会因为“返回 false”而“跳转”到锚点。

但是,此事件仅在单击事件上触发。因此,如果我从任何其他页面访问我的“标签”,“跳转”效应就会被触发。为了解决这个问题,我会自动滚动到页面的顶部,但我宁愿这种情况不要发生。

有没有办法在页面加载时模拟“ return false”,防止锚“跳转”发生。

希望我说得够清楚了。

谢谢

172180 次浏览

Does your fix not work? I'm not sure if I understand the question correctly - do you have a demo page? You could try:

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


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

编辑: 在 Firefox,IE 和 Chrome 中测试并在 Windows 上工作。
编辑2: 将 setTimeout()移到 if块内,道具@vsync。

还有其他方法可以追踪你所在的标签页,比如设置 cookie,或者隐藏字段中的值等等。

我想说的是,如果你不想让页面在加载时跳转,你最好使用这些其他选项之一,而不是哈希,因为优先使用哈希的主要原因是允许你想要阻止的东西。

另一点-如果你的散列链接不匹配文档中标记的名称,页面不会跳转,所以如果你想继续使用散列,你可以操作内容,使标记的命名不同。如果您使用一致的前缀,那么您仍然可以使用 Javascript 在两者之间跳转。

Hope that helps.

我想我已经找到了一种不需要重做功能就可以实现 UI 标签的方法,到目前为止我还没有发现任何问题。

    $( ".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);

一切准备就绪。它将“ tab _”作为散列的前缀,但是在单击时和页面加载散列时都可以工作。

我使用了 dave1010的解决方案,但是当我把它放到 $()中时,它有点跳跃。就绪功能。所以我这样做: (不在 $()中。预备)

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

另一种方法

尝试检查页面是否已经滚动,然后重置位置:

var scrolled = false;


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


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

Heres a demo

  1. Browser jumps to <element id="abc" /> if there are http://site.com/#abc hash in the address and the element with id="abc" is visible. So, you just should hide the element by default: <element id="anchor" style="display: none" />. If there is no visible element with id=hash at the page, the browser would not jump.

  2. 创建一个脚本,检查 url 中的散列,然后查找并显示 prrpopriate 元素(默认情况下隐藏该元素)。

  3. 通过将一个 onclick 事件绑定到一个链接来禁用默认的“类散列链接”行为,并指定作为 onclick 事件结果的 return false;

当我实现制表符时,我写了这样的东西:

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

我在 Firefox 中使用上面的 setTimeout方法并没有取得很大的成功。

我没有使用 setTimeout,而是使用了 onload 函数:

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

很不幸,还是有点小故障。

I have not had any consistent success with these solutions.

显然是因为跳转发生在 Javascript = > 之前 参考资料(http://forum.jquery.com/topic/preventing-anchor-jump)

我的解决方案是使用 CSS 默认将所有锚定位于顶部。

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

然后使用 jquery 滚动到目标锚的父级或兄弟级(可能是一个空的 em 标记)

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

Jquery 示例,用于滚动输入带有散列的 URL
(页面不能已经装载在窗口/选项卡中,这涵盖了来自其他/外部来源的链接)

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

此外,您还需要防止默认的锚点击,而在页面上,然后滚动到他们的目标

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

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

这种方法的好处是锚标记目标,在结构上保留在相关内容之外,尽管它们的 CSS 位置在顶部。

这意味着搜索引擎爬虫不会有问题。 < br/> < br/> Cheers, I hope this helps
Gray

尝试这样做可以防止客户端在散列表更改(在您的事件处理程序中)上进行任何类型的垂直滚动:

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

(浏览器重绘)

在这里可以看到我的答案: Stackoverflow 答案

诀窍就是尽快删除标签并存储它的值供自己使用:

重要的是,不要将该部分代码放在 $()或 $(窗口)中。Load ()函数,因为为时已晚,而且浏览器已经移动到标记。

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

虽然公认的答案确实有效,但我确实发现有时候,尤其是在包含大图片的页面上,滚动条会被广泛使用

 window.scrollTo(0, 0);

这会让用户分心。

我最后决定的解决方案实际上非常简单,就是在目标上使用与 location.hash中使用的 ID 不同的 ID

例如:

Here is the link on some other page

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

So of course if there is an element with an ID of tab2 on the tabs page the window will jump to it on load.

所以你可以在 ID 后面附加一些东西来防止它:

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

然后你可以在 javascript 中将 "-noScroll"附加到 location.hash:

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

Dirty CSS 只修复了每次使用锚点时滚动的问题(如果你仍然想使用滚动跳转的锚点,这对于解除链接非常有用) :

.elementsWithAnchorIds::before {
content: "";
display: block;
height: 9999px;
margin-top: -9999px; //higher thin page height
}

通过这样做解决了我的问题:

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

没有一个答案对我来说不够好,我看到页面跳转到锚,然后到顶部的一些解决方案,有些答案根本不起作用,可能是多年来的事情发生了变化。希望我的功能能帮到某人。

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

在我的案例中,因为使用了 CSS 弹出的锚链接,我使用了这种方式:

点击保存 pageYOffset,然后将 ScrollTop 设置为:

$(document).on('click','yourtarget',function(){
var st=window.pageYOffset;
$('html, body').animate({
'scrollTop' : st
});
});

这将与引导程序 v3一起工作

$(document).ready(function() {
if ($('.nav-tabs').length) {
var hash = window.location.hash;
var hashEl = $('ul.nav a[href="' + hash + '"]');
hash && hashEl.tab('show');


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


// Change tab on hashchange
window.addEventListener('hashchange', function() {
var changedHash = window.location.hash;
changedHash && $('ul.nav a[href="' + changedHash + '"]').tab('show');
}, false);
}
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<div class="container">
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#home">Home</a></li>
<li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
</ul>


<div class="tab-content">
<div id="home" class="tab-pane fade in active">
<h3>HOME</h3>
<p>Some content.</p>
</div>
<div id="menu1" class="tab-pane fade">
<h3>Menu 1</h3>
<p>Some content in menu 1.</p>
</div>
</div>
</div>