• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Frage JS zusammenfassen

Dven

Neues Mitglied
Guten Tag allerseits,

ich habe ein Konstrukt aus Boxen, nun habe ich dazu ein JS, welches mir on click die jeweilige Box mit dem passenden Inhalt befüllt. Das funktioniert soweit auch prima, aber es sieht von der Syntax total falsch aus, da meine JS Kenntnisse nicht die besten sind, wollte ich bei euch fragen, ob man das alles irgendwie "zusammenfassen" kann. Sprich nicht für jede einzelne Box eine neue function.

Der Part sieht wie folgt aus:

Code:
    $("#box-1").click(function () {
        $('.box-content').addClass('show');
        $('.box-content').children('p').empty().append('<span class="box-content head">1</span><br>Box 1 Inhalt');
    });

    $("#box-2").click(function () {
        $('.box-content').addClass('show');
        $('.box-content').children('p').empty().append('<span class="box-content head">2</span><br>Box 2 Inhalt');
    });

    $("#box-3").click(function () {
        $('.box-content').addClass('show');
        $('.box-content').children('p').empty().append('<span class="box-content head">3</span><br>Box 3 Inhalt');
    });

    $("#box-4").click(function () {
        $('.box-content').addClass('show');
         $('.box-content').children('p').empty().append('<span class="box-content-head">4</span><br>Box 4 Inhalt');
    });

    $("#box-5").click(function () {
        $('.box-content').addClass('show');
        $('.box-content').children('p').empty().append('<span class="box-content-head">5</span><br>Box 5 Inhalt');
    });
 
Bei JQuery sollte das so gehen Ungetestet
Javascript:
    $("#box-1,#box-2,#box-3,#box-4,#box-5").click(function () {
        $('.box-content').addClass('show');
        $('.box-content').children('p').empty().append('<span class="box-content-head">5</span><br>Box 5 Inhalt');
    });

Sowas kann man auch ohne jQuery machen und nur mit normalen Vanilla Javascript.
Dafür gibt es querySelectorAll
 
Kannst du mal das HTML dazu zeigen?
Das sieht ja so aus, sobald du einer der Box 1-5 klickst, alle das Gleiche machen, und zwar den div class="box-content"> ansprechen?

Der Code zeigt mir das die klick Boxen nicht mit den content Boxen verschachtelt sind.
Ein this wird auch nicht benutzt.

Wäre mal gut das HTML zu sehen
 
Kannst du mal das HTML dazu zeigen?
Das sieht ja so aus, sobald du einer der Box 1-5 klickst, alle das Gleiche machen, und zwar den div class="box-content"> ansprechen?

Der Code zeigt mir das die klick Boxen nicht mit den content Boxen verschachtelt sind.
Ein this wird auch nicht benutzt.

Wäre mal gut das HTML zu sehen

Hey, danke für deine Antwort.

Ich hab mal via JSFiddle schnell das Case erstellt:

also wie du siehst, habe ich oben einen Container mit dem Inhalt und sobald man auf eins der Boxen klickt, wird der jeweilige Content für die Box oben angezeigt. Deshalb auch fünf unterschiedliche Parts, weil ich den Text immer direkt über das Script einbinde. Es ist etwas umständlich, weil ich in der richtigen Anwendung ein SVG habe indem ich die Inhalte schreiben muss, weshalb ich z.B. nicht einfach die passenden Inhalte direkt in eine Box legen kann (z.B. als Div oder span). Es ist auch nicht immer derselbe Text, es soll immer ein anderer Inhalt dargestellt werden.

Und wie erwähnt, das funktioniert soweit gut, nur sieht das JS total mies aus. Ich wiederhole jedes Mal die function, obwohl die Vorgehensweise dieselbe ist, sich lediglich eben der Text ändert. Daher die Frage, ob man das JS da irgendwie schöner zusammenfassen kann.
 
Zuletzt bearbeitet:
Daher di Frage, ob man das JS da irgendwie schöner zusammenfassen kann.
Man kann (ohne das überflüssige jQuery):
Javascript:
const target = document.querySelector('.box-content p span');
const source = document.querySelector('.boxes');
source.addEventListener('click',function (event) {
  let nr = event.target.id.substring(4);
  target.textContent = 'Box ' + nr + ' Inhalt';
});
Es erhebt sich aber natürlich die Frage wo der zu setzende Inhalt herkommen soll (ich habe jetzt einfach mal aus der ID die Nummer extrahiert) - hier würden sich evtl. data-*-Attribute anbieten, für den Zugriff darauf gibt es die dataset-Eigenschaft.
 
Man kann (ohne das überflüssige jQuery):
Javascript:
const target = document.querySelector('.box-content p span');
const source = document.querySelector('.boxes');
source.addEventListener('click',function (event) {
  let nr = event.target.id.substring(4);
  target.textContent = 'Box ' + nr + ' Inhalt';
});
Es erhebt sich aber natürlich die Frage wo der zu setzende Inhalt herkommen soll (ich habe jetzt einfach mal aus der ID die Nummer extrahiert) - hier würden sich evtl. data-*-Attribute anbieten, für den Zugriff darauf gibt es die dataset-Eigenschaft.

Hey, auch an dich danke für die rasche Antwort. Das klappt super, aber es trifft nicht ganz meinen Anwendungsfall. Ich habe in allen Boxen unterschiedliche Texte und möchte diese, je nachdem welche Box angeklickt ist, anzeigen. Deshalb auch oben im jsfiddle mein Beispiel mit eben jeder einzelnen Box. jQuery btw ist kein Problem, da dies bei mir eh eingebunden ist.

Das mit dem data-attribute ist eine gute Idee, die Frage ist ob ich dies in ein SVG reinschreiben kann (also in den <path direkt). Müsste ich ausprobieren, wie würde denn der JS Part aussehen wenn man sich den Inhalt aus einem data-attribute holt?
 
Oder Inhalte in ein Array packen

Javascript:
  const inhalt=['Inhalt box 1','Inhalt box 2','Inhalt box 3','Inhalt box 4','Inhalt box 5'];

  target.textContent = 'Box ' + inhalt[nr-1] + ' Inhalt';
 
Immer diese jQuery-Muffel hier :)
Javascript:
const content = ["content 1","content 2","content 3","content 4","content 5"]
$("#box-1,#box-2,#box-3,#box-4,#box-5").click(function () {
        $('.box-content').addClass('show');
         let index = $(this).index();
        $('.box-content').children('p').empty().append('<span>'+content[index]+ '</span>');
    });
Auch ungetestet aber mit .Index() kriegst du den Index für deinen Array mit dem Content.
 
Immer diese jQuery-Muffel hier :)
Javascript:
const content = ["content 1","content 2","content 3","content 4","content 5"]
$("#box-1,#box-2,#box-3,#box-4,#box-5").click(function () {
        $('.box-content').addClass('show');
         let index = $(this).index();
        $('.box-content').children('p').empty().append('<span>'+content[index]+ '</span>');
    });
Auch ungetestet aber mit .Index() kriegst du den Index für deinen Array mit dem Content.

Super danke, genau das, was ich benötigt hab! :)
 
Jquery brauch doch keiner mehr.
Aber wenn schon dann kürzer bitte
Wir können ja auch noch Golfen
Javascript:
const content = ["content 1", "content 2", "content 3", "content 4", "content 5"]
$(".boxes > div").click(function() {
  $('.box-content').addClass('show').children('p').html('<span>' + content[$(this).index()] + '</span>');
});
 
Das mit dem data-attribute ist eine gute Idee, die Frage ist ob ich dies in ein SVG reinschreiben kann (also in den <path direkt). Müsste ich ausprobieren, wie würde denn der JS Part aussehen wenn man sich den Inhalt aus einem data-attribute holt?
Keine Ahnung ob data-Attribute jetzt auch in svg direkt stehen dürfen, in HTML geht es aber auf jeden Fall - wie man darauf zugreift steht auf der von mir verlinkten Seite. Mir ist allerdings nicht so ganz klar was jetzt eigentlich dein Anwendungsfall ist (also was angeklickt werden soll und von wo nach wo die Texte müssen) - auf jeden Fall sind div-Elemente als Klickbare Elemente aber falsch: das sind keine aktiven Elemente und damit per Tastaturbedienung nicht erreichbar.

Immer diese jQuery-Muffel hier :)
ich habe jQuery durchaus früher auch verwendet, heutzutage ist es aber überflüssig geworden und es ist sinnlos es einzubinden wenn es mit Vanilla-JS auch mit viel weniger Code geht (man muss schon den jQuery-Code mitrechnen!).

Wobei ich noch das hinzufügen der Klasse add vergessen habe - dafür gibt es classList.add().

Du kannst auf die ID's auch verzichten mit
Javascript:
  $(".boxes div").click(function () { });
als Selector reicht .boxes oder kann jQuery kein Event bubbling? Ich habe in #5 den EventHandler auch für .boxes registriert, die ID habe ich nur für die Nummer verwendet.
 
Jquery brauch doch keiner mehr.
Aber wenn schon dann kürzer bitte
Wir können ja auch noch Golfen
Javascript:
const content = ["content 1", "content 2", "content 3", "content 4", "content 5"]
$(".boxes > div").click(function() {
  $('.box-content').addClass('show').children('p').html('<span>' + content[$(this).index()] + '</span>');
});
.html() macht mehr Sinn ja! Und als direkter Erbe $(".boxes > div") auch.
 
Bei JQuery sollte das so gehen Ungetestet
Javascript:
    $("#box-1,#box-2,#box-3,#box-4,#box-5").click(function () {
        $('.box-content').addClass('show');
        $('.box-content').children('p').empty().append('<span class="box-content-head">5</span><br>Box 5 Inhalt');
    });

Sowas kann man auch ohne jQuery machen und nur mit normalen Vanilla Javascript.
Dafür gibt es querySelectorAll
eigentlich ja sollte so gehen.
 
Immer diese jQuery-Muffel hier :)
Javascript:
const content = ["content 1","content 2","content 3","content 4","content 5"]
$("#box-1,#box-2,#box-3,#box-4,#box-5").click(function () {
        $('.box-content').addClass('show');
         let index = $(this).index();
        $('.box-content').children('p').empty().append('<span>'+content[index]+ '</span>');
    });
Auch ungetestet aber mit .Index() kriegst du den Index für deinen Array mit dem Content.
Ja finde ich auch, guter Ausdruck: Muffel;-)
 
Mit purem Javascript schaut's so aus:
Javascript:
const content = ["content 1","content 2","content 3","content 4","content 5"];
const buttons = document.querySelectorAll(".boxes > div");
const boxContent = document.querySelector(".box-content");
var index;
    for(i=0;i<buttons.length;i++) {
        buttons[i].addEventListener('click', clickThis, false);
    }
function clickThis() {
 for(i=0;i<buttons.length;i++) {
    if(this  == buttons[i]) {
        index = i;
    }
}
boxContent.querySelector("p span").innerHTML = content[index];
}
Jetzt auch nicht die Welt...
 
Zuletzt bearbeitet:
Mit purem Javascript schaut's so aus:
Javascript:
const content = ["content 1","content 2","content 3","content 4","content 5"];
const buttons = document.querySelectorAll(".boxes > div");
const boxContent = document.querySelector(".box-content");
var index;
    for(i=0;i<buttons.length;i++) {
        buttons[i].addEventListener('click', clickThis, false);
    }
function clickThis() {
 for(i=0;i<buttons.length;i++) {
    if(this  == buttons[i]) {
        index = i;
    }
}
boxContent.querySelector("p span").innerHTML = content[index];
}
Jetzt auch nicht die Welt...

Das wird wohl so klappen ´wie du es machst doch eine vanilla JS Lösung gab es schon in 5#.
Deinen Code kann man aber auch noch kürzen bzw etwas übersichtlicher halten.

Mit Array dann so
Javascript:
const inhalt=['Inhalt box 1','Inhalt box 2','Inhalt box 3','Inhalt box 4','Inhalt box 5'];
const target = document.querySelector('.box-content p span');
const source = document.querySelector('.boxes');
source.addEventListener('click',function (event) {
    let nr = event.target.id.substring(4);
    target.textContent = 'Box ' + inhalt[nr-1] + ' Inhalt';
});
 
Deinen Code kann man aber auch noch kürzen bzw etwas übersichtlicher halten.
Ohne die IDs geht es auch:
Javascript:
const inhalt = ['Inhalt box 1', 'Inhalt box 2', 'Inhalt box 3', 'Inhalt box 4', 'Inhalt box 5'];
const target = document.querySelector('.box-content p span');
const source = document.querySelector('.boxes');
const index = selectedBox => [...source.children].findIndex(child => selectedBox == child);
source.addEventListener('click', function(event) {
  target.textContent = inhalt[index(event.target)] ?? 'foo';
});
Die Funktion index() sucht dabei die Nummer der ausgewählten Box und verwendet diese als Index um den entsprechenden Inhalt aus inhalt zu holen. Das »foo« ist der Inhalt wenn innerhalb von .boxes geklickt wird, dabei aber keine der Boxen angeklickt wurde (kann natürlich auch ein Leerstring sein). Wenn für jede Box ein eigener EventListener registriert werden soll geht das natürlich auch, die beiden for-Schleifen sind dann unnötig, forEach existiert und hat einen zweiten Parameter (index).
 
Zurück
Oben