1

I have four div id elements (and I cannot switch id for class) and I need the same javascript function to work for all of them, not just the first one. The function shuffles the verses of the poem everytime the page is refreshed, and it only works for the first div so far, I don't know how to repeat it for the others. I already tried copy pasting it four times and changing the variable names and I also tried "document.getElementById('text1,text2,etc..')" both methods made the code stop working completely. Any suggestions? Thanks!

const text = document.getElementById('text1');

function rndPoem() {

  const lines = text
  .innerHTML.split(/<br>/)
  .map(line => line.trim());

  for (let i = lines.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [lines[i], lines[j]] = [lines[j], lines[i]];
  }

  return lines.join('<br>');

}
text.innerHTML = rndPoem();
    html {
     
    }
    body {
          font-family: 'Arial';
         font-size: 10px;
      font-family: 'Arial';
      display: flex;
      font-size: 1vw;
      text-transform: uppercase;
      line-height: 1;
      overflow: hidden;
      margin-left: 5%;
        margin-right: 10%;
    }

.text {
    padding: 2%;
    width: 25%;
}
<div id="text1">

  Quand le ciel bas et lourd pèse comme un couvercle<br> Sur l'esprit gémissant en proie aux longs ennuis,<br> Et que de l'horizon embrassant tout le cercle<br> Il nous verse un jour noir plus triste que les nuits ;<br> Quand la terre est changée en un
  cachot humide,<br> Où l'Espérance, comme une chauve-souris,<br> S'en va battant les murs de son aile timide<br> Et se cognant la tête à des plafonds pourris ;<br> Quand la pluie étalant ses immenses traînées<br> D'une vaste prison imite les barreaux,<br>  Et qu'un peuple muet d'infâmes araignées<br> Vient tendre ses filets au fond de nos cerveaux,<br> Des cloches tout à coup sautent avec furie<br> Et lancent vers le ciel un affreux hurlement,<br> Ainsi que des esprits errants et sans patrie<br> Qui se
  mettent à geindre opiniâtrement.<br> - Et de longs corbillards, sans tambours ni musique,<br> Défilent lentement dans mon âme ; l'Espoir,<br> Vaincu, pleure, et l'Angoisse atroce, despotique,<br> Sur mon crâne incliné plante son drapeau noir.<br>
</div>
<div id="text2">

  Quand le ciel bas et lourd pèse comme un couvercle<br> Sur l'esprit gémissant en proie aux longs ennuis,<br> Et que de l'horizon embrassant tout le cercle<br> Il nous verse un jour noir plus triste que les nuits ;<br> Quand la terre est changée en un
  cachot humide,<br> Où l'Espérance, comme une chauve-souris,<br> S'en va battant les murs de son aile timide<br> Et se cognant la tête à des plafonds pourris ;<br> Quand la pluie étalant ses immenses traînées<br> D'une vaste prison imite les barreaux,<br>  Et qu'un peuple muet d'infâmes araignées<br> Vient tendre ses filets au fond de nos cerveaux,<br> Des cloches tout à coup sautent avec furie<br> Et lancent vers le ciel un affreux hurlement,<br> Ainsi que des esprits errants et sans patrie<br> Qui se
  mettent à geindre opiniâtrement.<br> - Et de longs corbillards, sans tambours ni musique,<br> Défilent lentement dans mon âme ; l'Espoir,<br> Vaincu, pleure, et l'Angoisse atroce, despotique,<br> Sur mon crâne incliné plante son drapeau noir.<br>
</div>
<div id="text3">

  Quand le ciel bas et lourd pèse comme un couvercle<br> Sur l'esprit gémissant en proie aux longs ennuis,<br> Et que de l'horizon embrassant tout le cercle<br> Il nous verse un jour noir plus triste que les nuits ;<br> Quand la terre est changée en un
  cachot humide,<br> Où l'Espérance, comme une chauve-souris,<br> S'en va battant les murs de son aile timide<br> Et se cognant la tête à des plafonds pourris ;<br> Quand la pluie étalant ses immenses traînées<br> D'une vaste prison imite les barreaux,<br>  Et qu'un peuple muet d'infâmes araignées<br> Vient tendre ses filets au fond de nos cerveaux,<br> Des cloches tout à coup sautent avec furie<br> Et lancent vers le ciel un affreux hurlement,<br> Ainsi que des esprits errants et sans patrie<br> Qui se
  mettent à geindre opiniâtrement.<br> - Et de longs corbillards, sans tambours ni musique,<br> Défilent lentement dans mon âme ; l'Espoir,<br> Vaincu, pleure, et l'Angoisse atroce, despotique,<br> Sur mon crâne incliné plante son drapeau noir.<br>
</div>
<div id="text4">

  Quand le ciel bas et lourd pèse comme un couvercle<br> Sur l'esprit gémissant en proie aux longs ennuis,<br> Et que de l'horizon embrassant tout le cercle<br> Il nous verse un jour noir plus triste que les nuits ;<br> Quand la terre est changée en un
  cachot humide,<br> Où l'Espérance, comme une chauve-souris,<br> S'en va battant les murs de son aile timide<br> Et se cognant la tête à des plafonds pourris ;<br> Quand la pluie étalant ses immenses traînées<br> D'une vaste prison imite les barreaux,<br>  Et qu'un peuple muet d'infâmes araignées<br> Vient tendre ses filets au fond de nos cerveaux,<br> Des cloches tout à coup sautent avec furie<br> Et lancent vers le ciel un affreux hurlement,<br> Ainsi que des esprits errants et sans patrie<br> Qui se
  mettent à geindre opiniâtrement.<br> - Et de longs corbillards, sans tambours ni musique,<br> Défilent lentement dans mon âme ; l'Espoir,<br> Vaincu, pleure, et l'Angoisse atroce, despotique,<br> Sur mon crâne incliné plante son drapeau noir.<br>
</div>
zell wd
  • 49
  • 6

4 Answers4

2

You can use "event delegation" and set up a single event handler on a common ancestor of all of the div elements and handle the event at that ancestor when the event "bubbles" up to it:

// Set up an event handler at a common ancestor
document.addEventListener("mousewheel", function(event){
  // Check to see if the element that the event originated at 
  // (event.target) is one that we want to handle here:
  if(event.target.id.startsWith("text")){
    rndPoem(event.target); // Call the desired function
  }
});

function rndPoem(element) {
  const lines = element
  .innerHTML.split(/<br>/)
  .map(line => line.trim());

  for (let i = lines.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [lines[i], lines[j]] = [lines[j], lines[i]];
  }
  element.innerHTML = lines.join('<br>');
}
body {
      font-family: 'Arial';
      font-size: 10px;
      font-family: 'Arial';
      display: flex;
      font-size: 1vw;
      text-transform: uppercase;
      line-height: 1;
      overflow: hidden;
      margin-left: 5%;
      margin-right: 10%;
}

.text {
    padding: 2%;
    width: 25%;
}
<div id="text1">
  Quand le ciel bas et lourd pèse comme un couvercle<br> Sur l'esprit gémissant en proie aux longs ennuis,<br> Et que de l'horizon embrassant tout le cercle<br> Il nous verse un jour noir plus triste que les nuits ;<br> Quand la terre est changée en un
  cachot humide,<br> Où l'Espérance, comme une chauve-souris,<br> S'en va battant les murs de son aile timide<br> Et se cognant la tête à des plafonds pourris ;<br> Quand la pluie étalant ses immenses traînées<br> D'une vaste prison imite les barreaux,<br>  Et qu'un peuple muet d'infâmes araignées<br> Vient tendre ses filets au fond de nos cerveaux,<br> Des cloches tout à coup sautent avec furie<br> Et lancent vers le ciel un affreux hurlement,<br> Ainsi que des esprits errants et sans patrie<br> Qui se
  mettent à geindre opiniâtrement.<br> - Et de longs corbillards, sans tambours ni musique,<br> Défilent lentement dans mon âme ; l'Espoir,<br> Vaincu, pleure, et l'Angoisse atroce, despotique,<br> Sur mon crâne incliné plante son drapeau noir.<br>
</div>
<div id="text2">
  Quand le ciel bas et lourd pèse comme un couvercle<br> Sur l'esprit gémissant en proie aux longs ennuis,<br> Et que de l'horizon embrassant tout le cercle<br> Il nous verse un jour noir plus triste que les nuits ;<br> Quand la terre est changée en un
  cachot humide,<br> Où l'Espérance, comme une chauve-souris,<br> S'en va battant les murs de son aile timide<br> Et se cognant la tête à des plafonds pourris ;<br> Quand la pluie étalant ses immenses traînées<br> D'une vaste prison imite les barreaux,<br>  Et qu'un peuple muet d'infâmes araignées<br> Vient tendre ses filets au fond de nos cerveaux,<br> Des cloches tout à coup sautent avec furie<br> Et lancent vers le ciel un affreux hurlement,<br> Ainsi que des esprits errants et sans patrie<br> Qui se
  mettent à geindre opiniâtrement.<br> - Et de longs corbillards, sans tambours ni musique,<br> Défilent lentement dans mon âme ; l'Espoir,<br> Vaincu, pleure, et l'Angoisse atroce, despotique,<br> Sur mon crâne incliné plante son drapeau noir.<br>
</div>
<div id="text3">
  Quand le ciel bas et lourd pèse comme un couvercle<br> Sur l'esprit gémissant en proie aux longs ennuis,<br> Et que de l'horizon embrassant tout le cercle<br> Il nous verse un jour noir plus triste que les nuits ;<br> Quand la terre est changée en un
  cachot humide,<br> Où l'Espérance, comme une chauve-souris,<br> S'en va battant les murs de son aile timide<br> Et se cognant la tête à des plafonds pourris ;<br> Quand la pluie étalant ses immenses traînées<br> D'une vaste prison imite les barreaux,<br>  Et qu'un peuple muet d'infâmes araignées<br> Vient tendre ses filets au fond de nos cerveaux,<br> Des cloches tout à coup sautent avec furie<br> Et lancent vers le ciel un affreux hurlement,<br> Ainsi que des esprits errants et sans patrie<br> Qui se
  mettent à geindre opiniâtrement.<br> - Et de longs corbillards, sans tambours ni musique,<br> Défilent lentement dans mon âme ; l'Espoir,<br> Vaincu, pleure, et l'Angoisse atroce, despotique,<br> Sur mon crâne incliné plante son drapeau noir.<br>
</div>
<div id="text4">
  Quand le ciel bas et lourd pèse comme un couvercle<br> Sur l'esprit gémissant en proie aux longs ennuis,<br> Et que de l'horizon embrassant tout le cercle<br> Il nous verse un jour noir plus triste que les nuits ;<br> Quand la terre est changée en un
  cachot humide,<br> Où l'Espérance, comme une chauve-souris,<br> S'en va battant les murs de son aile timide<br> Et se cognant la tête à des plafonds pourris ;<br> Quand la pluie étalant ses immenses traînées<br> D'une vaste prison imite les barreaux,<br>  Et qu'un peuple muet d'infâmes araignées<br> Vient tendre ses filets au fond de nos cerveaux,<br> Des cloches tout à coup sautent avec furie<br> Et lancent vers le ciel un affreux hurlement,<br> Ainsi que des esprits errants et sans patrie<br> Qui se
  mettent à geindre opiniâtrement.<br> - Et de longs corbillards, sans tambours ni musique,<br> Défilent lentement dans mon âme ; l'Espoir,<br> Vaincu, pleure, et l'Angoisse atroce, despotique,<br> Sur mon crâne incliné plante son drapeau noir.<br>
</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
1

You can use document.querySelectorAll() to target multiple ids simultaneously.

Array.from(document.querySelectorAll("#id1,#id2,#id3,#id4")).forEach(
  function(div) {
    div.innerHTML = rndPoem(div);  
  }
);
function rndPoem(div) {

  const lines = div.innerHTML.split(/<br>/).map(line => line.trim());

  for (let i = lines.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [lines[i], lines[j]] = [lines[j], lines[i]];
  }

  return lines.join('<br>');

}
<div id="id1"></div>
<div id="id2"></div>
<div id="id3"></div>
<div id="id4"></div>
mykaf
  • 1,034
  • 1
  • 9
  • 12
  • @zellwd Please take a look at my answer which is more performant (no loop and only one event handler) and easier to maintain as it will work for any element that has an `id` that starts with `text`, so you can add/remove `div` elements without changing the JavaScript. – Scott Marcus Jun 07 '22 at 21:05
  • 1
    There is no need for `Array.from()` here as `.forEach()` natively works with the node list returned from `querySelectorAll()`. – Scott Marcus Jun 07 '22 at 21:07
  • @Scott Marcus, I've been working in a system that requires IE compatibility for too long. But then again, I think IE doesn't allow Array.from() either. – mykaf Jun 07 '22 at 21:09
  • Correct, so you'd need to resort to a more traditional `for` loop for IE. – Scott Marcus Jun 07 '22 at 21:11
  • Also, you shouldn't modify the DOM from within a loop as this is a big "no no" as far as performance goes (the HTML parser has to kick in repeatedly and rebuild the DOM over and over and this will cause CSS reflows and CSS repaints). Instead, build up a string from your loop and after the loop is done, inject the string into the DOM. – Scott Marcus Jun 07 '22 at 21:15
0

Your javascript is only retrieving the first poem using this: const text = document.getElementById('text1'); i.e. it will only get the <div> with an id of text1. What you need to do is have the same identifier for all of them.

You could add a class of poem (or something similar) to each <div> and then change your javascript to retrieve all of them using:

const text = document.getElementsByClassName('poem');
mohammedkhan
  • 953
  • 6
  • 14
  • 1
    [Do not use `getElementsByClassName()`](https://stackoverflow.com/questions/54952088/how-to-modify-style-to-html-elements-styled-externally-with-css-using-js/54952474#54952474), plus the OP has said that classes aren't an option. – Scott Marcus Jun 07 '22 at 21:03
  • @ScottMarcus Thanks for that. Though I don't understand why class wouldn't be an option for the OP I was trying to find a way of doing something "jquery-esque" without using jQuery. – mohammedkhan Jun 07 '22 at 21:07
  • I don't know either, but the OP states: *(and I cannot switch id for class)* – Scott Marcus Jun 07 '22 at 21:08
0

your problem is that the function rndPoem refers to the outer variable text. The functoin rndPoem needs to be able to have the element text passed to it.

I might try something like this:

var ids = ["text1", "text2", "text3", "text4"]
var elements = ids.map(id => document.getElementById(id))
var results = elements.map(element => rndPoem(element))

and change the rndPoem to

function rndPoem(text) {
   /* rest of code */
}

If you dont like it as three separate lines / commands you can write it in a chained format:

["text1", "text2", "text3", "text4"].
    map(document.getElementById).
    map(rndPoem)

or any number of different ways

akaphenom
  • 6,728
  • 10
  • 59
  • 109