【问题标题】:jQuery - how to test if link goes to anchor on same page?jQuery - 如何测试链接是否锚定在同一页面上?
【发布时间】:2023-03-29 14:27:01
【问题描述】:

我正在尝试在单击链接时运行 ajax 函数,但我需要排除指向同一页面上的锚点的链接,因此当我只是向下滚动时不会尝试重新加载页面内容到同一页面的不同部分。

我知道我可以测试 href 是否包含哈希,但这还不够:

if (href.indexOf("#") === -1)

因为我会有链接到另一个页面并滚动到本地锚点。所以我需要测试 href 是否指向当前页面并包含哈希。在这种情况下,我会将其排除在功能之外。但如果它指向不同的页面并包含一个哈希值,它仍然应该被包含在内。

如何使用 jQuery 实现这一点?

【问题讨论】:

    标签: javascript jquery ajax if-statement


    【解决方案1】:

    给你,

    // extract hash from URL
    const hash = new URL(`https://example.com/#your-anchor`).hash; // return => #your-anchor
    
    // if hash exists in the URL, and the anchor is also exists
    if(hash.length && document.querySelectorAll(hash).length){
       // do something
    }
    

    【讨论】:

      【解决方案2】:

      你不需要 jQuery。只需在 Javascript 中使用正则表达式。

      if(/^#/.test(href)) { // .test() returns a boolean
      
          /* do not run AJAX function */ 
      
      } else {
      
          /* run the AJAX function */ 
      
      }
      

      解释:

      ^# 是正则表达式。 // 是您包装正则表达式的位置。^ 表示字符串的开头,# 是您要查找的内容。 .test() 是一个 javascript 函数,它在给定字符串上执行正则表达式并返回一个布尔值。

      阅读: RegExp.prototype.test() - JavaScript | MDN


      更新 1:

      如果href 不是以# 开头,但它仍然指向同一个网页,那么您的问题将简化为检查一个字符串是否是另一个字符串的子字符串。您可以使用window.location.href.indexOf() 来实现:

      if(href.indexOf(window.location.href) > -1) { 
      
          /* do not run AJAX function */ 
      
      } else {
      
          /* run the AJAX function */ 
      
      }
      

      window.location.href 返回您所在网页的 URL,href.indexOf(window.location.href) 检查 window.location.href 是否是 href 的子字符串;

      示例:https://www.example.com/page1https://www.example.com/page1#myDiv 的子字符串

      阅读:


      更新 2:

      @Tib 的好发现。我上面更新的代码没有检查主机名是否相同。我已在下面修复它:

      if(<hostnames are the same>) { // make use of window.location.hostname here to get hostname of current webpage
          if(href.indexOf(window.location.href) > -1) { 
      
              /* do not run AJAX function */ 
      
          } else {
      
              /* run the AJAX function */ 
      
          }
      } else {
      
          /* do not run AJAX function */
      
      }
      

      【讨论】:

      • 感谢 Rahul,但仅测试 hash 是否是 strong 中的第一个字符是不够的。这些是 CMS 页面,导航链接在每个页面上都具有相同的 URL。在主页上,这些链接转到同一页面上的锚点,在其他页面上,它们转到主页上的锚点。所以哈希不会在开头。我需要可靠地测试 href 是转到当前页面还是另一个页面。
      • @BenekLisefski 请在我上面的回答中签出更新1
      • 我最终调整了我的计划并找到了另一种解决方法,但无论如何感谢您的详细回答。
      • 大错特错!如果您有一个指向外部网站锚点的链接怎么办?您还应该检查主机名部分。罗德里戈指出了正确的解决方案
      【解决方案3】:
          /**
           * Checks if the href belongs to the same page and returns the anchor if so.
           *
           * @param  {String} href
           * @returns {Boolean|String}
           */
          function getSamePageAnchor (href) {
              var link = document.createElement('a');
              link.href = href;
      
              /**
               * For IE compatibility
               * @see https://stackoverflow.com/a/24437713/1776901
               */
              var linkCanonical = link.cloneNode(false);
      
              if (
                  linkCanonical.protocol !== window.location.protocol ||
                  linkCanonical.host !== window.location.host ||
                  linkCanonical.pathname !== window.location.pathname ||
                  linkCanonical.search !== window.location.search
              ) {
                  return false;
              }
      
              return link.hash;
          }
      

      【讨论】:

        【解决方案4】:

        这是我的看法,更苗条:-

        $('a[href*=\\#]').on('click', function (event) {
            if(this.pathname === window.location.pathname){
                // Do something 
            }
        });
        

        【讨论】:

          【解决方案5】:

          所有浏览器都支持:

          "use strict"; // Start of use strict
          $('a').bind('click', function(event) {
            if (this.pathname == window.location.pathname &&
              this.protocol == window.location.protocol &&
              this.host == window.location.host) {
              alert('links to same page');
              event.preventDefault();
            } else {
              alert('links to a different page');
            }
          });
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <a href="#same-page">Same Page</a>
          <br>
          <a href="/users/913950#page">Other Page</a>

          【讨论】:

          • 做了同样的事情,但在末尾添加了&amp;&amp; this.hash,只是为了检查它是否在 URL 中有哈希部分(本地锚点)。
          【解决方案6】:

          远非完美,但对我有用。 不要忘记使用 jQuery。

          玩得开心:

          jQuery('a').on('click',function (e) {
          
              var current = window.location.href.split('#')[0];
              var goto = jQuery(this).attr('href').split('#')[0];
          
              if (current == goto && this.hash) {
                  e.preventDefault();
          
                  var target = this.hash;
                  var $target = jQuery(target);
          
                  if($target.length){
                      jQuery('html,body').stop().animate({
                          'scrollTop': $target.offset().top
                      }, 900, 'swing');
                  }
              }
          
          });
          
          jQuery('a[href^=#]:not([href=#])').on('click',function (e) {
              e.preventDefault();
          
              var target = this.hash;
              var $target = jQuery(target);
          
              if($target.length){
                  history.pushState( null, jQuery('#title').html() , target);
                  jQuery('html,body').stop().animate({
                      'scrollTop': $target.offset().top }, 900, 'swing');
              }
          });
          jQuery('a[href=#]').on('click',function (e) {
              e.preventDefault();
              history.pushState( null, jQuery('#title').html() , location.href.replace(location.hash,""));
              jQuery('html,body').stop().animate({
                  'scrollTop': 0
              }, 900, 'swing');
          });
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-03-29
            • 2016-09-08
            • 1970-01-01
            • 1970-01-01
            • 2020-01-11
            • 2018-01-12
            • 1970-01-01
            • 2012-12-22
            相关资源
            最近更新 更多