【Web前端问题】js使用for修改a标签内容只有一个被修改
我希望页面中的所有a标签都被修改,但是打开页面总是最后一个标签被修改,而且有时是第一个标签的内容。
<!DOCTYPE html><meta charset="UTF-8">
<div id="content">http://www.xiami.com/song/1770607143<br>http://www.xiami.com/song/1999582</div>
<style>
.music{line-height:1.4;padding:.3em .8em .3em .3em;border-radius:.3em;color:#35D;display:inline-block;text-decoration:none!important}
.music:hover{background:rgba(80,190,255,.1)}
.music:after{margin-left:.5em;font-style:normal;color:#999;content:'▷'}
.music.play{background:rgba(80,190,255,.1)}
.music.play:after{content:'| |'}
.music.pause:after{content:'▷'}
</style>
<script>
$ = function(i) {
return document.querySelector(i)
};
$.S = function(i) {
return document.querySelectorAll(i)
};
$.x = function(i, p, f) {
var x = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
x.open(p ? 'POST' : 'GET', i, 1);
x.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
x.send(p || '');
if (f) x.onreadystatechange = f;
}
String.prototype.enHtml = function() {
return this.replace(/(^\s*)|(\s*$)/g, '').replace(/(http\:\/\/|)(ww[0-9]{1}\.sinaimg\.cn\/)(?:[\w]{4,10})(\/[\w]{16,32}\.)(gif|jpg|jpeg|png)/g, "http://$2bmiddle$3$4").replace(/http:\/\/www\.xiami\.com\/song\/([0-9]{5,12})[\?\w\.\=]*/g, '<a href="//www.xiami.com/song/$1" target="_blank" class="music">http://www.xiami.com/song/$1</a>').replace(/(http\:\/\/[0-9A-Za-z\/.#&!?%:;=_]+\.)(gif|jpg|jpeg|png)/g, "<img src=\"$1$2\">").replace(/(^|[^\"\'\]>])(http|ftp|mms|rstp|news|https|telnet)\:\/\/([0-9A-Za-z\/.#&!?%:;=\-_]+)/g, '$1<a href="$2://$3" rel="external nofollow noreferer" class="link" target="_blank">$2://$3</a>').replace(/(@)([\u4e00-\u9fa5\u0800-\u4e00A-Za-z0-9\-_]{2,32})/ig, "<span class=\"at\">$1$2</span>").replace(/\n/g, '<br>')
};
var music = function(g, f) {
if (!$.Audio) {
$.Audio = new Audio()
}
$.Audio.addEventListener("ended", function() {
if ($(".music.play")) {
$(".music.play").className = "music"
}
}, false);
var c = function() {
for (var p = $.S(".music"), k, n, o, h = p.length, m = 0; m < h; m++) {
k = p[m];
o = k.href.match(/[0-9]{5,12}$/) * 1;
if (k.onclick) {
continue
}
$.x('http://xmplayer.applinzi.com/?id=' + o, 0, function() {
if (this.readyState == 4 && this.status == 200) {
var json = eval('(' + this.responseText + ')');
name = json.name, artist = json.artist, url = json.url;
k.innerHTML = name + ' - ' + artist;
k.onclick = function() {
if (this.className == "music") {
this.className = "music play";
$.Audio.src = url;
$.Audio.play()
} else {
if (this.className == "music play") {
this.className = "music pause";
$.Audio.pause()
} else {
this.className = "music play";
$.Audio.play()
}
}
return false
}
}
})
}
}
c();
}
$('#content').innerHTML = $('#content').innerHTML.enHtml();
music();
</script>
本地测试结果是:
回答:
这个问题应该是属于JS的闭包问题,问题点在下面的代码部分:
for (var p = $.S(".music"), k, n, o, h = p.length, m = 0; m < h; m++) { k = p[m];
...
$.x('http://xmplayer.applinzi.com/?id=' + o, 0, function() {
if (this.readyState == 4 && this.status == 200) {
...
k.innerHTML = name + ' - ' + artist;
...
}
})
}
注意,在for
循环中,k
是遍历所有节点的,但是$.x()
函数实际上是一个异步的HTTP请求,那么在HTTP请求完成的时候,k
的值已经遍历到最后一个节点。这个可以通过添加下述打印来确认的:
k.innerHTML = name + ' - ' + artist;console.log(k, json)
从运行结果上可以看到,json的值是正确的,但是k的值总是最后一个节点。
我的修改方法如下:
在
$.x
函数中增加参数k
,并且在x.onreadystatechang
回调中讲参数k
再传回给回调函数
$.x = function(i, p, f, k) { var x = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
x.open(p ? 'POST' : 'GET', i, 1);
x.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
x.send(p || '');
if (f) x.onreadystatechange = function(){
f(this, k);
};
}
在回调函数中使用这个传入的参数,而不是用局部变量
$.x('http://xmplayer.applinzi.com/?id=' + o, 0, function(xmlhttp, kk) { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
...
kk.innerHTML = name + ' - ' + artist;
kk.onclick = function() {
...
}
}
}, k)
测试,修改后可以正常显示。
以上是 【Web前端问题】js使用for修改a标签内容只有一个被修改 的全部内容, 来源链接: utcz.com/a/137380.html