JQuery-在加载并直接转到带有锚点的URL时获取偏移量
JQuery - Get an offset when loading and going directly to a URL with anchor
我尝试添加以下功能:当我键入带有锚的URL时,我希望直接在锚上。我的问题是,我有一个固定的头,并且我当前的JQuery代码没有考虑我放置的偏移量(55
,即the height of header
)。
以下是代码片段:
if ($(location.href.split("#")[1])) {
var target = $('#'+location.href.split("#")[1]);
if (target.length) {
var hash = this.hash;
$('html,body').animate({ scrollTop: target.offset().top - 55 }, 300, function() {
location.hash = hash;
});
}
}
此代码片段位于[ancher.js][1]脚本中。
我被很好地重定向到锚,但无论我采用什么偏移值,最终结果都不会考虑到这一点,因此在加载页面后,锚名称会被固定的标题隐藏。
如果有人能帮我解决这个问题,
提前谢谢。
ps:我只想让它在Firefox和Chrome上运行。
更新
看来解决方案可能来自这个环节。
为此,我必须在<a name="..."></a>
标记之前插入一个带有class='direct_anchor'
的<span>
标记(带有.before
Jquery函数),因此我在CSS中包含以下规则:
.direct_anchor {
display: block;
height: 55px; // Height of fixed header
margin-top: -55px;
visibility: hidden;
}
最后,这里是我直接在地址栏中键入一个具有哈希扩展名的URL的情况的代码片段:
var target = $('[name="'+location.href.split("#")[1]+'"]');
var hash = location.href.split("#")[1];
if (target.length) {
location.hash = hash;
$('html,body').animate({ scrollTop: target.offset().top - 55 }, 300);
target.before( "<span class='direct_anchor'></span>" );
}
不幸的是,我无法使其工作,class='direct_anchor'
CSS规则似乎没有应用于span
标记。
我不是Jquery的专家,有人能看出问题出在哪里吗?
谢谢你的帮助。
我调试后发现,在重新加载时,脚本不会在if语句中执行。
$(window).bind("load", function () {
$('a[href*="#"]:not([href="#SECTION"]):not([href*="wikipedia"]):not([href*="mjx-eqn"])').click(function(event) {
event.preventDefault();
if (location.pathname.replace(/^'//,'') == this.pathname.replace(/^'//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
var hash = this.hash;
$('html,body').animate({ scrollTop: target.offset().top - 55 }, 300, function() {
href = window.location.href;
history.pushState({page:href}, null, href.split('#')[0]+hash);
});
return false;
}
}
});
$(window).bind('popstate', function(event) {
var state = event.originalEvent.state;
var target = window.location.href.split('#');
var href = target[0];
if (state) {
$('html,body').animate({ scrollTop: 0 }, 300, function() {
history.replaceState({}, null, href);
});
}
});
// code changed here
var target = $("[name='"+location.href.split("#")[1]+"']");
if (target.length) {
$('html,body').animate({ scrollTop: target.offset().top-55},300);
}
});
请注意,您可以使用name
而不是id
作为选择器来获取元素。这是一个现在已经解决的问题。我已经通过调试进行了检查,所以不能确定它,但它在chrome中运行良好。我无法签入firefox,因为我不知道如何使用调试器编辑脚本。
尝试在动画之前更改位置哈希
location.hash = this.hash;
$('html, body').animate({scrollTop: target.offset().top -55 }, 300);
在动画之后更改它会导致页面跳回没有偏移的目标。
有趣的是,几天前我在博客上也遇到了同样的问题。问题不在于代码,而在于浏览器实现,它会等待一段时间和/或多次尝试将哈希与页面上的id匹配。在我的例子中,id是用Javascript生成的,浏览器仍然会访问它们。您的代码可能会被执行,然后浏览器无论如何都会转到该点。
我的解决方案包括插入一个不可见的元素,该元素在散列中实际携带id,并使其位置相对且顶部为-50像素。作为一个通用的解决方案,我认为你唯一的(丑陋的)选择是检查id与哈希相同的元素的偏移量,并且只在检测到浏览器移动它或超时后滚动容器。
这是一个解决方案的演示(在jsfiddle中不起作用)。请注意,在这里我会立即执行脚本,因此如果页面加载需要更长的时间,您可能需要增加超时时间。另一个解决方案是在DOMready上运行它,但我认为这会给您带来尴尬的延迟。
<html>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>
<style>
header {
height:50px;
width:100%;
background:wheat;
position:fixed;
top:0;
}
#target {
color:red;
}
#topHalf, #bottomHalf {
margin-left:20%;
width:50%;
height:2000px;
background-color:gray;
}
</style>
<script>
(function() {
if (!location.hash) return;
var timeout=1000; //1 second. You may want to wait more
var done=false;
var interval=setInterval(function() {
var elem=document.getElementById(location.hash.substr(1));//hash can be '#id,div.aClass' or similar
if (!elem) return;
elem=$(elem);
var ofs=elem.offset();
if (!ofs||!ofs.top) return;
timeout-=100; //interval time
var scrollY=$(window).scrollTop(); //window to get scrollTop, not html,body which yields 0 on Chrome
if (Math.abs(ofs.top-scrollY)<55) { //header size, just to be sure
done=true; // if we are close, then probably the browser did its thing
clearInterval(interval);
$('html,body').animate({ scrollTop: ofs.top - 55 }, 300);
}
if (timeout<=0) { //otherwise, just do it on timeout
clearInterval(interval);
if (!done) $('html,body').animate({ scrollTop: ofs.top - 55 }, 300);
}
},100);
})();
</script>
<header></header>
<content>
<div id="topHalf"></div>
<a id="target">This is the target</a>
<div id="bottomHalf"></div>
</content>
<script>
var k=0;
for (var i=0; i<100000000; i++) {
//some slow running code
k+=Math.random();
}
document.write('K:',k); // using k so that it doesn't get optimized away
</script>
End
</html>
只需在h4之上为锚点创建一个div。例如:
<div id="simulation"></div>
带有:
#simulation {
position: relative;
bottom: 50px;
}
我不确定JavaScript是否是最好的方法。如果你的标题是固定的,你只需要在CSS的主要内容包装上添加55像素的填充即可。
- 添加新数据时D3.JS条形图列偏移量
- 当偏移量改变时滚动顶部
- 引导数据偏移量底部
- 可以在调整窗口大小时重新调整stellar.js的元素偏移量
- 可滚动元素,如何在调整大小时更改顶部偏移量
- 使用JavaScript日期的任何时间的时区偏移量
- 时刻时区:UTC 偏移量差异
- jQuery偏移量顶部没有'工作不正常
- 如何获取当前时区偏移量(并正确格式化)
- d3.mouse 偏移量返回的值不正确
- jQuery根据鼠标位置计算DIV偏移量和边界
- 更改 for 循环中 SVG 行的笔触虚线偏移量
- 时区偏移量计算
- jquery 如何设置偏移量 () 值
- 在javascript中向本地时间戳添加时间戳偏移量
- jquery ui draggable中的奇怪偏移量
- 如何在发布JavaScript日期对象时保留时区偏移量
- 如何使用javascript获取&使用字符偏移量设置插入符号位置
- Javascript日期(yyyy-mm-ddThh:mm:ss偏移量)未正确转换
- JQuery-在加载并直接转到带有锚点的URL时获取偏移量