0

関数prepareMapEventListener()は256のEventListenersを追加します(el.addEventListener("click", function (e) { B_modeWindow('1', cords) });

でouterHTMLを使用してコードdocument.getElementById(XxY).outerHTML=xmlhttp.responseText;をハングアップした後、その要素のEventListenerの追加をやり直す必要があります。これは、次の方法で実行しようとしました。

// refresh clicable map after it's edited
function refreshMapEventListener() {
    var el = document.getElementById(position);
    el.addEventListener("click", function (e) { B_modeWindow('1', position) });
}

しかし、それはその仕事の半分を行います:リスナーを更新しますが、最後にクリックされた要素に対してのみ-10個の要素をクリックし、それらの5番目を変更したい場合-10番目の要素が変更されます。

refreshMapEventListener();そこで、次の要素を削除して置換することで、すべての要素に対してリスナーを再再生してみprepareMapEventListener()ました。

    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
            document.getElementById(XxY).outerHTML=xmlhttp.responseText;  
            refreshMapEventListener();
            hideloading();
        }
    }

そしてそれは動作します!しかし、試行するたびに出力が2倍になります。したがって、2回クリックすると3回のAJAX呼び出しが発生し、3回クリックすると6回発生します。12回ではありません。

それを解決する方法は?

実例(コンソール/ファイアバグを必ずご覧ください):

http://xn--wiadomesny-37b.pl/stackoverflow/

以下の完全なコード:

// prepare clicable map
function prepareMapEventListener() {
    for (x = 1; x <= 16; x++) {
    for (y = 1; y <= 16; y++) {
        (function prepareClickableMap() {
            var cords = x + "x" + y;
            var el = document.getElementById(cords);
            el.addEventListener("click", function (e) { B_modeWindow('1', cords) });
        })();
    }
    }
}

// selection mode
var s;
function selectionMade(e) {
    selection = e.currentTarget.id.split("_"); 
    s = selection[1];
}

// send edited map info to DB
var position;
function B_modeWindow (id,XxY) {  
    if (s !== undefined) {    
        loading();
    
        var xmlhttp;
        position = XxY;
    
        if (window.XMLHttpRequest) {
            xmlhttp=new XMLHttpRequest();
        } else {
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
    
        var xy = position.split("x"); 
    
        xmlhttp.onreadystatechange=function() {
            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                document.getElementById(XxY).outerHTML=xmlhttp.responseText;  
                prepareMapEventListener();
                hideloading();
            }
        }
    
        xmlhttp.open("GET","processMapEdit.php?id="+id+"&x="+xy[0]+"&y="+xy[1]+"&s="+s,true);
        xmlhttp.send();
    }
}
4

1 に答える 1

0

あなたのコメント (および実際の例) から、必要なclassのは HTML 要素の新しいものだけであることがわかりました。それははるかに簡単です...

あなたの

xmlhttp.onreadystatechange=function() {
            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                document.getElementById(XxY).outerHTML=xmlhttp.responseText;  
                prepareMapEventListener();
                hideloading();
            }
        }

xmlhttp.onreadystatechange=function() {
            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                document.getElementById(XxY).className=xmlhttp.responseText;
                hideloading(); //I don't know what this is, so I leave it here
            }
        }

そして、要素processMapEdit.php全体ではなく、目的のクラス名のみを返すように変更します。DIV

XMLHttpRequestまた、有効な XML テキストの代わりにプレーン テキストを取得するとうまく動作しないブラウザがあるかもしれないので、追加することをお勧めします。

xmlhttp.overrideMimeType("text/plain")

前にsend()

于 2012-09-11T09:33:52.120 に答える