Javascript jQuery替换相对链接

Javascript jQuery替换相对链接,javascript,jquery,Javascript,Jquery,希望有人能解释我在jQuery中遇到的一些奇怪行为。下面的脚本正在我的页面上查找相对链接,并将其替换为绝对链接 $(document).ready(function() { $("a[href^='/']").each(function(){ var cur_href = $(this).prop("href"); $(this).prop("href", 'http://www.mysite.com'+cur_href); }); }); 我在一个将通过https提

希望有人能解释我在jQuery中遇到的一些奇怪行为。下面的脚本正在我的页面上查找相对链接,并将其替换为绝对链接

$(document).ready(function() {
  $("a[href^='/']").each(function(){ 
    var cur_href = $(this).prop("href");
    $(this).prop("href", 'http://www.mysite.com'+cur_href);
  });
});
我在一个将通过https提供服务的页面上使用此脚本,但我不希望所有导航都链接到https页面。因为我的导航是全局包含的,所以这似乎是解决问题的最简单方法

我遇到的问题是实际的替换。脚本的第二行正确匹配页面上的所有相关链接,然后运行脚本的替换部分。在替换的第4行,我得到了一些奇怪的结果。在脚本的这一部分运行后,我的URL最终看起来如下所示:

if(! /http/.test( cur_href) ){
   $(this).attr("href", 'http://www.mysite.com'+cur_href);

}
$( "a[href^='/']" ).prop( "href",
  function( _idx, oldHref ) {
    return oldHref.replace( /^https:/, 'http:' );
  }
);
http://www.mysite.comhttps//www.mysite.com/mypage.htm

很明显,这不是我想要的。脚本的第一部分似乎与相对URL匹配,但当替换部分启动时,浏览器已经锁定了域信息

到目前为止,我所发现的唯一一件事实际上是实现了我想要的功能,那就是编写替换内容,以预测浏览器的附加功能:

this.href = this.href.replace(/^https:\/\/www\.mysite\.com\//, "http://www.mysite.com/");
有更好的方法吗



编辑:。

尝试以下操作:

if(! /http/.test( cur_href) ){
   $(this).attr("href", 'http://www.mysite.com'+cur_href);

}
$( "a[href^='/']" ).prop( "href",
  function( _idx, oldHref ) {
    return oldHref.replace( /^https:/, 'http:' );
  }
);
.prop()
获取属性的值,而不是属性的值。虽然相似,但也有一些微妙的、重要的区别——其中之一适用于这里。元素上的
href
属性始终是完整路径。例如:

<a id="myAnchor" href="/foo.html"></a>

<script>
elem = document.getElementById('myAnchor');
$elem = $(elem);
alert(elem.href); //alerts the full path, http://www.example.com/foo.html
alert($elem.prop('href')); //same as above
alert($elem.attr('href')); //alerts just "/foo.html"
</script>

elem=document.getElementById('myAnchor');
$elem=$(elem);
警报(elem.href)//通知完整路径,http://www.example.com/foo.html
警报($elem.prop('href'))//同上
警报($elem.attr('href'))//警报仅“/foo.html”
换句话说,将域附加到已经是绝对路径的值。只要使用
.attr()
而不是
.prop()
就可以了

要查看示例,请打开控制台并转到此页面:

代码:

$(function() {
    $('input').click(function() {
        $('a').not('[href^="http"],[href^="https"],[href^="mailto:"],[href^="#"]').each(function() {
            $(this).attr('href', function(index, value) {
                if (value.substr(0,1) !== "/") {
                    value = window.location.pathname + value;
                }
                return "http://mynewurl.com" + value;
            });
        });
    });
});
请参阅此JSFIDLE:


这里有一个链接指向我解决这个问题的方法:

这并不漂亮,但它应该可以跨浏览器工作:

$(document).ready(function() {
  $("a[href^='/']").each(function(){ 
    var cur_href = $(this).attr("href");
    if( cur_href.indexOf( "http" ) !== -1 ) {
        $(this).attr("href", cur_href);
    } else {
        $(this).attr("href", 'http://www.mysite.com'+cur_href);
    }  
  });
});

jQuery在这里没有引起问题。问题在于HtmlanchoreElement(jQuery正在返回的对象类型)的
href
属性始终包含一个绝对URI

在HTML5中
href
是,您可以通过修改
href.protocol
随意交换协议(在
/
之前的部分),例如:

var link = $( '<a href="https://example.com/foo">bar</a>' )[0];
console.log( link.href );
// => https://example.com/foo

link.href.protocol = 'http:';
console.log( link.href );
// => http://example.com/foo
TLDR:您的代码应该如下所示:

if(! /http/.test( cur_href) ){
   $(this).attr("href", 'http://www.mysite.com'+cur_href);

}
$( "a[href^='/']" ).prop( "href",
  function( _idx, oldHref ) {
    return oldHref.replace( /^https:/, 'http:' );
  }
);
另外,您会注意到我省略了您的
$。每次呼叫。这是因为
prop
会自动作用于匹配集合中的每个元素,即它已经完成了您对每个
所做的操作


  • 属性名称
    要设置的属性的名称
  • 函数(索引,oldPropertyValue)
    返回要设置的值的函数。接收集合中元素的索引位置和旧属性值作为参数。在函数中,关键字
    this
    指的是当前元素
简单地尝试一下

$(document).ready(function() {
  $("a[href^='/']").each(function(){ 
    var cur_href = this.href;  /* <-- access to the href attribute 
                                      through the DOM reference */  
    $(this).prop("href", 'http://www.mysite.com'+cur_href);
  });
});
$(文档).ready(函数(){
$(“a[href^='/'])。每个(函数(){

var cur_href=this.href;/*你能为这个问题做一个JSFIDLE吗?我以前注意到IE会添加域信息,但Firefox通常不会。这很奇怪,也出乎意料,因此在你的JS中必须考虑一些东西。
[href^='/']
是一个属性选择器,因此可能
.attr
给出了正确的结果。这可能会让您感兴趣:我想同意您的观点,但我认为这并不是那么简单。我很少使用prop(),总是使用attr()我看到一些浏览器返回完整路径。特别是IE8。也许你是对的。我倾向于总是使用.href属性,所以我总是得到完整路径。我想OP会为我们测试这个路径。这似乎不会改变任何事情。这与OP的原始问题相同。这个解决方案很有效。我想我喜欢Aknosis的稍微修改一下,但是你的是我原来的脚本的一个工作版本。这个解决方案起了作用,并且增加了我在第一个版本中没有考虑的一些检查。这是一个奇怪的用例,但是我知道你在读这个问题时所说的内容。很高兴你发现它有用:我把代码编辑成了答案,所以这篇文章不仅仅是一堆链接。代码是如何工作的,但我试图弄清楚它是如何工作的。什么是idx?我引用了(并链接到)上面文档的相关部分。
\u idx
在JavaScript中没有任何特殊意义,它只是一个变量名(在某些语言中,通常只将未使用的变量命名为“
”,但我使用它作为前缀)。在这种情况下,
prop
所做的就是在每个匹配元素上获取给定属性(
href
)的值,将其传递给匿名函数(在我的代码中为
oldHref
),然后将属性更改为函数返回的任何值。它类似于。感谢您的解释和修复。我本应查看.prop文档,但我认为_idx引用了某种类型的全局变量。这是一个漂亮而优雅的修复,我将使用它。