| Så här borde det gå: (jag har skrivet en del noteringar som kommentarer) var config = { rows: '5', cols: '25', okButtonText: 'Spara', cancelButtonText: 'Avbryt' }; // identifierar editerbara element när sidan startas, aktiverar funktionen inPlaceEditor window.onload = function () { var pElements = document.getElementsByTagName('*'); //EDIT: (För klarhet bör du nog använda någon specialkonstruerad variant av document.getElementsByClassName här, istället för en egen loop.) for (var i=0; i < pElements.length; i++) { if(pElements[i].className == 'editable') inPlaceEditor(pElements[i]); }; }; function inPlaceEditor (editableElement) { // EDIT: "normalisera" elementet så att det bara finns en enda textnod, om någon editableElement.normalize(); // klick på editerbart element startar en funktion editableElement.onclick = function() { // EDIT: om det redan finns ett "barn" i editerbara elementet (p-taggen) så händer inget // (enklare att avbryta med return; om inget annat ska göras ändå, indenteringsnivån // bör inte bli för stor.) if(this.firstChild != this.lastChild) return; var text = getTextArea(this); // startar funktionen getTextArea var buttons = getButtons(text.div); // startar funktionen getButtons this.className = 'not_editable'; var container = this; // avbryt-knappens funktion definieras buttons.cancel.onclick = function(e) //EDIT: Parametern e följer med som en event i alla andra webbläsare än IE { // vid klick på avbryt-knappen .. container.firstChild.nodeValue = text.origText; // .. återgår textrutans text till ursprungstexten .. container.removeChild(text.div); // .. den tillfälliga diven med textrutan tas bort (EDIT: text.div är tydligare än childNodes[1]) container.className = 'editable'; // ursprungstexten görs åter editerbar // kod som medger att man kan klicka på och aktivera textrutans innehåll utan att samtidigt aktivera "containern" if (!e) e = window.event; //EDIT: För IE ska window.event användas istället. Ändra bara variabeln om e inte finns, lägg inte all kod här. if (e.stopPropagation) e.stopPropagation(); return false; } // redigeringsknappens funktion definieras buttons.edit.onclick = function(e) { //EDIT: Istället för att skapa nya noder kan vi göra som i cancel och bara ändra den gamla var newText = text.textarea.value; // den nyredigerade texten samlas upp i variablen newText container.firstChild.nodeValue = newText; container.removeChild(text.div); container.className='editable'; if (!e) e = window.event; if (e.stopPropagation) e.stopPropagation(); return false; } } } function getTextArea(obj) { var origText = obj.firstChild.nodeValue; // lägg den ursprungliga texten i variabeln origText obj.firstChild.nodeValue = ''; var div = document.createElement("div"); // skapa ett div-element för att lagra den tillfälliga textrutan //div.setAttribute("id","lager"); // ge den skapade diven id=lager //EDIT: (id's behövs inte, det räcker att referera till yttre variabler som innehåller elementen (som finns kvar tack vare closures.)) obj.appendChild(div); // lägg denna div som barn till p-taggen var textarea = document.createElement("textarea"); // skapa en textruta textarea.setAttribute("cols", config.cols); // hämta textrutans kolumnstorlek från var config textarea.setAttribute("rows", config.rows); // hämta textrutans radstorlek från var config textarea.value = origText; // lägg den ursprungliga texten i textrutan div.appendChild(textarea); // lägg textrutan i den skapade diven // skapa den redigerbara textrutan, lägg in ursprungstexten och placera allt i den skapade diven var text = { 'origText': origText, 'textarea': textarea, 'div': div } return text; } function getButtons(obj) { var br = document.createElement("br"); // skapa radbrytning för att knapparna ska komma under textrutan var edit = document.createElement("input"); // skapa editeringsfunktion edit.setAttribute("type", "button"); // knyt editeringsfunktionen till en knapp edit.setAttribute("value", config.okButtonText); // hämta upp data från var config obj.appendChild(br); // koppla radbrytning till knappen obj.appendChild(edit); // koppla editeringsfunktionen till knappen var cancel = document.createElement("input"); // skapa avbrytfunktionen cancel.setAttribute("type", "button"); // knyt avbrytfunktionen till knappen cancel.setAttribute("value", config.cancelButtonText); // hämta data från var config obj.appendChild(cancel); // koppla avbrytfunktionen till knappen // skapa knapparna var buttons = { 'edit': edit, 'cancel': cancel } return buttons; } Notera också att ditt skript konkurrerar med ett annat skript du har skrivit; båda använder variabeln "config" och skriver över window.onload. För det andra problemet kan du använda någon annan event-metod (som den från "javascript replace"-tråden) eller (vilket också skulle förenkla din kod betydligt, men kanske är något kontraproduktivt om du ska lära dig JavaScripts inbyggda DOM-funktioner) använda jQuery (se $(document).load). För att undvika problemet med namnkollisioner är den bästa lösningen helt enkelt att innesluta hela din kod i (function(){...})(); så att de variabler du använder hamnar som closures för din kod, men ingen annans. (Om du ska deklarera globala funktioner kan du använda window.f=... eller strunta i 'var' framför.) Du verkar också ha en del onödiga kommentarer. Att kommentera div.appendChild(textarea); med // lägg textrutan i den skapade diven är helt onödigt (det följer utifrån koden, och följer inte principen att kommentera 'vad' koden gör istället för 'hur') och gör den bara mer oläslig. | | Hej! Med följande javascript kan jag editera text och spara den nya texten med class editable, men trots det är den sparade texten inte editerbar. Hur kan det komma sig? Hur ska jag skriva scriptet för att få den editerade sparade texten åter editerbar? <snip> |
|