Expandera/Döja text, allt i Javascript

Permalänk
Medlem

Expandera/Döja text, allt i Javascript

Har två text stycken som skall vara dolda från början men som ska expanderas/döljas med två olika länkar. All funkar bra med länkarna i HTML dokumentet men när jag plockar bort dom och sätter in dom med createElement i Javascriptet så funkar det helt enkelt inte.

Om nån vill testa kan man enkelt skapa en länk i HTML dokumentet och kalla på scriptet med onclick showHide(this.id,show1) för första paragrafen. Men som sagt, jag vill ha det funkerade med att även ha länkarna skapta i Javascript. Så vad är det jag missar?

Så om nån upptäcker mitt fel så är jag glad för feedback på vad som är fel.

HTML koden är basic...

<!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Javascript Hidden textarea</title> <link href="style.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/js_hiddentext.js"></script> </head> <body> <div id="container"> <div id="content"> <div class="post"> <h3> Javascript </h3> <p class="author"> posted by </p> <aside> Använda Javascript </aside> <p> En introduktionstext som skall bli längre.... </p> <p class="show" id="show1"> ...så att vidare information kan visas. Här kommer då en längre exempel text där användaren kan läsa mera om just denna post. Detta är en vanlig funktion som du kan hitta på många vanliga webbsidor som säljer produkter. </p> </div> <div class="post"> <h3> Javascript </h3> <p class="author"> posted by </p> <aside> Tänk vad mycket man kan göra </aside> <p> Även detta textstycke skall utökas... </p> <p class="show" id="show2"> ...så att vidare information kan visas. Här kommer då en längre exempel text där användaren kan läsa mera om just denna post. Detta är en vanlig funktion som du kan hitta på många vanliga webbsidor som säljer produkter. </p> </div> </div> </div> </body> </html>

Javascriptet...

/* Function created by "Simon Willson" to be able to call several functions with a single event */ //Create the function function addLoadEvent(func) { //Create a variable for window.onload event var oldonload = window.onload; //If window.onload is NOT a function, then assign 'func' to window.onload if (typeof window.onload != 'function') { window.onload = func; //If window.onload already is a function then make a new function } else { window.onload = function() { //To do what the old onload function did if (oldonload) { oldonload(); } //then do whatever the new function does func(); } } } //Create two links, link1 & link2 and position them before each relevant paragraph element function newLink() { var dv, newLink; dv = document.getElementById('show1'); newLink = document.createElement('a'); newLink.setAttribute('id','show1_link'); newLink.setAttribute('href','#'); newLink.setAttribute('onclick','showHide(this.id,elemId);'); var newLinkText = document.createTextNode('Visa mera information'); newLink.appendChild(newLinkText); dv.parentNode.insertBefore(newLink,show1); } addLoadEvent(newLink); function newLink2() { var dv, newLink; dv = document.getElementById('show2') newLink = document.createElement('a'); newLink.setAttribute('id','show2_link'); newLink.setAttribute('href','#'); newLink.setAttribute('onclick','showHide(this.id,elemId);'); var newLinkText = document.createTextNode('Visa mera information'); newLink.appendChild(newLinkText); dv.parentNode.insertBefore(newLink,show2); } addLoadEvent(newLink2); function showHide(link_id,elemId) { //Create a variable for the link and the paragraph var link = document.getElementById(link_id); var text = document.getElementById(elemId); //Make a check to distinguish visible from hidden var status = (text.style.display == 'block') ? 'none' : 'block'; text.style.display=status; //Change the text on the link depending on if the value is true or false link.innerHTML = (status == 'block') ? 'Visa mindre information' : 'Visa mera information'; } adLoadEvent(showHide);

För att komma åt dom båda paragraferna lade jag även in var sitt Id, optimalt vore om man endast kunde kalla på klassen show, så det får vara tills vidare om ingen annan har en bra lösning på även de. Måste skriva om funktionen i så fall...

Permalänk
Medlem

Förenklad funktion

Skrev om länken och förenklade funktionen med ternary option så den verkligen blir enkel att läsa, nu fungerar den med att visa/dölja texten

function newLink() { //Make a few safety check to see if the browser can handle the elements if (!document.getElementById) { if (!document.createElememt) { if (!document.createTextNode) { return false; } } } //Create the link newLink = document.createElement('a'); //Set the href newLink.href = "javascript:showHide(document.getElementById('show1'))"; //Give the link a Id newLink.id = "show1_link"; //Create a variable for the link text var newLinkText = document.createTextNode('Visa mera information'); //Append the text to the link newLink.appendChild(newLinkText); //Create a variable for the paragraph var elem = document.getElementById('show1') //Insert the text before the paragraph with the Id show1 elem.parentNode.insertBefore(newLink,show1); } addLoadEvent(newLink); function showHide(text) { //Choose display options using ternary option text.style.display = (text.style.display == 'block') ? 'none' : 'block'; }

Nu behöver jag bara få in i funktionen att den ändrar text på länken beroende på status Visa mera information/Visa mindre information

Jag hade tänkt något i still med

function showHide(link_id,elemid) { var link = getElementById(link_id); var text = getElementById(elemId); text.style.display = (text.style.display == 'block') ? 'none' : 'block'; var status = (text.style.display == 'block') ? 'none' : 'block'; text.style.display = status; link.innerHTML = (status == 'block') ? 'Dölj information' : 'Visa mera infomration'; } addLoadEvent(showHide);

Sen ändra: newLink.href = 'javascript:showHide(this.id,elemId)';

Men den vill inte som jag vill, någon som har nån bra idé? Måste ha en variabel som kollar vilken länk som används och sedan ändra länk texten som används beroende på om display är 'block' eller 'none'

Permalänk
Permalänk
Medlem

Kommer dit senare, först vill jag verkligen greppa detta. Känns som det är något litet jag missar för att mitt script jag länkade först funkade med länkarna i HTML dokumentet men inte när jag skapade dom dynamiskt. Vill få en förståelse för vad jag missar... Fast nu funkar det att visa/dölja, bara problemet kvar att ändra namn på länkarna i samband med aktivering.

Permalänk
Medlem

Har uppdaterat min kod men får "elemId is not defined", hänger inte riktigt med på vad felet är. Några förslag?

function newLink() { //Make a few safety check to see if the browser can handle the elements if (!document.getElementById) { if (!document.createElememt) { if (!document.createTextNode) { return false; } } } //Create the link newLinkElement = document.createElement('a'); //Give the link a Id newLinkElement.id = "show1_link"; //Set the href newLinkElement.href = 'javascript:showHide(this.id,elemId)'; //Create a variable for the link text var linkText = document.createTextNode('Visa mera information'); //Append the text to the link newLinkElement.appendChild(linkText); //Create a variable for the paragraph var elem = document.getElementById('show1') //Insert the text before the paragraph with the Id show1 elem.parentNode.insertBefore(newLinkElement,show1); } addLoadEvent(newLink); function showHide(link_id,elemId) { var link = document.getElementById(link_id); var text = document.getElementById(elemId); text.style.display = (text.style.display == 'block') ? 'none' : 'block'; var status = (text.style.display == 'block') ? 'none' : 'block'; text.style.display = status; link.innerHTML = (status == 'block') ? 'Dölj information' : 'Visa mera infomration'; }

Permalänk
Medlem
Skrivet av Angel78:

Har uppdaterat min kod men får "elemId is not defined", hänger inte riktigt med på vad felet är. Några förslag?

function newLink() { //Make a few safety check to see if the browser can handle the elements if (!document.getElementById) { if (!document.createElememt) { if (!document.createTextNode) { return false; } } } //Create the link newLinkElement = document.createElement('a'); //Give the link a Id newLinkElement.id = "show1_link"; //Set the href newLinkElement.href = 'javascript:showHide(this.id,elemId)'; //Create a variable for the link text var linkText = document.createTextNode('Visa mera information'); //Append the text to the link newLinkElement.appendChild(linkText); //Create a variable for the paragraph var elem = document.getElementById('show1') //Insert the text before the paragraph with the Id show1 elem.parentNode.insertBefore(newLinkElement,show1); } addLoadEvent(newLink); function showHide(link_id,elemId) { var link = document.getElementById(link_id); var text = document.getElementById(elemId); text.style.display = (text.style.display == 'block') ? 'none' : 'block'; var status = (text.style.display == 'block') ? 'none' : 'block'; text.style.display = status; link.innerHTML = (status == 'block') ? 'Dölj information' : 'Visa mera infomration'; }

elemId är inte definierad. Vet inte hur man ska förklara det bättre än vad den redan gör
Ingenstans står det exempelvis
var elemId = 123;

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem

elemId är i funktionen showHide i variabeln text.

Men en lite ändrad kod så funkar det ända ner till var status och innerHTML, ger mig ett "link is null", kommenterar jag bort dom två så funkar showHide funktionen och just elemId också. Så på något sätt hittar den inte min länk text verkar det som. Så ny kod med dom två sista bort kommenterade

function newLink() { //Make a few safety check to see if the browser can handle the elements if (!document.getElementById) { if (!document.createElememt) { if (!document.createTextNode) { return false; } } } //Create the link newLinkElement = document.createElement('a'); //Give the link a Id newLinkElement.id = 'show1_link'; //Set the href newLinkElement.href = "javascript:showHide(this.id,'show1')"; //Create a variable for the link text var linkText = document.createTextNode('Visa mera information'); //Append the text to the link newLinkElement.appendChild(linkText); //Create a variable for the paragraph var elem = document.getElementById('show1') //Insert the text before the paragraph with the Id show1 elem.parentNode.insertBefore(newLinkElement,show1); } addLoadEvent(newLink); function showHide(link_id,elemId) { //function showHide(link_id,elemId) { var link = document.getElementById(link_id); var text = document.getElementById(elemId); text.style.display = (text.style.display == 'block') ? 'none' : 'block'; var status = (text.style.display == 'block') ? 'none' : 'block'; //text.style.display = status; //link.innerHTML = (status == 'block') ? 'Dölj information' : 'Visa mera infomration'; }

Permalänk
Skrivet av Angel78:

elemId är i funktionen showHide i variabeln text.

Men en lite ändrad kod så funkar det ända ner till var status och innerHTML, ger mig ett "link is null", kommenterar jag bort dom två så funkar showHide funktionen och just elemId också. Så på något sätt hittar den inte min länk text verkar det som. Så ny kod med dom två sista bort kommenterade

function newLink() { //Make a few safety check to see if the browser can handle the elements if (!document.getElementById) { if (!document.createElememt) { if (!document.createTextNode) { return false; } } } //Create the link newLinkElement = document.createElement('a'); //Give the link a Id newLinkElement.id = 'show1_link'; //Set the href newLinkElement.href = "javascript:showHide(this.id,'show1')"; //Create a variable for the link text var linkText = document.createTextNode('Visa mera information'); //Append the text to the link newLinkElement.appendChild(linkText); //Create a variable for the paragraph var elem = document.getElementById('show1') //Insert the text before the paragraph with the Id show1 elem.parentNode.insertBefore(newLinkElement,show1); } addLoadEvent(newLink); function showHide(link_id,elemId) { //function showHide(link_id,elemId) { var link = document.getElementById(link_id); var text = document.getElementById(elemId); text.style.display = (text.style.display == 'block') ? 'none' : 'block'; var status = (text.style.display == 'block') ? 'none' : 'block'; //text.style.display = status; //link.innerHTML = (status == 'block') ? 'Dölj information' : 'Visa mera infomration'; }

newLinkElement.href = "javascript:showHide(this.id,'show1')";

Varför skapar du inline javascript istället för att använda click()?

var link = document.getElementById(link_id)

Varför hämtar du elementet igen?
Är det inte smartare att skicka med this istället för this.id så att du slipper använda getElementById?
Eller om du använder click() och event.target.

Edit:
Och framförallt, varför i hela friden har du skapat funktionen newLink2 som innehåller exakt samma kod som newLink ?

Permalänk
Medlem

Menar du:

newLinkElement.href = 'javascript:void(0)'; newLinkElement.onclick = "showHide(this,'show1')";

Något åt de hållet?

Varför jag har var link i showHide funktionen är för att göra koden kortare och sen sätta in link.innerHTML med ny text med en ternary beroende på vad som är valt.

Skapade newLink2 för att den innehåller href "show2" eftersom newLink innehåller href "show1", förstår inte helt hur jag skulle kunna kalla på samma createElement med en enda funktion som sedan skulle ha två olika href eftersom den ena har Id "show1" och den andra Id "show2".

Vill helt enkelt förstå hur jag skickar länk namnet och sen ändra det. Trodde jag gjorde de för att när länkarna låg ute i html dokumentet löste jag det med denna funktion men inte dynamiskt. Tror inte jag riktigt förstår hur jag skulle tillämpa det du menar i min funktion, du får gärna skriva om den så den funkar med någon fin kommentar som jag kan ta del utav och försöka förstå.

Permalänk
Medlem

Löste mitt problem, kanske någon annan undra samma sak någon gång så klistrar jag in hela mitt Javascript, finns optimeringar att göra som jag kommer försöka lösa senare men tills vidare så är en fungerande kod iallafall:

/* Function created by "Simon Willson" to be able to call several functions with a single event */ //Create the function function addLoadEvent(func) { //Create a variable for window.onload event var oldonload = window.onload; //If window.onload is NOT a function, then assign 'func' to window.onload if (typeof window.onload != 'function') { window.onload = func; //If window.onload already is a function then make a new function } else { window.onload = function() { //To do what the old onload function did if (oldonload) { oldonload(); } //then do whatever the new function does func(); } } } //Add as many functions you like with addLoadEvent(functionName); //Create the show/hide function function showHide(link_id,elemId) { //Make a variable for the link (link_id) and for the paragraph (elemId) var link = document.getElementById(link_id); var text = document.getElementById(elemId); //If the content is hidden set the link text to 'Visa mera infomration' if (text.style.display == 'block') { link.innerHTML = 'Visa mera information'; text.style.display = 'none'; //if content is visible change the link text to 'Dölj information' } else { link.innerHTML = 'Dölj information'; text.style.display = 'block'; } } //Create two links, link1 & link2 and position them before each relevant paragraph element function newLink() { //Make a few safety check to see if the browser can handle the elements if (!document.getElementById) { if (!document.createElememt) { if (!document.createTextNode) { return false; } } } //Create the link a = document.createElement('a'); //Give the link a Id a.id = 'show1_link'; //Set the href a.href = "javascript:showHide('show1_link','show1')"; //Create a variable for the link text var linkText = document.createTextNode('Visa mera information'); //Append the text to the link a.appendChild(linkText); //Create a variable for the paragraph var elem = document.getElementById('show1') //Insert the text before the paragraph with the Id show1 elem.parentNode.insertBefore(a,show1); } addLoadEvent(newLink); function newLink2() { //Create the link a = document.createElement('a'); //Give the link a Id a.id = 'show2_link'; //Set the href a.href = "javascript:showHide('show2_link','show2')"; //Create a variable for the link text var linkText = document.createTextNode('Visa mera information'); //Append the text to the link a.appendChild(linkText); //Create a variable for the paragraph var elem = document.getElementById('show2') //Insert the text before the paragraph with the Id show2 elem.parentNode.insertBefore(a,show2); } addLoadEvent(newLink2);

Hade gärna löst detta med en enda länk funktion men är inte helt klar med hur man kallar på samma funktion och positionerar den länken före ett annat p element när elem.parentNode.insertBefore.(a,show1); redan pekar på mitt första p element.

Den som vet får gärna försöka sig på att ändra koden och eventuellt slänga in lite kommentarer, väldigt intresserad av att försöka förstå det hela.

Permalänk
Skrivet av Angel78:

Den som vet får gärna försöka sig på att ändra koden

var showOrHide = { createLinks: function(nodeClass){ var nodes = document.getElementsByClassName(nodeClass); for (var i=0; i < nodes.length; i++) (function(i) { var target = nodes[i]; var parent = target.parentNode; var a = document.createElement('a'); a.href = '#'; a.innerHTML = 'Show more'; a.onclick = function(){ showOrHide.showHide(this, target); return false; } parent.insertBefore(a, target); })(i); }, showHide: function(trigger, target){ var status = (target.style.display == 'block') ? 'none' : 'block'; target.style.display = status; trigger.innerHTML = (status == 'block') ? 'Show less' : 'Show more'; } } window.onload = function(){ showOrHide.createLinks('show') };

Permalänk
Medlem

Stort tack för den koden, har suttit någon timme nu och försökt förstå exakt vad det är som händer, det är vissa saker jag inte är bekant med och så här långt förstår du nog att jag inte är helt hundra på detta men försöker verkligen sätta mig in i det.

Jag har gjort en massa kommentarer och lade till en del "safety" checks, ditt sätt att lägga till text på länken gillar jag skarpt istället för att göra en TextNode, sen append, sparar kod. Inte helt klar med upplägget och hur hela funktionen är i från allra början, första frågan jag tänkte var "varför börja med en variabel"? och sen lika med funktionen, "varför createLinks:, sen funktionen och inte funktionen och sen createLinks?

Likaså blir slutet också ett frågetecken då du kallar på funktionen med window.onload, det är jag med på så klart med ser inte alls ut som jag är van vid att kalla på en funktion, vilket säkert lägger sig med lite förklaringar. Du verkar vara riktigt haj på detta

Loopen är jag med på tills du sätter var target, om du nu inte sätter target därför att den irriterar igenom alla element i loopen senare som innehåller klassen 'show'. Att det är just en klass är från första raden "var nodes = document.getElementsByClassName(nodeClass);" korrekt?

Sen sätter du parent för att den senare ska bli just förälder till target. Är jag med så långt?

Att du sen lägger in parent.insertBefore är jag med på, men raden under med [i] som hör till nodes, den är jag inte riktigt med på.

Lägger in hela min kommenterade och modifierade kod här, även addLoadEvent som jag jag verkligen tycker om för flera funktioner

Kommentera gärna vad som är fel i mina kommentarer eller lägg till, stort tack igen så här långt.

/* Function created by "Simon Willson" to be able to call several functions with a single event */ //Create the function function addLoadEvent(func) { //Create a variable for window.onload event var oldonload = window.onload; //If window.onload is NOT a function, then assign 'func' to window.onload if (typeof window.onload != 'function') { window.onload = func; //If window.onload already is a function then make a new function } else { window.onload = function() { //To do what the old onload function did if (oldonload) { oldonload(); } //then do whatever the new function does func(); } } } //Add as many functions you like with addLoadEvent(functionName); //Create a function to hide the paragraphs function hideParagraph() { //Get all elements var elements = document.getElementsByTagName('*'); //Loop through all elements for(i = 0; i < elements.length; i++) { //If any element with the class 'show' if (elements[i].getAttribute('class') == 'show') { //then hide it elements[i].style.display = 'none'; } } } addLoadEvent(hideParagraph); //Not familiar with this structure of a function var showOrHide = { //A function but not used to the way it is typed, elaborate please? createLinks: function(nodeClass){ //Make safety checks to see if the browser can understand the code, otherwise do not continue if (!document.getElementsByClassName) { if (!target.parentNode) { if (!document.createElement) { return false; } } } //Get all the nodes of a class var nodes = document.getElementsByClassName(nodeClass); //Make the loop for (var i=0; i < nodes.length; i++) (function(i) { //This is what? var target = nodes[i]; //This is what? var parent = target.parentNode; //Create the link element var a = document.createElement('a'); //Prevent the page from ever refeshing on click a.href = 'javascript:void(0)'; //Set the link text a.innerHTML = 'Visa mera information'; //Set the click function for the link a.onclick = function(){ //Call the function showHide using this link and it's child target showOrHide.showHide(this, target); } //Insert the link before it's target element, which is 'show' parent.insertBefore(a, target); //This is what? })(i); }, showHide: function(trigger, target){ //Set the toggle option var status = (target.style.display == 'block') ? 'none' : 'block'; //Depending on what the status is target.style.display = status; //Change the text accordingly trigger.innerHTML = (status == 'block') ? 'Dölj information' : 'Visa mera information'; } } addLoadEvent(function() showOrHide.createLinks('show'));

Permalänk

Gör ett försök att svara på alla frågor.

Inte helt klar med upplägget och hur hela funktionen är i från allra början, första frågan jag tänkte var "varför börja med en variabel"? och sen lika med funktionen, "varför createLinks:, sen funktionen och inte funktionen och sen createLinks?

- Jag skapar en singleton. På ditt sätt så blir dina funktioner globala, vilket helst ska undvikas. Varför jag har "createLinks: function() { }" är helt enkelt för att syntaxen ser ut så. var myObject = { function myFunction() { } } fungerar inte.

Likaså blir slutet också ett frågetecken då du kallar på funktionen med window.onload, det är jag med på så klart med ser inte alls ut som jag är van vid att kalla på en funktion, vilket säkert lägger sig med lite förklaringar. Du verkar vara riktigt haj på detta

- Är inte riktigt med på vad du menar här, antar att du menar varför jag har "showOrHide." före "createLinks('show')" ?
showOrHide är ett objekt och kan liknas vid en klass. För att anropa metoder eller egenskaper på objektet så anropas de med myObject.myFunction() eller myObject.myProperty = "foo";

Loopen är jag med på tills du sätter var target, om du nu inte sätter target därför att den irriterar igenom alla element i loopen senare som innehåller klassen 'show'. Att det är just en klass är från första raden "var nodes = document.getElementsByClassName(nodeClass);" korrekt?

- Är inte riktigt med på vad du menar här heller, var target = nodes[i]; sätter jag för att jag tyckte det var lättare med target, den raden kan egentligen tas bort och så kan target bytas ut mot nodes[i].

Sen sätter du parent för att den senare ska bli just förälder till target. Är jag med så långt?

- Ja, var parent = target.parentNode; sätter parent till targets förälder, i det här fallet <div class="post">.

Att du sen lägger in parent.insertBefore är jag med på, men raden under med [i] som hör till nodes, den är jag inte riktigt med på.

- Förstår tyvärr inte vad du menar

Permalänk
Medlem

Läst på om singleton och börjar förstå hur du menar och ja du har rätt, jag har mestadels gjort alla funktioner globala. I fortsättningen ska jag försöka använda mig utav singleton om det är någonting som gör exakt lika varje gång man kallar på en instans.

Mycket bra förklaring på hur du kallade på showOrHide, det var det jag menade, förstår upplägget efter jag läst några artiklar om singleton.

De jag menade [i] i slutet var var egentligen (i) för koden som ligger under insertBefore nämligen

})(i); },

Det här var mycket intressant läsning tycker jag, roligt