Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JQuery-加载并直接转到带有锚的URL时获取偏移量_Javascript_Jquery - Fatal编程技术网

Javascript JQuery-加载并直接转到带有锚的URL时获取偏移量

Javascript JQuery-加载并直接转到带有锚的URL时获取偏移量,javascript,jquery,Javascript,Jquery,我尝试添加以下功能:当我键入带有锚的URL时,我希望直接位于锚上。我的问题是,我有一个固定的页眉,而我当前的JQuery代码没有考虑我放置的偏移量(55,即页眉高度) 下面是代码片段: if ($(location.href.split("#")[1])) { var target = $('#'+location.href.split("#")[1]); if (target.length) { var hash = this.hash; $('

我尝试添加以下功能:当我键入带有锚的URL时,我希望直接位于锚上。我的问题是,我有一个固定的页眉,而我当前的JQuery代码没有考虑我放置的偏移量(
55
,即
页眉高度

下面是代码片段:

 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;
       });
    }
  } 
此代码段位于[anchor.js][1]脚本中

我很好地重定向到锚,但是,无论我采用什么偏移量值,最终结果都不会考虑这一点,因此在加载页面后,锚名称被固定标题隐藏

如果有人能帮我解决这个问题

提前谢谢

ps:我只想让它在Firefox和Chrome上运行

更新

看来解决办法可以从哪里来

为此,我必须在
标记之前插入一个
标记,带有
class='direct\u anchor'
(带有
.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>" );
  }
var target=$('[name=“”+location.href.split(“#”)[1]+'];
var hash=location.href.split(“#”)[1];
if(目标长度){
location.hash=hash;
$('html,body').animate({scrollTop:target.offset().top-55},300);
目标。在(“”)之前;
}
不幸的是,我无法让它工作,
class='direct\u-anchor'
CSS规则似乎没有应用到
span
标记上

我不是Jquery的专家,任何人都能看出哪里出了问题


感谢您的帮助。

尝试在播放动画之前更改位置哈希

location.hash = this.hash;
$('html, body').animate({scrollTop: target.offset().top -55 }, 300);

在动画之后更改它会导致页面跳回目标,而不带偏移量。

我调试后发现脚本在重新加载时不会在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,因为我不知道如何使用调试器编辑脚本。

有趣的是,几天前我在博客上遇到了完全相同的问题。问题不在于代码,而在于浏览器实现,它会等待一点和/或多次尝试将哈希值与页面上的id匹配。在我的例子中,ID是用Javascript生成的,浏览器仍然可以访问它们。您的代码可能会被执行,然后浏览器仍会转到该点

我的解决方案是在散列中插入一个实际携带id的不可见元素,并使其位置相对,位于前50px。作为一个通用的解决方案,我认为您唯一的(丑陋的)选择是检查id与哈希相同的元素的偏移量,并且仅在检测到浏览器移动它或超时后滚动容器

下面是解决方案的演示(在JSFIDLE中不起作用)。请注意,这里我立即执行脚本,因此如果页面加载时间较长,您可能需要增加超时时间。另一个解决方案是在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>

标题{
高度:50px;
宽度:100%;
背景:小麦;
位置:固定;
排名:0;
}
#目标{
颜色:红色;
}
#上半部,#下半部{
左缘:20%;
宽度:50%;
高度:2000px;
背景颜色:灰色;
}
(功能(){
如果(!location.hash)返回;
var timeout=1000;//1秒。您可能需要等待更长时间
var done=false;
var interval=setInterval(函数(){
var elem=document.getElementById(location.hash.substr(1));//哈希可以是“#id,div.aClass”或类似的值
如果(!elem)返回;
elem=$(elem);
变量ofs=元素偏移量();
如果(!ofs | |!ofs.top)返回;
超时-=100;//间隔时间
var scrollY=$(window).scrollTop();//获取scrollTop而不是html的窗口,在Chrome上生成0

如果(Math.abs(ofs.top scrollY)只需在h4上方为锚创建一个div。例如:

<div id="simulation"></div>

我不确定JavaScript是否是最好的方法。如果你的标题是固定的,你可以在CSS的主内容包装器中添加55px的padding top,这应该可以做到。

如果($(location.href.split(“#”)[1])
应该实现什么?这是我来自外部URL(而不是我的网站)的情况我试图通过在浏览器中键入URL“”直接转到定位点,
$(location.href.split(“#”)的值是多少
?我的意思是你想在这里检查什么。我检查在#符号之后是否有字符串,也就是检查URL中是否有锚。我想说的是,你实际上不需要为此使用jquery
$
。你可以直接检查
location.hash
的长度。我不确定你的意思是标题显示为f谢谢,你的解决方案在chrome上无法系统地工作(可能是缓存或历史记录有问题),我一直在尝试在firefox上调试它。regardsCan可以在$(window.load)中添加最后更改的代码(function(){//to add here});我在控制台编辑您的脚本时没有遇到任何问题,我以这种方式绑定load event listener。但现在,当您更新脚本时,我会随机遇到问题。请检查/js/anchor.js中的第56行,其中以冒号(:)而不是分号(;)结尾。引发错误。
#simulation {
 position: relative;
 bottom: 50px;
}