0

HTMLページのbodyonloadから呼び出される3つのJavascript関数があります。

各Javascript関数は、独自のJavascriptファイルに含まれています。各Javascriptファイルは、サーバー上の別のCGIスクリプトに対応しています。

bodyonload.jsは次のようになります。

function bodyOnload() {
 getElementsA();
 getElementsB();
 getElementsC();
}

各getElements関数は、CGIスクリプトを呼び出すだけで、3つの異なる選択ボックスのコンテンツを取得します。

問題は、3つの関数すべてが非同期的に呼び出されるため、選択ボックスが間違った結果を取得することです。これは、3つの関数が互いに足を踏み入れ、CGI応答を間違った選択ボックスに配置しているようなものです。私はCGIの応答が正しいことを知っています。これは、他の関数から各関数を連続して呼び出す場合に正常に機能します。最初の関数から2番目の関数を呼び出し、2番目の関数から3番目の関数を呼び出すように。同時に実行されているそれらの非同期の性質が問題を引き起こしているようです。

これは、getElements関数を含む各javascriptファイルの一般的なコードです。

function getElementsA() {
    strURL = "http://test.com/scriptA.cgi";
    var xmlHttpReq = false;
    var self = this;

    // Mozilla/Safari
    if (window.XMLHttpRequest) {
        self.xmlHttpReq = new XMLHttpRequest();
    }
    // IE
    else if (window.ActiveXObject) {
        self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
    }
    self.xmlHttpReq.open('POST', strURL, true);
    self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    self.xmlHttpReq.onreadystatechange = function() {
        if (self.xmlHttpReq.readyState == 4) {
            fillselectboxA(self.xmlHttpReq.responseText);
        }
    }

 self.xmlHttpReq.send();

}

function fillselectboxA(str)
 {
  document.getElementById("selectBoxA").length=0;
  var results = new Array();
  results = str.split(/\n/);
  var size = results.length;
  var select = document.getElementById("selectBoxA");
  for (x=0;x<size;x++)
   {
    var element = results[x];
    select.options.add(new Option(element, x))
   }
 } 

-------------------

function getElementsB() {
    strURL = "http://test.com/scriptB.cgi";
    var xmlHttpReq = false;
    var self = this;

    // Mozilla/Safari
    if (window.XMLHttpRequest) {
        self.xmlHttpReq = new XMLHttpRequest();
    }
    // IE
    else if (window.ActiveXObject) {
        self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
    }
    self.xmlHttpReq.open('POST', strURL, true);
    self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-  urlencoded');
    self.xmlHttpReq.onreadystatechange = function() {
        if (self.xmlHttpReq.readyState == 4) {
            fillselectboxB(self.xmlHttpReq.responseText);
        }
    }

 self.xmlHttpReq.send();

}

function fillselectboxB(str)
 {
  document.getElementById("selectBoxB").length=0;
  var results = new Array();
  results = str.split(/\n/);
  var size = results.length;
  var select = document.getElementById("selectBoxB");
  for (x=0;x<size;x++)
   {
    var element = results[x];
    select.options.add(new Option(element, x))
   }
 } 

------------------------

function getElementsC() {
    strURL = "http://test.com/scriptC.cgi";
    var xmlHttpReq = false;
    var self = this;

    // Mozilla/Safari
    if (window.XMLHttpRequest) {
        self.xmlHttpReq = new XMLHttpRequest();
    }
    // IE
    else if (window.ActiveXObject) {
        self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
    }
    self.xmlHttpReq.open('POST', strURL, true);
    self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    self.xmlHttpReq.onreadystatechange = function() {
        if (self.xmlHttpReq.readyState == 4) {
            fillselectboxC(self.xmlHttpReq.responseText);
        }
    }

 self.xmlHttpReq.send();

}

function fillselectboxC(str)
 {
  document.getElementById("selectBoxC").length=0;
  var results = new Array();
  results = str.split(/\n/);
  var size = results.length;
  var select = document.getElementById("selectBoxC");
  for (x=0;x<size;x++)
   {
    var element = results[x];
    select.options.add(new Option(element, x))
   }
 } 
4

1 に答える 1

0

まるで3つの機能が互いに足を踏み入れているようです

それがまさに起こっていることです。を呼び出すときにonreadystatechange設定されているハンドラーを上書きし、次にを呼び出すときに再び上書きします。これは、とが3つの関数すべてのグローバルオブジェクトであるためです(すべてがに類似していると仮定します)。getElementsAgetElementsBgetElementsCthisselfgetElementsA

関数呼び出しをオブジェクトのインスタンス化に変更することで、これを回避できます。

function bodyOnload() {
  new getElementsA();
  new getElementsB();
  new getElementsC();
}
于 2012-11-02T03:04:44.197 に答える