• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[JavaScript] Problem mit meiner Drag'nDrop Klasse

Gawin

New member
Hi leute,
hab wie der Titel schon sagt ne Drag'nDrop Klasse geschrieben, funktioniert an sich auch einwandfrei.
Aber der IE8 spielt irgent wie nicht mit ich finde einfach keinen Fehler bzw. eine Lösung.

edit: hab gerade das <meta http-equiv="X-UA-Compatible" content="IE=7" /> gefunden aber muss ja bestimmt auch anders gehen.

Eine Demoseite findet Ihr Hier.
Und ein direkt link zum Script Hier.
Hoffe es hat jemand die Zeit und Lust sich mal mein Script anzugucken.

Gruss Gawin

edit2: Hab die hasClass Funktion verändert (auch wenns nichts mit dem eigentlichem Problem zu tuen hat).
 
Zuletzt bearbeitet:
Deine verwendete Funktion contentLoaded ist Mist und startet deine Funktion zu früh.

PS: Die Funktionenen aus deiner "mainlibary" sind nicht so der Hit...
 
Auweia, was soll ich dazu sagen. Hast du dir die contentLoaded überhaupt angeguckt? Sie funktioniert einwandfrei und startet das Script wenn der HTML-code verfügbar ist und nicht wenn die seite geladen ist was auch vollkommen korreckt ist ein alert beim mousedown oder mouseup wird vollkommen koreckt ausgefürt. Und ausserdem meinste nicht das ich sonst ne fehlermeldung bekommen hätte wo steht das die sachen noch nicht vorhanden sind?

Und was ist den nicht so der hit an meinen mainlib Funktionen?

Gruss Gawin
 
Ja, ich hab' mir die contentLoaded angesehen - und im IE8 startet die einfach zu früh, was deine ganzen Probleme verursacht. Du kannst dir ja mal this.windows.length ausgeben lassen...

Und warum sollte da eine Fehlermeldung kommen? Zeig' mir die Stelle im Code, die einen fehlerhaften Zugriff darstellt, wenn das Dokument noch nicht fertig ist.

Zu deinen mainlib Funktionen:
_$ ist inkonsistent: wenn getElementsByClassName existiert (du prüfst da auch noch falsch: du prüfst auf document.get... aber du benutzt pardoc.get... - aus der Existenz des einen kann man noch nicht auf die Existenz des anderen schließen) suchst du in pardoc. In den anderen Fällen suchst du im kompletten document. Auch wird parent manchmal als ID gehandhabt und manchmal als Node. .querySelectorAll wird so, wie du es verwendest, nie das gewünschte Verhalten zeigen: '.class' != '.' + clas
Auch ist der Rückgabewert manchmal eine HTMLCollection und manchmal ein Array - die haben in bestimmten Situationen (wenn z.B. eine Node aus dem DOM-Tree ausgehakt wird) völlig verschiedene Verhaltensweisen.
Außerdem sollte man document.all nicht mehr verwenden.

hasClass ist sehr komisch: im classList-Fall vertraust du nicht auf den Rückgabewert von .contains, wenn der false ist - nur wenn true. Warum du auf document.all prüfst, wenn du .className (was alle Browser unterstützen) abrufen willst, ist mir völlig unklar. Außerdem ist der Rückgabe wert undefined, wenn die Klasse nicht enthalten ist - das muss false sein.
Außerdem sollte man new Array() nicht verwenden - besser ist das Literal ([]). Zusätzlich erzeugst du eine globale Variable l.

mouse_pos ist halbwegs in Ordnung... du erzeugst nur eine globale Variable pos.
 
komisch das alles funktioniert und wenn ich es über window.onload lade is auch kein unterschied und auf document.all prüfe ich falls irgent wer nen totalen exzoten hat deshalb auch noch das getAttribute und der soll auf true prüfen bei classList.contains sonst wenn false is soll er ja ins nächste xDD aber egal warum funktioniert das nicht im ie8??? es liegt 1000% nicht am contentLoaded und er springt nicht zu früh rein
 
Zuletzt bearbeitet:
OK - es liegt nicht an contentLoaded. Es liegt an deiner "mainlib"...

Dir ist schon klar, dass FF kein document.all hat.? Und FF ist jetzt kein "Exzot".
Wenn classList.contains false zurückgibt - warum soll es dann ins Nächste?
 
Stimmt an ältere FF hab ich nicht gedacht xD.

Wenn classList.contains false zurückgibt - warum soll es dann ins Nächste?
Warum er ins nächste soll? Ich hab die if abfrage nun mal so angepasst das er nur reinfällt wenn .classList UND .classList.contains wahr sind wenn ich nur contains abfrage kommt fehler in älteren browsern das .classList nicht existiert deshalb beides.
Und wenn das false liefert soll er es mit der .className methode probieren. oder soll ich alle alten Browser deiner meinung nach ausschließen? xDDD

Aber wo ist denn der fehler in der mainlib das der IE8 nicht will?

Und nochmal zu den "globalen Variablen" mit mouse_pos hatteste natürlich recht, aber bei der l Variable muss ich dir wiedersprechen.
Ich erzeuge sie for(var i=0,l=var.length;i<l;i++) was vollkommen koreckt ist es ist genauso legitiem wie var a,b,c = 1; oder var a=0,b=1;. Das Komma trennt hier nur die Deklarationen aber alle sind im bezug auf das Schlüsselwort var. Wenn ich es aber (wie es viele tuen) for(var i=0; i<var.length;i++) mache wird bei jedem schleifendurchlauf die methode var.length aufgerufen, in meiner schreibweise aber nur einmal am anfang.
 
Zuletzt bearbeitet:
Auch der aktuelle FF gibt bei document.all undefined zurück...

Dass du .classList abfrägst, bevor du darauf zurückgreifst ist völlig in Ordnung - wenn aber die Funktion .classList.contains existiert und false zurückgibt, hast du schon auf die Klasse geprüft.

Les' dir #4 noch einmal durch - da steht schon drin, was an deiner mainlib nicht in Ordnung ist.

Das mit der Variablen l hatte ich irgendwie falsch gesehen (die Schreibweise var a, b,...; ist mir schon bekannt) - dafür ist in $_ pardoc global...
 
Hab _$ und hasClass nochmal überarbeitet aber das es manchmal eine HTMLcolletion zurückgibt und manchmal nen array kann ich nix drann ändern oder doch? Und document.all muss ich leider verwenden da IE5 z.b. document.body.getElementsByTagName nicht kennt.

Naja so sehen sie jetzt aus was soll ich noch ändern?
Code:
_$ = function(clas, parent){
    var pardoc = document.getElementById(parent) || document;
    
    if(pardoc.getElementsByClassName){
        return pardoc.getElementsByClassName(clas);
    }else if(document.querySelectorAll){
        return document.querySelectorAll('.class');
    }else{
        var obj = document.all ? document.all : (document.getElementById(parent) || document.body).getElementsByTagName('*');
        var ret = [];
        for( var i=0, l=obj.length; i<l; i++){
            if(hasClass(obj[i], clas)) ret.push(obj[i]);
        }
    }
    return ret;
}

hasClass = function(obj, clas){
    var clas_erg = [];
    if(obj.classList){
        return obj.classList.contains(clas) ? true : false;
    }else if(obj.className){
        clas_erg = obj.className != "" ? obj.className.split(" ") : null;
    }else if(obj.getAttribute("class")){
        clas_erg = obj.getAttribute("class") != "" ?obj.getAttribute("class").split(" ") : null;
    }else return false;
    if(clas_erg == null) return false;
    
    for(var i=0, l=clas_erg.length; i<l; i++){
        if(clas_erg[i] === clas) return true;
    }
    return false;
}

ps.: IE8 verweigert sich immer noch
 
Hab _$ und hasClass nochmal überarbeitet aber das es manchmal eine HTMLcolletion zurückgibt und manchmal nen array kann ich nix drann ändern oder doch?
Du könntest die HTMLCollection in ein Array umschreiben.
Und document.all muss ich leider verwenden da IE5 z.b. document.body.getElementsByTagName nicht kennt.
IE5? Ist nicht dein Ernst. Der ist tot! Und wer ihn benutzt, ist selbst schuld.
Code:
        return obj.classList.contains(clas) ? true : false;
Das ist ja ein lustiges Konstrukt... warum machst du nicht einfach nur
Code:
return obj.classList.contains(clas);
?
ps.: IE8 verweigert sich immer noch
Es sind noch nicht alle Probleme aus #4 gelöst. Deswegen mag der IE8 noch nicht.
 
IE5? Ist nicht dein Ernst. Der ist tot! Und wer ihn benutzt, ist selbst schuld.
Hab seid 2 Jahren nicht mehr wirklich Javascript und co gecodet für mich is der noch da. xD Aber selbst wenn ausgestorben möchte ich doch das es so ziehmlich überall funkt ;)

Das ist ja ein lustiges Konstrukt... warum machst du nicht einfach nur
Code:
return obj.classList.contains(clas);
?.
Weil ich nicht drann gedacht habe das dass ja auch true oder false liefert xDD

so siehts jetzt aus:
Code:
_$ = function(clas, parent){
    var ret = [];
    var pardoc = document.getElementById(parent) || document;   

    if(pardoc.getElementsByClassName){
        var obj = pardoc.getElementsByClassName(clas);
        for(var i=0, l=obj.length; i<l; i++){
            ret.push(obj[i]);
        }
    }else if(document.querySelectorAll){
        var query = parent ? '#'+parent+' .'+clas : '.'+clas;
        var obj = document.querySelectorAll(query);
        for(var i=0, l=obj.length; i<l; i++){
            ret.push(obj[i]);
        }
    }else{
        var obj = (document.getElementById(parent) || document.body).getElementsByTagName('*');
        obj = obj[0] ? obj : document.all;        

        for( var i=0, l=obj.length; i<l; i++){
            if(hasClass(obj[i], clas)){
                if(obj != document.all ||
                   (obj == document.all && !parent) ||
                   (parent && obj[i].parentNode.id === parent)){
                    ret.push(obj[i]);
                }
            }
        }
    }
    return ret;
}

hasClass = function(obj, clas){
    var clas_erg = [];
    if(obj.classList){
        return obj.classList.contains(clas);
    }else if(obj.className){
        clas_erg = obj.className != "" ? obj.className.split(" ") : null;
    }else if(obj.getAttribute("class")){
        clas_erg = obj.getAttribute("class") != "" ? obj.getAttribute("class").split(" ") : null;
    }else return false;
    if(clas_erg == null) return false;
    
    for(var i=0, l=clas_erg.length; i<l; i++){
        if(clas_erg[i] === clas) return true;
    }
    return false;
}

ps.: endlich machts der IE8 xDD
 
Zuletzt bearbeitet:
Hab seid 2 Jahren nicht mehr wirklich Javascript und co gecodet für mich is der noch da. xD Aber selbst wenn ausgestorben möchte ich doch das es so ziehmlich überall funkt ;)
auch vor 2 Jahren hat niemand mehr ernsthaft den IE 5 unterstützt. IE 6 gibt es seit 2001

Zumal es mit document.all nicht getan ist. Der IE 5 hat soviele Bugs und würde auf heutigen Seiten ständig abschmieren, wenn du JS zulassen würdest, dass niemand bis auf deine Seite kommt, der so einen Browser mit aktivierten JS benutzt.
 
auch vor 2 Jahren hat niemand mehr ernsthaft den IE 5 unterstützt. IE 6 gibt es seit 2001

Zumal es mit document.all nicht getan ist. Der IE 5 hat soviele Bugs und würde auf heutigen Seiten ständig abschmieren, wenn du JS zulassen würdest, dass niemand bis auf deine Seite kommt, der so einen Browser mit aktivierten JS benutzt.

Mir egal wenns nicht riesiger aufwand ist mach is ;)
 
Schön, dass es jetzt funktioniert.
Die Funktion arbeitet aber immer noch nicht in allen Fällen gleich: #PARENTID .CLASS ist nicht das gleiche wie hasClass(obj, clas) && obj.parendNode.id == parent
 
Ausserdem sollten die Events für onmousedown/mousmove ein return false zurück geben, da sonst Text markiert wird. Und der mousedown darüber hinaus noch e.preventDefault() aufrufen, da sonst das Dragen im Firefox ab und zu stockt.
 
Die Funktion arbeitet aber immer noch nicht in allen Fällen gleich: #PARENTID .CLASS ist nicht das gleiche wie hasClass(obj, clas) && obj.parendNode.id == parent

Schon klar das dass nicht das selbe ist, das bezieht sich ja auch auf das document.all für ie5 damit überprüf ich ob die erste obere ebene mit parent gleich ist. Ka wie ich das sonst machen sollte is der einfachste weg wenigstens sowas ähnliches reinzupacken ;)


Ausserdem sollten die Events für onmousedown/mousmove ein return false zurück geben, da sonst Text markiert wird. Und der mousedown darüber hinaus noch e.preventDefault() aufrufen, da sonst das Dragen im Firefox ab und zu stockt.
Danke für den Tipp das mit return false hatte ich mal gehört aber total vergessen das andere is mir neu ;)

ps.: hab alles nochmal nen bisschen geändert und neu hochgeladen, aber jetzt klappt irgent was nicht richtig im IE -.- das neu eingetragene fenster sieht nicht richtig aus und lässt sich nicht verschieben.

edit: Fehler gefunden!
edit2: neuer Fehler -.-. wieso kann ich die objeckte mit classe=dragobj nicht verschieben? mousedown bei window klappt ja sonst würde der ja nicht zur hand wechseln aber document.onmousemove/onmouseup klappt irgent wie net
edit3: geändert und jetzt will der IE mal wieder nicht ich ruf ja nen fenster mit verzögerung auf aber da kommt ne fehlermeldung zeile: 251 zeichen: 6 = Window.style.top = top+"px";
hab Window geürft mit nem alert und das object ist ok ka was da los ist
edit4: dummer fehler wurde behoben hoffe Ihr könnt mir trotzdem nochn paar tipps geben
 
Zuletzt bearbeitet:
Um das gleich zu machen, könntest du die .parentNode-Kette raufklettern und prüfen, ob irgendeines die richtige ID hat.
 
Was hälste davon?
Code:
_$ = function(clas, parent){
    var ret = [];
    var pardoc = document.getElementById(parent) || document;
    
    if(pardoc.getElementsByClassName){
        var obj = pardoc.getElementsByClassName(clas);
        for(var i=0, l=obj.length; i<l; i++){
            ret.push(obj[i]);
        }
    }else if(document.querySelectorAll){
        var query = parent ? '#'+parent+' .'+clas : '.'+clas;
        var obj = document.querySelectorAll(query);
        for(var i=0, l=obj.length; i<l; i++){
            ret.push(obj[i]);
        }
    }else{
        var obj = (document.getElementById(parent) || document.body).getElementsByTagName('*');
        obj = obj[0] ? obj : document.all;
        
        for( var i=0, l=obj.length; i<l; i++){
            if(hasClass(obj[i], clas)){
		var parentobj = obj[i];
		
                if(obj != document.all || (obj == document.all && !parent)){
                    ret.push(obj[i]);
                }else if((obj == document.all && parent)){
		    while(parentobj.parentNode){
			if(parentobj.parentNode.id === parent) ret.push(obj[i]); break;
			parentobj = parentobj.parentNode;
		    }
		}
            }
        }
    }
    return ret;
}
 
Zuletzt bearbeitet:
Hm... langsam wird's.
Warum du im letzten else der ersten Ebene nicht pardoc verwendest, ist mir nicht ganz klar. Außerdem kann es passieren, dass pardoc einfach kein Element enthält und deswegen obj[0] nicht existiert - und nicht weil der Browser die Schreibweise mit * nicht unterstützt.

Die Variable parentobj wird an der falschen Stelle erstellt - die wird erst vor dem while benötigt.

Auch das if vor dem while ist unnötig - durch die erste Abfrage, kann da gar nichts anderes mehr übrig bleiben. Die Abfragen auf == document.all finde ich auch nicht so besonders schön - das lässt sich besser in einer Flag speichern.
 
Das mit dem obj[0] is ja nur wenn in einer id gar kein Objekt ist aber wie kann ich das rausfinden ob da nun gar keins ist oder nicht * erkannt wird?.
Hoffe sonst ist alles ok mit dem code.
Code:
SH.getByClass = function(clas, parent){
    var ret = [];
    var pardoc = document.getElementById(parent) || document;
    
    if(pardoc.getElementsByClassName){
        var obj = pardoc.getElementsByClassName(clas);
        for(var i=0, l=obj.length; i<l; i++){
            ret.push(obj[i]);
        }
    }else if(document.querySelectorAll){
        var query = parent ? '#'+parent+' .'+clas : '.'+clas;
        var obj = document.querySelectorAll(query);
        for(var i=0, l=obj.length; i<l; i++){
            ret.push(obj[i]);
        }
    }else{
	var all = false;
        var obj = pardoc.getElementsByTagName('*');
        if(!obj[0]) obj = document.all; all = true;
        for( var i=0, l=obj.length; i<l; i++){
            if(SH.hasClass(obj[i], clas)){
                if(!all || (all && !parent)){
                    ret.push(obj[i]);
                }else{
                    var parentobj = obj[i]
		    while(parentobj.parentNode){
			if(parentobj.parentNode.id === parent) ret.push(obj[i]); break;
			parentobj = parentobj.parentNode;
		    }
		}
            }
        }
    }
    return ret;
}

Hab alles mal in nen "Namespace" reingepackt und neu benannt

edit: mir is was eingefallen weis aber nicht ob das so in ordnung ist
Code:
if((!obj[0] && !parent) || (parent && parent.firstChild && obj[0])){ obj = document.all; all = true;}
 
Zuletzt bearbeitet:
Zurück
Oben