希望有人可以解释我在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最终看起来像这样:
HTTP://www.mysite.comhttps//www.mysite.com/mypage.htm
显然没有做我想做的事。看起来脚本的第一部分与相对URL匹配,但当替换部件触发时,浏览器已经添加了域信息。
到目前为止,我发现的唯一能够实现我想要的就是编写替代品,预测浏览器的内容:
this.href = this.href.replace(/^https:\/\/www\.mysite\.com\//, "http://www.mysite.com/");
有更好的方法吗?
答案 0 :(得分:3)
jQuery在这里没有引起问题。问题是HTMLAnchorElement的href
属性(jQuery返回的对象类型)per the spec始终包含绝对URI。
在HTML5中,href
为a composite attribute,您可以通过修改//
来随意交换协议(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
对于没有复合href
的旧浏览器,您只需要使用正则表达式:
console.log( link.href );
// => https://example.com/foo
link.href = link.href.replace( /^https:/, 'http:' );
console.log( link.href );
// => http://example.com/foo
TLDR:您的代码应如下所示:
$( "a[href^='/']" ).prop( "href",
function( _idx, oldHref ) {
return oldHref.replace( /^https:/, 'http:' );
}
);
P.S。您会注意到我已经删除了$.each
来电。这是因为prop
会自动对匹配集中的每个元素执行操作,即它已经执行了您使用each
执行的操作。
.prop( propertyName, function(index, oldPropertyValue) )
propertyName
要设置的媒体资源的名称。function(index, oldPropertyValue)
将值设置为set的函数。接收set中元素的索引位置和旧属性值作为参数。在函数中,关键字this
引用当前元素。
答案 1 :(得分:1)
代码:
$(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;
});
});
});
});
请参阅此jsfiddle:http://jsfiddle.net/aknosis/kWrjr/
以下是我对此问题的解决方案的链接:http://aknosis.com/2011/07/17/using-jquery-to-rewrite-relative-urls-to-absolute-urls-revisited/
答案 2 :(得分:1)
这不是很好,但它应该适用于各种浏览器:
$(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);
}
});
});
答案 3 :(得分:0)
尝试这样的事情:
if(! /http/.test( cur_href) ){
$(this).attr("href", 'http://www.mysite.com'+cur_href);
}
答案 4 :(得分:0)
.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>
换句话说,您将域附加到已经是绝对路径的值。只需使用.attr()
而不是.prop()
,您就可以了。
要查看示例,请打开控制台并转到此页面:http://jsfiddle.net/JUcHU/
答案 5 :(得分:0)
只需使用
即可$(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);
});
});