abcd423417984 Skrevet 24. mai 2007 Skrevet 24. mai 2007 (endret) Hei Har laget et javascript (basert på et jeg fant på nett) for å flytte en div. Problemet oppstår når jeg registrerer en eventhandler for onmousemove. I Firefox funker alt glimrende, men når funksjonen/eventhandlern skal kjøres i IE (7) sendes ikke event argumentet med (er null). Er ikke i stand til å finne ut hvorfor det i IE ikke sendes med argument når alt funker i firefox. På alle kilder jeg har funnet står det at IE støtter propertiene i event-argumentet, derfor har jeg også tatt det som gitt at event-argumentet faktisk skal eksistere. HTML dokumentet ligger på: http://www.mediafire.com/?fnxxz2fydkp function mousemove(event) { if(over) { if(event == null) //for debugging { alert("event is null for some reason!"); over = false; return; } var ob = document.getElementById("panel"); ob.style.top = event.pageY - Y; ob.style.left = event.pageX - X; } } document.onmousemove = mousemove; Feilen oppstår på linjen hvor det sies event.pageY fordi event ikke er et objekt. alertbeskjeden vil aldri kjøres i firefox, mens den alltid kjøres i IE7. Endret 24. mai 2007 av invictus
LostOblivion Skrevet 25. mai 2007 Skrevet 25. mai 2007 (endret) Jeg vet ikke om det hjelper, men event blir sendt som argument til en eventhandlerfunksjon uansett om du inkluderer event-variabel i argumentlista, så kanskje når du lager din egen event så overskriver du IE sin eller et eller annet... Jeg vet at i Java må man ha med denne og kan kalle den hva man vil, men er litt usikker i JavaScript. Tror jeg hvertfall. (IE er jo alltid litt upålitelig, hvis du skjønner hva jeg mener. ) Du kan jo prøve noe som under f eks. document.onmousedown = function() { if (over) { var ob = document.getElementById("panel"); X = event.layerX; Y = event.layerY; return false; } } document.onmousemove = function() { //if (ob) if(over) { if(event == null) //for debugging { alert("event is null for some reason!"); over = false; return; } var ob = document.getElementById("panel"); ob.style.top = event.pageY - Y; ob.style.left = event.pageX - X; } } Jeg svært usikker på dette, men hvis jeg ikke tar feil, fungerte dette for meg i IE6. Edit: Prøvde, men fungerer ikke noe bedre er jeg redd. Beklager. Endret 25. mai 2007 av LostOblivion
luxus Skrevet 26. mai 2007 Skrevet 26. mai 2007 (endret) Event i IE må hentes ut i fra window.event. Dette vil vil antageligvis hjelpe deg: function mousemove(event) { // Henter ut event egenskaper event = event || window.event; // Bruker event hvis finnes, eller window.event var target = event.target || event.srcElement; // Bruker target, eller IEs versjon srcElement if ( target.nodeType == 3 ) { // Fikser safaribug target = target.parentNode; } if(over) { [...] Når det er sagt tror jeg nok du vil få litt problemer med pageX/Y. Du kan lese mer om det på http://www.quirksmode.org/js/events_properties.html. På Quirksmode står det ganske mye om forskjeldene på de forskjellige browserene og hvordan man kommer rundt de. Endret 26. mai 2007 av luxus
abcd423417984 Skrevet 26. mai 2007 Forfatter Skrevet 26. mai 2007 Jepp det stemmer. Virker som Mozilla støtter pageX/Y mens IE ikke gjør det. Videre støtter mozilla layerX/Y mens ikke IE. IE derimot støtter offsetX/Y men det gjør ikke mozilla. I tillegg behandler visstnok opera, konquerer, safari osv clientx/y forskjellig. Av og til er det fristende å gi opp alt som er av webutvikling så lenge ingen browsere støtter noe felles
luxus Skrevet 26. mai 2007 Skrevet 26. mai 2007 hehe, joda.. Men som det står på Quirksmode, for å få ut riktige mousepos:: function doSomething(e) { var posx = 0; var posy = 0; if (!e) var e = window.event; if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else if (e.clientX || e.clientY) { posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } // posx and posy contain the mouse position relative to the document // Do something with this information } Det kan jo også være en ide å bruke et bibliotek som YUI, http://developer.yahoo.com/yui/event/. Da kan du la biblioteket ta seg av disse forskjeldene.
abcd423417984 Skrevet 27. mai 2007 Forfatter Skrevet 27. mai 2007 Flott. Dette så ut til å funke. Det jeg da må gjøre er å finne ut en nøyaktig metode for å regne ut de lokale x og y kordinatene i forhold til komponenten jeg trykker på. For det bruker jeg for øyeblikket følgende kode: function mousedown(e) { if (over) { e = e || window.event; ob = document.getElementById("panel"); ob = ob.style; X= e.layerX ? e.layerX : e.offsetX; Y= e.layerY ? e.layerY : e.offsetY; } } I koder her er det de 2 siste linjene som er viktig. Her sier jeg at X skal være e.layerX hvis den eksisterer og hvis ikke skal den være offsetX. Dessverre er ikke layerX og offsetX det samme, noe som fører til en løsning som ikke er riktig på de forskjellige nettleserne. Noen forslag? mozilla støtter layerX, mens resten tilsynelatende støtter offsetX
abcd423417984 Skrevet 27. mai 2007 Forfatter Skrevet 27. mai 2007 Fant en kode som visstnok skulle løse problemet ved å lage en offsetX lignende metode i firefox: var Element = evt.target; var CalculatedTotalOffsetLeft = CalculatedTotalOffsetTop = 0; while (Element.offsetParent) { CalculatedTotalOffsetLeft += Element.offsetLeft; CalculatedTotalOffsetTop += Element.offsetTop; Element = Element.offsetParent; }; OffsetXForFirefoxOrNetscape = evt.pageX - CalculatedTotalOffsetLeft; OffsetYForFirefoxOrNetscape = evt.pageY - CalculatedTotalOffsetTop; Når jeg tolket denne koden og skrev noe tilsvarende i min egen kode endte jeg opp med følgende: function mousedown_beta(e) { if (over) { var posx = 0; var posy = 0; e = e || window.event; ob = document.getElementById("panel"); if (e.offsetX || e.offsetY) { posx = e.offsetX; posy = e.offsetY; } else if (e.layerX || e.layerY) { var OffsetLeft = 0; var OffsetTop = 0; var Element = ob; while (Element.offsetParent) { OffsetLeft += Element.offsetLeft; OffsetTop += Element.offsetTop; Element = Element.offsetParent; }; posx = ob.pageX - OffsetLeft; posy = ob.pageY - OffsetTop; alert("x: " + posx + ", y=" + posy); } X = posx; Y = posy; } } Problemet her er bare at den alert()'en jeg har satt inn rapporterer at resultatet er NaH i begge tilfeller. Jeg aner ikke hva NaH betyr og hvordan fikse dette.
luxus Skrevet 27. mai 2007 Skrevet 27. mai 2007 (endret) Denne koden skal fungere i både FF, IE og Opera: Klikk for å se/fjerne innholdet nedenfor <html> <head> <style> .titlebar { width: 100%; background-color: #99CCFF; border-bottom: 1px solid blue; font-size: 14px; font-family: verdana; color: #000000; text-align: center; cursor: move; } .panel { width: 150; position: absolute; border: 1px solid blue; left: 350; top: 200; font-size: 13px; font-family: verdana; } .content { width: 100%; background-color: yellow; font-size: 13px; font-family: verdana; } </style> <script type="text/javascript"> /** * Funksjonen blir kalt på når musa presses ned * * @param {Event} e Event objektet */ function mouseDown(e) { e = e || window.event; var panel = document.getElementById("panel"); var mpos = getMousePos(e); // Finner ut hvor musa er i forhold til top/venstre posisjonen til panelet. // Parseint er er fordi top/left er string, og 10 forsikrer at parsinga går etter titallssystemet. panel.mouseXOffset = mpos.x - parseInt(panel.style.left, 10); panel.mouseYOffset = mpos.y - parseInt(panel.style.top, 10); // Gjør slik at mouseMove metoden får lov til å flytte på panalet. panel.isDragging = true; } /** * Funksjonen blir kalt på når musetasten slippes * * @param {Event} e Event objekte */ function mouseUp(e) { // "Resetter panelegenskapene" var panel = document.getElementById("panel"); panel.mouseXOffset = undefined; panel.mouseYOffset = undefined; panel.isDragging = false; // Dragging skal nå ikke skje mer } /** * Funksjonen blir kalt på når musa flyttes over et element * * @param {Event} e Event objekte */ function mouseMove(e) { var panel = document.getElementById("panel"); var mpos; if (panel.isDragging) { // isDragging er satt til true av mouseDown funksjonen, så da flyter vi på panelet.. mpos = getMousePos(e); panel.style.top = (mpos.y - panel.mouseYOffset) + "px"; panel.style.left = (mpos.x - panel.mouseXOffset) + "px"; } } /** * ET PAR GENERELLE FUNKSJONER SOM VI TRENGER KOMMER HER: */ /** * Henter ut museposisjonen, fungerer både i IE, FF og Opera * Museposisjon er relativ til dokumentet og ikke skjermen. * * @param {Event} e Event objektet * @return {Object} Ett objekt som inneholder x og y, altså museposisjonen */ function getMousePos(e) { // Oppretter variable var posx = 0; var posy = 0; // Sjekker om vi har W3C sin måte å gjøre det på (FF og Opera vil gå inn her) if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else if (e.clientX || e.clientY) { // IE posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } // Returnerer et objekt med verdien X og Y i som vi akkurat har funnet.. return {x: posx, y: posy}; } /** * Legger på en eventhandler på node * * @param {HTMLElement} node Noden å sette eventhandleren på * @param {String} type Hva slags type event skal den reagere på? * @param {function} f Funksjonen som skal kalles på */ function addEventHandler(node, type, f) { if ( node.addEventListener ) { // w3c node.addEventListener(type, f, false); // false -> event bubbles up } else if ( node.attachEvent ) { // ie node.attachEvent("on"+type, f); } else { // Dette burde virke på alle, men kan ikke legge på mer enn en event handler pr element node["on"+type] = f; } } /** * GENERELLE FUNKSJONER SLUTTER HER */ // Legger på eventhandlers når onload blir kalt, altså når siden er lastet inn window.onload = function() { var panel = document.getElementById("panel"); addEventHandler(panelHead, "mousedown", mouseDown); addEventHandler(panelHead, "mouseup", mouseUp); addEventHandler(panelHead, "mousemove", mouseMove); }; </script> </head> <body> <div style="top: 157px; left: 257px;" id="panel" class="panel"> <div class="titlebar" id="panelHead"> <b>title</b> </div> <div class="content">content</div> </div> <p> </p><center>this is a website</center> <p> </p> </body> </html> Jeg gjorde et par forandringer. For det første fjerna jeg in-line event-kallene dine. Alså der du hadde <div style="top: 157px; left: 257px;" id="panel" class="panel" onmousedown="gjør noe">. Det er bedre å la JavaScript selv legge på slike ting, og ikke skrive in-line JavaScript i HTMLen Videre fjernet jeg de globale variablene du hadde, "X", "Y" og "over" variabelene dine. Det er best å ha så lite globale variable som mulig. Disse variablene er nå lagt / blir lagret på selve DIVen med id panel. De heter nå mouseXOffset, mouseYOffset og isDragging. Håper det hjelper. Det virka i allefall her i både Firefox, Opera og IE6 da jeg testa koden jeg skrev. Endret 27. mai 2007 av luxus
abcd423417984 Skrevet 27. mai 2007 Forfatter Skrevet 27. mai 2007 (endret) Denne funket ikke helt optimalt i firefox2. Den virker tilsynelatende, men på spesielle posisjoner så slutter den å dra av seg selv. EDIT: samme problem i opera. virker som det skjer hvis jeg drar for fort Endret 27. mai 2007 av invictus
luxus Skrevet 27. mai 2007 Skrevet 27. mai 2007 Problemet her er bare at den alert()'en jeg har satt inn rapporterer at resultatet er NaH i begge tilfeller. Jeg aner ikke hva NaH betyr og hvordan fikse dette. 8713931[/snapback] Du får feilen NaN vel? Og ikke NaH skulle jeg tro. NaN står for Not a Number, og det kommer av dette: posx = ob.pageX - OffsetLeft; I variabelen pageX ligger det f.eks. "50px".. Altså er dette en tekststreng. I OffsetLeft der i mot ligger det et heltall (integer).. Du må gjøre om (parse) pageX-tekststrengen til et heltall før du kan bruke variabelen i en regneopperasjon. Med andre ord: posx = parseInt(ob.pageX, 10) - OffsetLeft; vil bli riktig. pageX vil bli gjort om til heltall, og 10 indikerer at tallet som skal parses er på formen titallssystemet.
luxus Skrevet 27. mai 2007 Skrevet 27. mai 2007 Denne funket ikke helt optimalt i firefox2. Den virker tilsynelatende, men på spesielle posisjoner så slutter den å dra av seg selv. EDIT: samme problem i opera. virker som det skjer hvis jeg drar for fort 8714340[/snapback] Bytt ut addEventHandler(panelHead, "mousemove", mouseMove); med addEventHandler(document, "mousemove", mouseMove); kanskje. Det skjer nok fordi musa kommer utenfor panelet, før panelet rekker å følge med. Derfor så blir det plutselig ikke registrert at den flytter på seg tenker jeg.
abcd423417984 Skrevet 27. mai 2007 Forfatter Skrevet 27. mai 2007 Denne funket ikke helt optimalt i firefox2. Den virker tilsynelatende, men på spesielle posisjoner så slutter den å dra av seg selv. EDIT: samme problem i opera. virker som det skjer hvis jeg drar for fort 8714340[/snapback] Bytt ut addEventHandler(panelHead, "mousemove", mouseMove); med addEventHandler(document, "mousemove", mouseMove); kanskje. Det skjer nok fordi musa kommer utenfor panelet, før panelet rekker å følge med. Derfor så blir det plutselig ikke registrert at den flytter på seg tenker jeg. 8714380[/snapback] Ser ut til å funke i mozilla og opera nå ja Et annet spørsmål...i Opera og i IE7 så vil tekst bli markert av seg selv når man drar panelet rundt...er det noen måte å hindre dette?
abcd423417984 Skrevet 27. mai 2007 Forfatter Skrevet 27. mai 2007 Problemet her er bare at den alert()'en jeg har satt inn rapporterer at resultatet er NaH i begge tilfeller. Jeg aner ikke hva NaH betyr og hvordan fikse dette. 8713931[/snapback] Du får feilen NaN vel? Og ikke NaH skulle jeg tro. NaN står for Not a Number, og det kommer av dette: posx = ob.pageX - OffsetLeft; I variabelen pageX ligger det f.eks. "50px".. Altså er dette en tekststreng. I OffsetLeft der i mot ligger det et heltall (integer).. Du må gjøre om (parse) pageX-tekststrengen til et heltall før du kan bruke variabelen i en regneopperasjon. Med andre ord: posx = parseInt(ob.pageX, 10) - OffsetLeft; vil bli riktig. pageX vil bli gjort om til heltall, og 10 indikerer at tallet som skal parses er på formen titallssystemet. 8714354[/snapback] posx = parseInt(...) fungerte ikke. Får fremdeles NaN på denne. Har jo alltids koden du skrev som jeg kan jobbe videre på, men skulle gjerne likt å visst hvor ting gikk galt i min egen kode også.
luxus Skrevet 27. mai 2007 Skrevet 27. mai 2007 Hm, hva ligger i OffsetLeft da - Også en string kanskje? For alt må i allefall parses der posx = parseInt(ob.pageX, 10) - parseInt(OffsetLeft, 10); Når det gjelder det med at teksten ikke skal være mulig å markere, så kanskje http://www.tek-tips.com/viewthread.cfm?qid=1184318&page=1 kan hjelpe. Jeg har ikke gjort noe slikt før så.
abcd423417984 Skrevet 27. mai 2007 Forfatter Skrevet 27. mai 2007 (endret) posx = ob.pageX - OffsetLeft; posy = ob.pageY - OffsetTop; Skal selvfølgelig være: posx = e.pageX - OffsetLeft; posy = oe.pageY - OffsetTop; Det funker nå Men la meg spørre deg om en annen ting: I koden din skriver du bare panel.mouseXOffset = undefined; panel.mouseYOffset = undefined; panel.isDragging = false; // Dragging skal nå ikke skje mer Er det lov å bare "opprette" variabler i elementer på den måten? Endret 27. mai 2007 av invictus
luxus Skrevet 27. mai 2007 Skrevet 27. mai 2007 Ja, det er lov, jeg har ikke lest noen som har noe i mot det i allefall. Og vil si det er mye bedre enn å opprette globale variable. Kanskje ikke så viktig å tenke på i små scripts, men når scriptet blir større / du henter inn kode som andre har skrevet er det lurt å passe på å holde sine variabelnavn utenfor det globale skopet.
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå