Mehrere „Mehr lesen“-/„Weniger lesen“-Abschnitte funktionieren auf einer Seite nicht

Lesezeit: 8 Minuten

Mehrere „Mehr lesen „Weniger lesen Abschnitte funktionieren auf einer Seite nicht
Designer16

Ich habe mehrere „Mehr lesen“-/„Weniger lesen“-Abschnitte für eine Seite. Wenn ich einen Read More Read / Less-Abschnitt auf der Seite verwende, funktioniert das gut, wenn ich mehrere Abschnitte auf der Seite verwende, funktioniert nur ein Abschnitt, andere funktionieren nicht. Ich benötige mehrere Abschnitte, um auf derselben Seite zu arbeiten.

const content = document.querySelector(".content-inner");
const contentFull = document.querySelector(".content-full");
const more = document.querySelector(".read-more");
let open = false;

if (more) {
  more.addEventListener("click", (e) => {
    if (open) {
      content.removeAttribute("style");
      e.target.innerText = "click here";
      open = false;
    } else {
      content.style.maxHeight = `${contentFull.clientHeight}px`;
      e.target.innerText = "read less";
      open = true;
    }
  });
}
.read-more {
  display: inline-block;
  margin-top: 10px;
  font-weight: 400;
  cursor: pointer;
  font-size: 14px;
}
<div class="content">
  <div class="content-inner update-modal">
    <div class="content-full">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>
  </div>
  <span class="read-more">click here</span>
</div>

  • Sie müssen querySelectorAll für die mehreren Ergebnisse der Abfrage verwenden. Und wenden Sie dann den Ereignis-Listener auf jeden einzeln an.

    – Rajesh Paudel

    8. Dezember 2021 um 5:17 Uhr

  • Vielen Dank für Ihre Antwort und angesichts Ihrer prompten Zeit, sehr zu schätzen … Ich habe es gemäß Ihrem Vorschlag versucht, aber alle Funktionen zum Weiterlesen gestoppt

    – Designer16

    8. Dezember 2021 um 5:25 Uhr

  • Ich werde versuchen, Ihre Frage zu beantworten, um Ihnen dann eine bessere Vorstellung zu geben. Es hätte funktionieren sollen.

    – Rajesh Paudel

    8. Dezember 2021 um 5:34 Uhr

1647182531 563 Mehrere „Mehr lesen „Weniger lesen Abschnitte funktionieren auf einer Seite nicht
Teemu

Dies ist eine Aufgabe, die mit der Ereignisdelegierung zu erledigen ist. Click-Events (wie die meisten Events) sprudeln hoch document vom angeklickten Element, und Sie können Ereignisse auf ihrem Weg nach oben erkennen.

Das folgende Beispiel zeigt Ihnen, wie Sie die Ereignisdelegierung verwenden. Der Code ist wiederverwendbar, er kann auf jeder Seite mit fast jeder Elementstruktur verwendet werden, Sie können auch Ihre Klassen und das Styling der Elemente beibehalten. Dieses Snippet kann auch auf dynamischen Seiten verwendet werden, es funktioniert, ohne dass Änderungen an JS vorgenommen werden müssen, wenn Sie erweiterbare Elemente zu den Containern hinzufügen oder daraus entfernen.

function toggleContent (options) {
  const {container, expandable, triggerer, autoClose} = options,
    contents = document.querySelectorAll(container),
    buttonText = ['Read more', 'Read less'];
  let current = null; // Keeps book of the currently open expandee

  function toggle (e) {
    const button = e.target;
    if (!button.matches(triggerer)) {return;} // Quit, an irrelevant element clicked 
    const commonParent = button.closest(expandable);
    if (!commonParent) {return;} // Quit, the expandable element was not found
    if (autoClose && current && button !== current) {
      // If autoClose is on, closes the current expandee
      toggle({target: current});
    }
    const state = +commonParent.classList.toggle('expanded');
    button.textContent = buttonText[state];
    current = state ? button : null;
  }

  // Add click listeners to all elements containing expandables
  contents.forEach(cont => cont.addEventListener('click', toggle));
}

// Activate ContentToggler
toggleContent({
  container: '.expandables-container', // Selector for the elements containing expandable elements
  expandable: '.expandable',   // Selector for expandable elements
  triggerer: '.toggle-button', // Selector for the element triggering expansion
  autoClose: true              // Indicates whether the expanded element is closed when a new element is expanded (optional)
});
.expandable {
  border: 1px solid #000;
  margin-bottom: 1em;
}

/* Hides all the expandees */
.expandable .expandee {
  display: none;
}

/* Shows the expandee when .expanded is added to the parent of expandee */
.expanded .expandee {
  display: block;
}
<div class="expandables-container">
  <div class="expandable">
    <p>Always visible content.</p>
    <div class="expandee">
      <p>More content.</p>
    </div>
    <button class="toggle-button">Read more</button>
  </div>
  <div class="expandable">
    <p>Toggle button can be placed above the expandee element.</p>
    <button class="toggle-button">Read more</button>
    <div class="expandee">
      <p>More content.</p>
    </div>
  </div>

  <p>Elements can be placed between expandables.</p>

  <div class="expandable">
    <p>Always visible content.</p>
    <div class="expandee">
      <p>More content.</p>
    </div>
    <p>Elements can be placed between expandable and toggle button.</p>
    <button class="toggle-button">Read more</button>
  </div>
  <div class="expandable">
    <p>The only requirement is, that the toggle button and expandee are descendants of expandable.</p>
    <div class="expandee">
      <p>And the button must not be placed inside expandee.</p>
    </div>
    <button class="toggle-button">Read more</button>
  </div>
</div>

Die Idee ist, dass alle Expandables in einem Element verpackt sind. Der Klick-Listener wird an diesen Wrapper angehängt, und es wird nur ein einziger Klick-Listener pro Wrapper benötigt. Dies wird als Ereignisdelegierung bezeichnet und ermöglicht es Ihnen, Inhalte jederzeit frei zum Wrapper hinzuzufügen oder daraus zu entfernen, ohne das Skript überhaupt aktualisieren zu müssen.

Alles ist eingepackt toggleContent Funktion aus drei Gründen. Erstens kapselt es den Code, es müssen keine globalen Variablen eingeführt werden. Zweitens ermöglicht es, die Funktion mehrmals mit unterschiedlichen Parametern aufzurufen und verschiedene Arten von Umschaltern auf derselben Seite zu erstellen. Drittens ist es viel einfacher, ein kompaktes Codepaket auf eine andere Seite zu kopieren.

toggle Funktion erhält das angeklickte Element aus dem Ereignisobjekt (e wird automatisch aus der Ereigniswarteschlange übergeben), wenn das Element nicht mit dem übergebenen Auslöser-Selektor übereinstimmt, wird das Ereignis abgebrochen. Dann findet es den gemeinsamen Elternteil des Auslösers und das anzuzeigende Element (“expandee”) und fügt es hinzu, wenn es gefunden wird expanded Klasse an die Eltern.

CSS zeigt den Expandee mit dem Descendant-Kombinator an .expanded .expandeedas sich auf das expandee-Element bezieht, wenn ein übergeordnetes Element vorhanden ist expanded Klasse. Das aktuell geöffnete Expandee wird einfach geschlossen, indem dieselbe Funktion mit einem Dummy-Ereignisobjekt mit dem aktuellen Element als Ziel aufgerufen wird. Abschließend werden der Textwert des Triggers und das aktuell aktive Element aktualisiert.

Es ist bemerkenswert, dass das Beispiel ein sehr generischer Klassenumschalter ist, er ändert nur den Klassennamen des übergeordneten Elements des angeklickten Elements, und Sie können in den CSS-Regeln beliebige Stile festlegen, es muss nicht sein displayAuch height kann verwendet werden, oder irgendetwas.

Das „Widget“ wird durch Aufruf aktiviert toggleContent Funktion. Selektoren für die Wrapper, die erweiterbaren Elemente und die Umschaltflächen werden in einem Objekt übergeben. Der vierte Parameter steuert das automatische Schließen. Wenn Sie zu diesem Zeitpunkt nur ein einzelnes erweitertes Element sichtbar halten möchten, übergeben Sie truebeim Vorbeigehen false oder durch Weglassen der Eigenschaft funktionieren die Umschaltflächen unabhängig voneinander.

Wenn Sie mehr Kontrolle über den umschaltbaren Inhalt benötigen, würde ich einen OOP-basierten Ansatz empfehlen. Dieses OOP-Beispiel verpackt den Code im Beispiel in dieser Antwort in eine Klasse und stellt einige Anwendungsfälle bereit, die zeigen, wie der Inhalt gesteuert wird. Wenn Sie Wind davon bekommen, wie OOP funktioniert (oder Sie es bereits wissen), können Sie der Klasse ganz einfach Methoden hinzufügen, z. zum Ausblenden/Anzeigen des gesamten Inhalts usw.

Mehrere „Mehr lesen „Weniger lesen Abschnitte funktionieren auf einer Seite nicht
Rajesh Paudel

Sie müssen die relative Auswahl auswählen, um diesen Vorgang auszuführen, da sich die Klassen wiederholen. Hier die toggleReadMore-Funktion wird an jede read more-Klasse angehängt und führt die Höhenmanipulationsaktion für die innere Inhaltsklasse aus.

var prevOpened = null;
function toggleReadMore(e) {
  if(prevOpened !== null && e.target !== prevOpened){
     prevOpened.click();
  }
  // get the current section parent. This will make the selection on other class items easier. 
  var contentSection = e.target.closest('.content');
  var contentInner = contentSection.querySelector('.content-inner');

  if (e.target.textContent === "read less") {
    contentInner.removeAttribute("style");
    e.target.innerText = "click here";
    prevClicked = null;
    return;
  }
  contentInner.style.maxHeight = `${contentSection.querySelector('.content-full').clientHeight}px`;
  e.target.innerText = "read less";
  prevOpened = e.target;
}

var readMoreSections = document.querySelectorAll(".read-more");
readMoreSections.forEach(function(sections) {
  sections.addEventListener("click", toggleReadMore);
})
.read-more {
  display: inline-block;
  margin-top: 10px;
  font-weight: 400;
  cursor: pointer;
  font-size: 14px;
}

.content-inner {
  max-height: 20px;
  overflow: hidden;
}
<div class="content">
  <div class="content-inner update-modal">
    <div class="content-full">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>
  </div>
  <span class="read-more">click here</span>
</div>


<div class="content">
  <div class="content-inner update-modal">
    <div class="content-full">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>
  </div>
  <span class="read-more">click here</span>
</div>

Bearbeiten: Dies wurde aktualisiert, um nur das zuletzt angeklickte Element zu öffnen.

  • Vielen Dank für Ihre Antwort, es funktioniert für mich, sehr geschätzt! … könnten Sie das Skript so anpassen, dass ein Abschnitt geöffnet ist, nachdem Sie auf “Weiterlesen” geklickt haben, und wenn ich auf einen anderen Abschnitt klicke, “Weiterlesen”, wird der erste automatisch geschlossen

    – Designer16

    8. Dezember 2021 um 6:19 Uhr

  • @Designer16 Sie können einfach auf die zuvor angeklickten Elemente klicken.

    – Rajesh Paudel

    8. Dezember 2021 um 6:48 Uhr

  • Nochmals vielen Dank für Ihre Antwort, ich habe hier aber nicht funktioniert, könnten Sie Ihr Skript für das gleiche bearbeiten

    – Designer16

    8. Dezember 2021 um 7:08 Uhr

  • @Designer16 wurde aktualisiert, um Ihren Anforderungen gerecht zu werden

    – Rajesh Paudel

    8. Dezember 2021 um 9:13 Uhr

998110cookie-checkMehrere „Mehr lesen“-/„Weniger lesen“-Abschnitte funktionieren auf einer Seite nicht

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy