2012-11-10 73 views
0

我寫一個小的JavaScript實用程序庫,一個關鍵要求的就是一個方法:提供內容READSTATE爲4

  • 把URL和ID
  • 使用這些參數通過Ajax(從提供的URL)獲取內容並將其放入HTML元素(由ID指定)中。

我採取的方法是:

  1. 創建對象命名空間中的庫[不直接相關,但它確實說明下面的代碼的結構]
  2. 編寫返回泛型方法ajax內容基於一個URL傳遞給它[請求工作正常,但提供內容到一個單獨的功能是我遇到問題]
  3. 編寫一個通用的方法,將採取ajax方法,並放置v ALUE返回到一個指定的HTML元素[我希望這將是相當簡單的,如果我可以修復點2]

我的問題是,我一直無法找到一個方法來返回內容時的onreadystatechange已確定readyState爲4.當發生這種情況時,我需要能夠將this.returnText的值傳遞給一個將它放入HTML中的函數。

相關的代碼如下(包含全,但封閉在評論中最相關的部分

// Init-time branching is used to detect objects and set functions accordingly. 
var utilite = { 
    addListener: null, 
    removeListener: null, 
    createAjaxObject: null, 
    ajaxReadyStateHandler: function() { 
      console.log('Ready state is: ' + this.readyState); 
      if (this.readyState === 4) { 
       // Check the status code: 
       if ((this.status >= 200 && this.status < 300) || (this.status === 304)) { 
       console.log('Status OK'); 
       if(this.status === 304){ 
        console.log('Using cached version'); 
       } 
       // Here's the problem: 
       // Despite 'testingAjax' being passed to the original calling function 
       // I can't access it directly and am forced to hard-code it here. 
       utilite.setElementContent({id: 'testingAjax', content: this.responseText}); 
       } else { // Status error! 
       console.log('Status error: ' + this.statusText); 
       } 
      } // End of readyState IF. 
     }, 
    doAjax: function(passedObject) { 
    var ajax = utilite.createAjaxObject(); 
    ajax.onreadystatechange = utilite.ajaxReadyStateHandler; 
    ajax.open(passedObject.requestType, passedObject.resource, true); 
    ajax.send(null); 
    }, 
    getElement: function (id) { // Retrieves element by passed id 
     'use strict'; 
     if (typeof id == 'string') { 
      return document.getElementById(id); 
     } 
    }, 
    setElementContent: function(passedObject){ 
     'use strict'; 
     var theElement = utilite.getElement(passedObject.id); 
     theElement.textContent = passedObject.content; 
    } 
}; // This is the end of utilite 

// Event listener branches 
if (typeof window.addEventListener === 'function') { // W3C and IE9 
    utilite.addListener = function (obj, type, fn) { 
     obj.addEventListener(type, fn, false); 
    }; 
    utilite.removeListener = function (obj, type, fn) { 
     obj.removeEventListener(type, fn, false); 
    }; 
} else if (typeof document.attachEvent === 'function') { // IE 
    utilite.addListener = function (obj, type, fn) { 
     obj.attachEvent('on' + type, fn); 
    }; 
    utilite.removeListener = function (obj, type, fn) { 
     obj.detachEvent('on' + type, fn); 
    }; 
} else { // DOM Level 0 
    utilite.addListener = function (obj, type, fn) { 
     obj['on' + type] = fn; 
    }; 
    utilite.removeListener = function (obj, type, fn) { 
     obj['on' + type] = null; 
    }; 
} 

// Ajax object creation branches 
utilite.createAjaxObject = function() { 
    var ajax = null; 
    if(window.XMLHttpRequest){ 
     ajax = new XMLHttpRequest(); 
    } else if (window.ActiveXObject) { // Older IE. 
     ajax = new Ac 
    var utilite = { 
     addListener: null, 
     removeListener: null, 
     createAjaxObject: null, 
     ajaxReadyStateHandler: function() { 
       if (this.readyState === 4) { 
        if ((this.status >= 200 && this.status < 300) || (this.status === 304)) { 
        if(this.status === 304){ 
         console.log('Using cached version'); 
        } 
        /* ------------------------- 

        It is the value of this.responseText here that I need to provide to a separate function 

        */ ------------------------- 
        } else { // Status error! 
        console.log('Status error: ' + this.statusText); 
        } 
       } // End of readyState IF. 
      }, 
     doAjax: function(passedObject) { 
     var ajax = utilite.createAjaxObject(); 
     ajax.onreadystatechange = utilite.ajaxReadyStateHandler; 
     ajax.open(passedObject.requestType, passedObject.resource, true); 
     ajax.send(null); 
     }, 
     getElement: function (id) { // Retrieves element by passed id 
      'use strict'; 
      if (typeof id == 'string') { 
       return document.getElementById(id); 
      } 
     } 
    }; // This is the end of utilite 
    // Event listener branches 
    if (typeof window.addEventListener === 'function') { // W3C and IE9 
     utilite.addListener = function (obj, type, fn) { 
      obj.addEventListener(type, fn, false); 
     }; 
     utilite.removeListener = function (obj, type, fn) { 
      obj.removeEventListener(type, fn, false); 
     }; 
    } else if (typeof document.attachEvent === 'function') { // IE 
     utilite.addListener = function (obj, type, fn) { 
      obj.attachEvent('on' + type, fn); 
     }; 
     utilite.removeListener = function (obj, type, fn) { 
      obj.detachEvent('on' + type, fn); 
     }; 
    } else { // DOM Level 0 
     utilite.addListener = function (obj, type, fn) { 
      obj['on' + type] = fn; 
     }; 
     utilite.removeListener = function (obj, type, fn) { 
      obj['on' + type] = null; 
     }; 
    } 
    // Ajax object creation branches 
    utilite.createAjaxObject = function() { 
     var ajax = null; 
     if(window.XMLHttpRequest){ 
      ajax = new XMLHttpRequest(); 
     } else if (window.ActiveXObject) { // Older IE. 
      ajax = new ActiveXObject('MSXML2.XMLHTTP.3.0'); 
     } 
     return ajax; 
    }; 
    init = function(){ 
     utilite.doAjax({requestType: 'GET', resource: 'test.txt'}); 
    }; 
    utilite.addListener(window, 'load', init); 
tiveXObject('MSXML2.XMLHTTP.3.0'); 
    } 
    return ajax; 
}; 

init = function(){ 
    utilite.doAjax({requestType: 'GET', resource: 'test.txt', target: 'testingAjax'}); 
}; 

utilite.addListener(window, 'load', init); 

任何及所有的幫助將是非常讚賞。

謝謝

回答

0

我會創建兩個額外的處理程序,例如AjaxSuccessAjaxError。然後您可以撥打AjaxSuccessajaxReadyStateHandlerresponseText作爲參數。在綁定處理程序時,還要將目標DOM元素作爲參數添加。

爲什麼不查看jQueryZepto的源代碼來查看它們如何處理這些事情?或者爲什麼不使用這些庫,它們是成熟的框架?

+0

嗨,謝謝你的提示。不幸的是,我不能使用這個庫(相信我 - 我感到很痛苦,知道我只用1行jQuery就可以實現這一點)。我確實嘗試了一下jQuery源代碼,但很快就失敗了。我會嘗試額外的處理程序,但我仍然不確定如何將AjaxSuccess的值返回到原始調用函數。我需要的是'testingAjax'的值不被硬編碼到ajaxReadyStateHandler中,而是從傳遞給utilite.doAjax的參數中獲得。再次感謝您的幫助。 – Gwyn

0

* 修訂 *

這樣做:

將這個你的Ajax之外:

this.funcResp= function(resp){ console.log(resp) }; 
var thisObj=this; 

將這個你的Ajax函數內部:

thisObj.funcResp(responseText); 
+0

嗨,感謝您的提示,但我無法得到這個工作 - 我懷疑因爲這是指不同的上下文。讓我知道如果我錯過了什麼。再次感謝您的幫助。 – Gwyn

+0

我已更新它。試試這個新版本。 – cube

0

謝謝AGA在迴應中。我現在已經設法使用範圍來解決問題。方法如下:

  1. 向命名空間對象名爲elementToUpdate添加了一個屬性。
  2. 如果doAjax()函數更改elementToUpdate的值。
  3. 從ajaxReadyStateHandler()引用elementToUpdate。

這很好用,但doAjax()被重複調用時確實有點問題。我懷疑這是因爲elementToUpdate被反覆引用/更新。我會再解決這個問題。

非常感謝。代碼如下所示。 G

// Init-time branching is used to detect objects and set functions accordingly. 

    var utilite = { 
    addListener: null, 
    removeListener: null, 
    createAjaxObject: null, 
    elementToUpdate: null, 
    ajaxReadyStateHandler: function() { 
      console.log('Ready state is: ' + this.readyState); 
      if (this.readyState === 4) { 
       // Check the status code: 
       if ((this.status >= 200 && this.status < 300) || (this.status === 304)) { 
       console.log('Status OK'); 
       if(this.status === 304){ 
        console.log('Using cached version'); 
       } 
       // Note: elementToUpdate is accessible here because of the way scope works 
       utilite.setElementContent({id: elementToUpdate, content: this.responseText}); 
       } else { // Status error! 
       console.log('Status error: ' + this.statusText); 
       } 
      } // End of readyState IF. 
     }, 
    doAjax: function(passedObject) { 
    elementToUpdate = passedObject.target; 
    var ajax = utilite.createAjaxObject(); 
    ajax.onreadystatechange = utilite.ajaxReadyStateHandler; 
    ajax.open(passedObject.requestType, passedObject.resource, true); 
    ajax.send(null); 
    }, 
    getElement: function (id) { // Retrieves element by passed id 
     'use strict'; 
     if (typeof id == 'string') { 
      return document.getElementById(id); 
     } 
    }, 
    setElementContent: function(passedObject){ 
     'use strict'; 
     var theElement = utilite.getElement(passedObject.id); 
     if(typeof theElement.innerText !== 'undefined') { theElement.innerText = passedObject.content; } 
     if(typeof theElement.textContent !== 'undefined') { theElement.textContent = passedObject.content; } 
    } 
}; // This is the end of utilite 

// Event listener branches 
if (typeof window.addEventListener === 'function') { // W3C and IE9 
    utilite.addListener = function (obj, type, fn) { 
     obj.addEventListener(type, fn, false); 
    }; 
    utilite.removeListener = function (obj, type, fn) { 
     obj.removeEventListener(type, fn, false); 
    }; 
} else if (typeof document.attachEvent === 'function') { // IE 
    utilite.addListener = function (obj, type, fn) { 
     obj.attachEvent('on' + type, fn); 
    }; 
    utilite.removeListener = function (obj, type, fn) { 
     obj.detachEvent('on' + type, fn); 
    }; 
} else { // DOM Level 0 
    utilite.addListener = function (obj, type, fn) { 
     obj['on' + type] = fn; 
    }; 
    utilite.removeListener = function (obj, type, fn) { 
     obj['on' + type] = null; 
    }; 
} 

// Ajax object creation branches 
utilite.createAjaxObject = function() { 
    var ajax = null; 
    if(window.XMLHttpRequest){ 
     ajax = new XMLHttpRequest(); 
    } else if (window.ActiveXObject) { // Older IE. 
     ajax = new ActiveXObject('MSXML2.XMLHTTP.3.0'); 
    } 
    return ajax; 
}; 

init = function(){ 
    utilite.doAjax({requestType: 'GET', resource: 'test.txt', target: 'funky'}); 
}; 

utilite.addListener(window, 'load', init);