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

Gibt es einen Nachbarselektor in Javascript?

Das Ganze funktioniert nicht mit CSS, da "auto" nicht von den transitions erkannt wird.

Du kannst aber mit CSS-Transitions arbeiten, wenn du die Höhe dynamisch mit JS ausliest:
Code:
<!DOCTYPE html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Fenstertitel</title>
<style type="text/css">
.expander {
	border: 1px solid black;
}
.expander button + div {
	transition-duration: 0.5s;
	transition-property: height;
	height: 0px;
	overflow: hidden;
}
</style>
</head>
<body>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<script type="text/javascript">
Array.prototype.slice.call(document.querySelectorAll(".expander button")).forEach(function(button){
	var text = "";
	var chars = "qwertzuiopasdfghjklyxcvbnm 1234567890";
	for (var i = 1e3; i > 0; i -= 1){
		text += chars.charAt(Math.floor(Math.random() * chars.length));
	}
	var next = button.nextElementSibling;
	next.innerHTML = text;
	var transitionAim = "";
	next.addEventListener("transitionend", function(){
		next.style.height = transitionAim;
	});
	button.addEventListener("click", function(){
		if (this.innerHTML !== "collapse"){
			transitionAim = "auto";
			next.style.height = next.scrollHeight + "px";
			this.innerHTML = "collapse";
		}
		else {
			next.style.height = transitionAim = next.clientHeight + "px";
			window.setTimeout(function(){
				next.style.height = transitionAim = "";
			}, 50);
			this.innerHTML = "expand";
		}
	});
});
</script>
</body>
</html>

PS: Nur für eine Animation React einzubauen scheint mir ein wenig overkill zu sein.
 
Hallo kkapsner, ich kann dir gar nicht genug für deine Hilfe danken.

Soweit ich deinen Code verstanden habe, weist du jeder div einen String mit random Character mit einer Länge von 1000(1*10³?) zu, arbeitest aber dann später auch mit 'auto'? Inwiefern liest du das etwas dynamisch aus?

Edit: Ich denke ich habe es verstanden. Du liest die Höhe mit next.scrollHeight + "px"; aus. Wieso benutzt du einmal scrollHeight und einmal clientHeight?
Und was ich noch nicht verstehe: Du brauchst in der else Klammer eine window.setTimeout Funktion, damit sich der Inhalt "smooth" zurückzieht und nicht abrupt. Umgekehrt,wieso brauchst du diese Funktion nicht, wenn der Inhalt herausfährt?
 
Zuletzt bearbeitet:
Wieso benutzt du einmal scrollHeight und einmal clientHeight?
scrollHeight gibt mir die Höhe, die das Element gerne hätte und clientHeight die wirkliche Höhe.

Du brauchst in der else Klammer eine window.setTimeout Funktion, damit sich der Inhalt "smooth" zurückzieht und nicht abrupt. Umgekehrt,wieso brauchst du diese Funktion nicht, wenn der Inhalt herausfährt?
Es geht dabei darum, dass man für die Animation immer Zahlenangaben für die Höhe braucht. Um von "auto" wieder zu "0px" zu fahren setze ich also die Höhe erst so hoch, wie es auch wirklich ist (clientHeight eben). Damit aber dann die zweite Angabe (das "" entspricht dann dem "0px" aus dem <style>) greift muss anscheinend die CSS Engine mal durchgelaufen sein - und mit 50ms ist es recht wahrscheinlich, dass das passiert ist.
Ist jetzt aber nicht 100%ig ausgetestet und ev. gibt es dafür auch noch eine bessere Lösung.
 
Verstanden. Kannst du mir nochmal näher erklären wieso du am Anfang : Array.prototype.slice.call(document.querySelectorAll('.expander div')).forEach(function sectionShowHide(div));

Aufrufst? Ginge auch stattdessen:
HTML:
Var list=document.getElementsByClassName('expander');
For(var i=0;i<list.length;i++){
  List[i].sectionShowHide();
}
(so ungefähr)
Noch eine Frage:
Was ist besser next.addEventListener('click', function…) oder next.onclick=function..;
Oder ist das nur Formsache?

Gruß Baumjohann
 
Zuletzt bearbeitet von einem Moderator:
Ginge auch stattdessen:
Jein. Du kannst natürlich auch mit einer for-Schleife iterieren, aber in meinem Code würde dann der Scope für die lokale Variablen next und transitionAim falsch sein.

(Außerdem hast du bei deinem Code Syntax- und Referenzfehler drin - du solltest in deinem Browser die Autokorrektur ausschalten, wenn du Code schreibst... Var, For und deine Variable List schreibt man alle klein ;))

Was ist besser next.addEventListener('click', function…) oder next.onclick=function..;
Definitiv Ersteres, denn damit kann man eleganter und einfacher mehrere Funktionen bei dem Event registrieren. Und man überschreibt nicht mal aus Versehen den Eventhandler von einem anderen Skript.
 
Super, alles funktioniert. Ich möchte noch das 'hovern' vom CSS ins JavaScript umsetzten.
Hier mein Code:
Code:
var sectionBar=document.getElementsByClassName('expander');
    for(var i=0;i<sectionBar.length;i++){
    sectionBar[i].addEventListener('mouseover',function(){hover(true)});
    sectionBar[i].addEventListener('mouseout',function(){hover('')});
    
var cursorTemp;
var backgroundColorTemp;

function hover(boolean){
    
    cursorTemp= this.style.cursor;
    backgroundColorTemp= this.style.backgroundColor;
    if(!boolean){
    this.style.cursor=cursorTemp;
    this.style.backgroundColor=backgroundColorTemp;
    }else{
    this.style.cursor='pointer';
    this.style.backgroundColor='#33A1C9';
    }
    }
Anscheinend stimmen die Abfragen, die dann in den globalen Variablen gespeichert werden, nicht. Ansonsten kommt es zu einer Veränderung bei mouseover. Mouseout funktioniert natürlich nicht.


Gruß Baumjohann
 
Zuletzt bearbeitet von einem Moderator:
Ich möchte noch das 'hovern' vom CSS ins JavaScript umsetzten.
Warum? Im CSS ist es besser aufgehoben.

globalen Variablen
Das ist schon mal eines der grundlegenden Problem, warum dein Code nicht funktioniert. Da du verschiedene Elemente verarbeiten willst, wird das nie mit globalen Variablen funktionieren. Außerdem sind globale Variablen immer zu vermeiden.

Außerdem ist die Logik in deiner hover-Funktion falsch. Das setzen der temp-Variablen darf nur in dem else-Zweig stattfinden... eigentlich sollte es komplett nur einmal stattfinden.

PS: mouseover und mouseout sind die falschen Events für hovern. Dafür musst du mouseenter und mouseleave verwenden.
 
Achso ich dachte das geht ganz schnell mit JavaScript. Das Problem mit dem hover beim CSS war, dass ich nicht den ausgewählten Button ansprechen kann: Die Buttons sind im HTML in der Klasse .expander zusammengefasst, sodass beim hovern über einem Button, direkt alle Button angesprochen werden, anstatt wie gewünscht nur der jeweilige Button. Ich dachte mir jedem Button extra eine id zu geben sei unelegant und eher hardgecoded.
 
Achso ich dachte das geht ganz schnell mit JavaScript.
Naja - mit CSS geht das meist schneller.

sodass beim hovern über einem Button, direkt alle Button angesprochen werden
Dann hast du deinen :hover-Pseudoselektor falsch gesetzt. In meinem Codebeispiel oben würde das so aussehen:
Code:
<!DOCTYPE html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Fenstertitel</title>
<style type="text/css">
.expander {
	border: 1px solid black;
}
.expander button + div {
	transition-duration: 0.5s;
	transition-property: height;
	height: 0px;
	overflow: hidden;
}
.expander:hover {
	background-color: red;
}
</style>
</head>
<body>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<div class="expander"><button>expand</button><div></div></div>
<script type="text/javascript">
Array.prototype.slice.call(document.querySelectorAll(".expander button")).forEach(function(button){
	var text = "";
	var chars = "qwertzuiopasdfghjklyxcvbnm 1234567890";
	for (var i = 1e3; i > 0; i -= 1){
		text += chars.charAt(Math.floor(Math.random() * chars.length));
	}
	var next = button.nextElementSibling;
	next.innerHTML = text;
	var transitionAim = "";
	next.addEventListener("transitionend", function(){
		next.style.height = transitionAim;
	});
	button.addEventListener("click", function(){
		if (this.innerHTML !== "collapse"){
			transitionAim = "auto";
			next.style.height = next.scrollHeight + "px";
			this.innerHTML = "collapse";
		}
		else {
			next.style.height = transitionAim = next.clientHeight + "px";
			window.setTimeout(function(){
				next.style.height = transitionAim = "";
			}, 50);
			this.innerHTML = "expand";
		}
	});
});
</script>
</body>
</html>
- es wird immer nur das Element rot, das auch wirklich unter der Maus ist.

Ich dachte mir jedem Button extra eine id zu geben sei unelegant und eher hardgecoded.
Ja, das ist unelegant und auch extrem schlecht zu warten.

PS: die cursor-Eigenschaft nur im hover zu setzen ist unsinnig, da sich diese Eigenschaft ja sowieso nur dann auf den Mauszeiger auswirkt, wenn sich dieser über dem Element befindet.
 
Sehr nice, klappt alles danke dir :). Nun ist meine Webseite fast fertig, ich würde aber gerne noch eine PDF Datei einbauen quasi mit einem PDF Viewer, sodass man die PDF Datei direkt auf der Seite sieht, aber auch downloaden kann.
In einem anderen Forum bin ich fündig geworden:
PDF.js
Usage

Include the javascript libraries in the HTML file and add an -element ( is HTML5 element, so it will work only in HTML5 browsers):

HTML:
<body>
  <canvas id="the-canvas" style="border:1px solid black;"/>
</body>
Use a javascript call similar to this to render the PDF inside this canvas:

PDFJS.getDocument('your-file-goes-here.pdf').then(function(pdf) {
  pdf.getPage(1).then(function(page) {
    var scale = 1.5;
    var viewport = page.getViewport(scale);

    var canvas = document.getElementById('the-canvas');
    var context = canvas.getContext('2d');
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    var renderContext = {
      canvasContext: context,
      viewport: viewport
    };
    page.render(renderContext);
  });
});

"Include the javascript libraries in the HTML file" -> Wie mache ich das? Ich habe bisher den Code kopiert, aber es zeigt sich nur ein leeres Canvas, wahrscheinlich weil ich noch keine js libraries in die HTML Datei importiert habe.
 
Zuletzt bearbeitet von einem Moderator:
Das ist mir schon klar nur weiß ich nicht die Details.
Ich hab mir jetzt mal nach Anleitung von Mozilla die Datei gedownloadet und Node.js installiert. Nun kann ich im Git Bash mit dem Kommando: $ node make server einen lokalen Webserver starten und folgende Links aufrufen:
http://localhost:8888/web/viewer.html
http://localhost:8888/test/pdfs/?frame
Nun komm ich nicht weiter. Nachdem ich das Kommando ausführe, nimmt die Konsole keine Kommandos mehr auf und ich muss die Anwendung neustarten und mich wieder ins richtige Verzeichnis navigieren (wie löse ich dieses Problem?).
Nächster Schritt nach Anleitung:
Building PDF.js

In order to bundle all src/ files into two productions scripts and build the generic viewer, issue:

$ node make generic

This will generate pdf.js and pdf.worker.js in the build/generic/build/ directory. Both scripts are needed but only pdf.js needs to be included since pdf.worker.js will be loaded by pdf.js. If you want to support more browsers than Firefox you'll also need to include compatibility.js from build/generic/web/. The PDF.js files are large and should be minified for production.

Hab ich umgesetzt nur kommt bei mir folgende Fehlermeldung:
Code:
C:\Users\Duc Anh\Documents\GitHub> cd pdf.js
C:\Users\Duc Anh\Documents\GitHub\pdf.js [master]> node make generic

### Getting extension build number
shell.js: internal error
Error: Command failed: "E:\nodejs\node.exe" C:\Users\Duc Anh\AppData\Local\Temp\shelljs_b27122516dbade730b0b
    at checkExecSyncError (child_process.js:441:13)
    at Object.execSync (child_process.js:481:13)
    at execSync (C:\Users\Duc Anh\Documents\GitHub\pdf.js\node_modules\shelljs\src\exec.js:77:11)
    at _exec (C:\Users\Duc Anh\Documents\GitHub\pdf.js\node_modules\shelljs\src\exec.js:210:12)
    at C:\Users\Duc Anh\Documents\GitHub\pdf.js\node_modules\shelljs\src\common.js:182:23
    at Function.target.buildnumber (C:\Users\Duc Anh\Documents\GitHub\pdf.js\make.js:739:15)
    at Object.global.target.(anonymous function) [as buildnumber] (C:\Users\Duc Anh\Documents\GitHub\pdf.js\node_modules\shelljs\make.js:28:26)
    at Function.target.bundle (C:\Users\Duc Anh\Documents\GitHub\pdf.js\make.js:479:10)
    at Object.global.target.(anonymous function) [as bundle] (C:\Users\Duc Anh\Documents\GitHub\pdf.js\node_modules\shelljs\make.js:28:26)
    at Function.target.generic (C:\Users\Duc Anh\Documents\GitHub\pdf.js\make.js:117:10)
C:\Users\Duc Anh\Documents\GitHub\pdf.js [master]>

Sorry für den langen Post, aber hast du eine Ahnung wie ich das Ding zum Laufen bekomme ? ;)
 
Zuletzt bearbeitet von einem Moderator:
Sorry für den langen Post, aber hast du eine Ahnung wie ich das Ding zum Laufen bekomme ? ;)
Die Länge ist kein Problem. Bitte verwende aber zukünftig Markierungs-Tags wie ich es jetzt gemacht habe. Dann kann man das schon gleich viel besser lesen und die Suchmaschinen indexieren es auch richtig.

Gehört das hier eigentlich alles noch zur Ursprungsfrage?
 
Zurück
Oben