andreaswebbMedlem sedan apr. 2003111 inlägg
Hej på er!
Håller på med en javascript-class som ska skapa "fönster" i form av div:ar i olika layer. Till detta hade jag tänkt att använda ajax för att hämta innehåller i dessa "fönster".
Klassen http://andreas.famstromgren.se/js/window.class.js
Ajax http://andreas.famstromgren.se/js/ajax.js
Koden i ajax.js är bara för att skapa ajax-objektet. Funktionen för att hämta datan ligger sedan i klassen. Grejjer är den att hur jag än gör så blir this.content == undefined. Jag har felsökt ajax-funktionen och den fungerar som den ska, det är kommunikationen mellan ajax-funktionen och draw-funktionen som inte fungerar. Har testat med att byta namn på variabeln som ska innehålla return-värdet från ajax-funktionen men det hjälper inte heller. Också testat att sätta variabeln direkt i ajax-funktionen men det hjälper inte.
Någon som vet vad som jag gjort fel?
Tackar på förhand!
Peter SMedlem sedan dec. 20025 484 inlägg
Ett exempel:
function iWindow(id,header) {
this.id = id;
this.header = header;
this.draw = function() {
if(!document.getElementById(this.id)) {
if(this.width == undefined) this.width = 100;
if(this.height == undefined) this.height = 100;
if(this.top == undefined) this.top = 0;
if(this.left == undefined) this.left = 0;
this.id = this.id
this.wrapper = document.createElement('div');
this.wrapper.id = this.id;
this.wrapper.style.width = this.width;
this.wrapper.style.height = this.height;
this.wrapper.style.backgroundColor = this.backgroundColor;
this.wrapper.style.position = 'absolute';
this.wrapper.style.top = this.top;
this.wrapper.style.left = this.left;
if(this.getContentMethod == undefined) this.getContentMethod = 'GET';
if(this.ajaxContent != undefined) {}
this.getContent(/*this.content*/"http://www.webforum.nu/",this.getContentMethod);
} else this.show();
}
this._draw = function() {
this.wrapper.innerHTML = iWindow._response;
document.getElementById('body').appendChild(this.wrapper);
}
this.getContent = function(addr,method) {
ajax = createAjaxObj();
iWindow._currObject = this;
ajax.onreadystatechange = function(obj) {
if(ajax.readyState == 4 && ajax.status == 200) {
iWindow._response = ajax.responseText;
iWindow._helper_();
}
}
ajax.open(method,addr,true);
ajax.send(null);
}
this.hide = function() {
document.getElementById(this.id).style.display = 'none';
}
this.show = function() {
document.getElementById(this.id).style.display = '';
}
}
iWindow._response = iWindow._currObject = null;
iWindow._helper_ = function() {
iWindow._currObject._draw();
}
Kanske ett fulhack, men det fungerar. :)
andreaswebbMedlem sedan apr. 2003111 inlägg
Man tackar :) Men nyfiken som man är så funderar jag på varför mitt inte fungerar?
Peter SMedlem sedan dec. 20025 484 inlägg
Du har någonting i stil med detta:
this.content = this.getContent(...);
I getContent()-metoden har du
obj.onreadystatechange = function(){
return <ajaxContent>;
}
Problemet är att onreadystatechange är en händelsehanterare, varför tiden för dess exekvering inte är omedelbar. Vad du gör i getContent() är att registrera den här händelsen för ett specifikt objekt, men du kan inte i den hanteraren returnera ett värde för den funktion i vilken onreadystatechange() definierats. I draw() kommer getContent() att köras, uppifrån och ned, avsluta och sedan återvända till draw(), utan att ha returnerat någonting. Därför blir this.content undefined.
andreaswebbMedlem sedan apr. 2003111 inlägg
Okej, man lär sig nått nytt varje dag ;). Om man nu skulle lösa detta på ett icke "fulhackat" sätt, hur ska det då se ut? Känns som att exemplet ovan blir onödigt krångligt, eller är det så det måste bli?
Peter SMedlem sedan dec. 20025 484 inlägg
Du kan wrappa AJAX-objektet i en egen klass:
ajax.js
function createAjaxObj() {
var httprequest=false
if (window.XMLHttpRequest){ // if Mozilla, Safari etc
httprequest=new XMLHttpRequest()
if (httprequest.overrideMimeType)
httprequest.overrideMimeType('text/html')
} else if (window.ActiveXObject){ // if IE
try {
httprequest=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e){
try{
httprequest=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e){}
}
}
return httprequest;
}
window.class.js
function iWindow(id,header,name) {
this.id = id;
this.header = header;
this.name = name
zIndex = 0; //Global variabel för att hålla reda på Z-index
this.draw = function() {
if(!document.getElementById(this.id)) {
if(this.width == undefined) this.width = 100;
if(this.height == undefined) this.height = 100;
if(this.top == undefined) this.top = 0;
if(this.left == undefined) this.left = 0;
if(this.template == undefined) this.template = 'standard';
if(this.html == undefined) this.html = '';
this.id = this.id
this.wrapper = document.createElement('div');
this.wrapper.id = this.id;
//Storlek
this.wrapper.style.width = (this.width+6)+'px';
this.wrapper.style.height = (this.height+6)+'px';
//Dropshadow
this.wrapper.className = 'dropshadow';
//Lagerhantering
this.wrapper.style.position = 'absolute';
this.wrapper.style.top = (this.top+4)+'px';
this.wrapper.style.left = (this.left+4)+'px';
this.wrapper.setAttribute('onclick',this.name +'.setFocus()');
this.wrapper.setAttribute('onmousedown',this.name +'.drag');
document.getElementById('body').appendChild(this.wrapper);
//Innehållet i wrapper
this.content = document.createElement('div');
this.content.id = this.id +'_content'
this.content.className = this.template;
this.content.style.padding = '3px';
this.content.style.width = (this.width-6)+'px';
this.content.style.height = (this.height-6)+'px';
document.getElementById(this.id).appendChild(this.content);
//Skapar rubrik
this.rubrik = document.createElement('h1');
this.rubrik.className = 'drag_area';
this.rubrik.innerHTML = this.header;
document.getElementById(this.id +'_content').appendChild(this.rubrik);
//Skapar container för användardefinierat innehåll
this.container = document.createElement('div');
this.container.id = this.id +'_container';
this.ajaxContent = true;
if(this.ajaxContent == true) this.getContent("http://www.webforum.nu/","GET",this);
else {
this.container.innerHTML = this.html;
document.getElementById(this.id +'_content').appendChild(this.container);
this.setFocus();
}
} else {
if(this.wrapper.style.display == 'none') this.show();
else this.setFocus();
}
}
this.setFocus = function() {
this.wrapper.style.zIndex = zIndex++;
}
this.getContent = function(addr,method,iwin) {
var ajax = new ajaxobj(iwin);
ajax.initorsc();
ajax.open(method,addr,true);
ajax.send(null);
}
this.hide = function() {
document.getElementById(this.id).style.display = 'none';
}
this.show = function() {
document.getElementById(this.id).style.display = '';
}
}
function ajaxobj(iwin)
{
this.xmlreq = createAjaxObj();
this.iwin = iwin;
this.initorsc = function()
{
this.xmlreq.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200){
iwin.container.innerHTML = this.responseText;
document.getElementById(iwin.id +'_content').appendChild(iwin.container);
iwin.setFocus();
}
}
}
this.open = function(method,addr,async)
{
this.xmlreq.open(method,addr,async);
}
this.send = function(str)
{
this.xmlreq.send(str);
}
}
andreaswebbMedlem sedan apr. 2003111 inlägg
Nu har jag äntligen fått tummen ur och testat detta. Fungerar utmärkt i IE, men i FF så går det inte. Efter lite felsökning så ser jag att this.readyState och this.status blir undefined i FF. Har testat att lägga till xmlreq mellan this och egenskapen, men det hjälper inte.
Peter SMedlem sedan dec. 20025 484 inlägg
Testa följande:
function ajaxobj(iwin)
{
this.iwin = iwin;
this.initorsc = function()
{
this.xmlreq = createAjaxObj();
var _this = this;
this.xmlreq.onreadystatechange = function()
{
if (_this.xmlreq.readyState == 4 && _this.xmlreq.status == 200){
_this.iwin.container.innerHTML = _this.xmlreq.responseText;
document.getElementById(_this.iwin.id +'_content').appendChild(_this.iwin.container);
_this.iwin.setFocus();
}
}
}
this.open = function(method,addr,async)
{
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
} catch (e){}
this.xmlreq.open(method,addr,async);
}
this.send = function(str)
{
this.xmlreq.send(str);
}
}
andreaswebbMedlem sedan apr. 2003111 inlägg
Nu fungerar det klockrent i både IE och FF. Tackar tackar :)