【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的值总是最后一个节点。

我的修改方法如下:

  1. $.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);

};

}

  1. 在回调函数中使用这个传入的参数,而不是用局部变量

                    $.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

回到顶部