I have a 5 buttons and each button click will add each element. My concern is when I click back to previous button I click. I need a previous element only will be add and other will be remove..
example:
if click 5. it shows 5 add(element)
if then I click back to click3 it show only 3 elements and remove element[5] and element[4].
let clickItem;
for (let c = 1; c < 6; c++) {
clickItem = document.getElementsByClassName('click-item-' + c);
$(clickItem).on('click', function() {
$('.child-item').not(this).removeClass('active');
$(this).addClass('active')
$(".add-item").slice(0, c).removeClass("inactive");
})
}
<style>.active {
display: block;
background-color: blue;
}
.inactive {
display: none;
}
</style>
<button class="child-item click-item-1">Click 1</button>
<button class="child-item click-item-2">Click 2</button>
<button class="child-item click-item-3">Click 3</button>
<button class="child-item click-item-4">Click 4</button>
<button class="child-item click-item-5">Click 5</button>
<div class="add-item inactive">Add 1</div>
<div class="add-item inactive">Add 2</div>
<div class="add-item inactive">Add 3</div>
<div class="add-item inactive">Add 4</div>
<div class="add-item inactive">Add 5</div>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
You can add a function that put the inactive class to all items and then, re-run the function.
let clickItem;
for (let c = 1; c < 6; c++) {
clickItem = document.getElementsByClassName('click-item-' + c);
$(clickItem).on('click', function() {
resetContext()
$('.child-item').not(this).removeClass('active');
$(this).addClass('active')
$(".add-item").slice(0, c).removeClass("inactive");
})
}
const resetContext = () => {
const elements = document.getElementsByClassName("add-item");
for (const elem of elements){
elem.classList.remove('active');
elem.classList.add('inactive');
}
}
<style>.active {
display: block;
background-color: blue;
}
.inactive {
display: none;
}
</style>
<button class="child-item click-item-1">Click 1</button>
<button class="child-item click-item-2">Click 2</button>
<button class="child-item click-item-3">Click 3</button>
<button class="child-item click-item-4">Click 4</button>
<button class="child-item click-item-5">Click 5</button>
<div class="add-item inactive">Add 1</div>
<div class="add-item inactive">Add 2</div>
<div class="add-item inactive">Add 3</div>
<div class="add-item inactive">Add 4</div>
<div class="add-item inactive">Add 5</div>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
Related
I wanted to make each element inside myArray will have it's unique action, but I end up with only one of them working.
I have tried one more way of doing it that worked, but it was a complete boilerplate and I'm looking for a better solution than that.
More details:
For each element (Another array of buttons) inside myArray it will have unique action like scrollIntoView of some element in HTML.
In HTML I have 4 divs that share the same class and it looks like that:
<div class='firstDiv'>
<button class="teamBtn"></button>
<button class="serviceBtn"></button>
etc..
</div>
<div class='secondDiv'>
<button class="teamBtn"></button>
<button class="serviceBtn"></button>
etc..
</div>
let aboutSection = document.querySelector('.about')
let serviceSection = document.querySelector('.services')
let teamSection = document.querySelector('.team')
let homeBtn = document.querySelectorAll('.homeBtn');
let aboutBtn = document.querySelectorAll('.aboutBtn');
let serviceBtn = document.querySelectorAll('.serviceBtn')
let teamBtn = document.querySelectorAll('.teamBtn')
let myArray = [];
myArray[0] = homeBtn;
myArray[1] = aboutBtn;
myArray[2] = serviceBtn;
myArray[3] = teamBtn;
myArray.forEach(el => {
addEventListener('click', () => {
teamBtn.forEach(() => {
teamSection.scrollIntoView();
});
serviceBtn.forEach(() => {
serviceSection.scrollIntoView();
});
})
})
You really want delegation from a container wrapping ALL divs. Then only one event handler is needed for all buttons
document.getElementById("nav").addEventListener("click",function(e) {
const tgt = e.target.closest("button")
if (tgt && (tgt.classList.contains("teamBtn") ||tgt.classList.contains("serviceBtn"))) {
document.getElementById(tgt.dataset.id).scrollIntoView();
}
})
section div {
height: 500px;
background-color: red;
border: 1px solid black;
}
<nav id="nav">
<div class="firstDiv">
<button class="teamBtn" data-id="team1">Team 1</button>
<button class="serviceBtn" data-id="service1">Service 1</button>
</div>
<div class="secondDiv">
<button class="teamBtn" data-id="team2">team 2</button>
<button class="serviceBtn" data-id="service2">Service 2</button>
</div>
</nav>
<section id="content1">
<div id="team1">Team 1</div>
<div id="service1">Service 1</div>
</section>
<section id="content2">
<div id="team2">Team 2</div>
<div id="service2">Service 2</div>
</section>
I'm trying to create a chain of buttons:
First options;
- Button 1
- Button 2
IF chosen Button 1:
- Button 1a
- Button 1b
IF chosen Button 1a:
- Button 1aa
- Button 1ab
IF chosen Button 1b:
- Button 1ba
- Button 1bb
And so on.. same goes for Button 2.
Thus far I got this but my .js is not working out for me.
I tried it in two ways.
WAY 1:
HTML (onclick="nextPush" is going to change in way 2)
<div class="buttons1-2">
<button id="btn1" class="btn btn1" onclick="buttonPushed(this)">Button 1</button>
<button id="btn2" class="btn btn2" onclick="buttonPushed(this)">Button 2</button>
</div>
<div class="buttons1a-b">
<button id="btn1a" class="btn btn1a" onclick="nextPush(this)">Button 1a</button>
<button id="btn1b" class="btn btn1b" onclick="nextPush(this)">Button 1b</button>
</div>
<div class="buttons2a-b">
<button id="btn2a" class="btn btn2a">Button 2a</button>
<button id="btn2b" class="btn btn2b">Button 2b</button>
</div>
<div class="buttons1aa-ab">
<button id="btn1aa" class="btn btn1a">Button 1aa</button>
<button id="btn1ab" class="btn btn1b">Button 1ab</button>
</div>
<div class="buttons1ba-bb">
<button id="btn1ba" class="btn btn2a">Button 1ba</button>
<button id="btn1bb" class="btn btn2b">Button 1bb</button>
</div>
WAY 1: .JS
function buttonPushed(btn) {
var replacewith = "buttons1a-b";
if (btn.id == "btn2") {
replacewith = "buttons2a-b";
}
function nextPush(btn) {
var replacewith = "buttons1aa-ab";
if (btn.id == "btn1b") {
replacewith = "buttons1ba-bb";
}
var allChildren = document.getElementsByClassName('buttons')[0].children;
for (var i = 0; i < allChildren.length; i++) {
var child = allChildren[i];
if (child.className != replacewith) {
child.style.display = "none";
} else {
child.style.display = "inline";
}
}
}
WAY 2: HTML (notice the onclick="nextPush" is gone)
<div class="buttons1-2">
<button id="btn1" class="btn btn1" onclick="buttonPushed(this)">Button 1</button>
<button id="btn2" class="btn btn2" onclick="buttonPushed(this)">Button 2</button>
</div>
<div class="buttons1a-b">
<button id="btn1a" class="btn btn1a" onclick="buttonPushed(this)">Button 1a</button>
<button id="btn1b" class="btn btn1b" onclick="buttonPushed(this)">Button 1b</button>
</div>
<div class="buttons2a-b">
<button id="btn2a" class="btn btn2a">Button 2a</button>
<button id="btn2b" class="btn btn2b">Button 2b</button>
</div>
<div class="buttons1aa-ab">
<button id="btn1aa" class="btn btn1a">Button 1aa</button>
<button id="btn1ab" class="btn btn1b">Button 1ab</button>
</div>
<div class="buttons1ba-bb">
<button id="btn1ba" class="btn btn2a">Button 1ba</button>
<button id="btn1bb" class="btn btn2b">Button 1bb</button>
</div>
WAY 2 .JS
function buttonPushed(btn) {
/* btn = Id: btn1, btn2, btn1a or btn1b */
let replacewith = "buttons1a-b";
if (btn.id == "btn2") {
replacewith = "buttons2a-b";
}
else if (btn.id == "btn1a") {
replacewith = "buttons1aa-ab";
}
else if (btn.id == "btn1b") {
replacewith = "buttons1ba-bb";
}
}
let allChildren = document.getElementsByClassName('buttons')[0].children;
for (let i = 0; i < allChildren.length; i++) {
let child = allChildren[i];
if (child.className != replacewith) {
child.style.display = "none";
} else {
child.style.display = "inline";
}
}
.CSS for BOTH WAYS:
.buttons1a-b {
display: none;
}
.buttons2a-b {
display: none;
}
.buttons1aa-ab {
display: none;
}
.buttons1ba-bb {
display: none;
}
Sorry for the long post, hope you can help me out :) If you know a better way to do this, please also do let me know.
Building on your example, and the one from Michael, you could also use another approach of declaring what div you want displayed by attaching an attribute to the button, and then add an event listener to all buttons with that attribute. This makes the HTML slightly smaller and more declarative, and makes it easier to switch what element you want to display next instead of relying on a particular schema of id's.
(function(document) {
// get all buttons that have the attribute data-next
const buttons = document.querySelectorAll('[data-next]');
for (const item of buttons) {
// get references to the parent item and next item to hide/show
const parentId = item.getAttribute('data-parent');
const parent = document.querySelector(`#${parentId}`);
const nextDivId = item.getAttribute('data-next');
const nextDiv = document.querySelector(`#${nextDivId}`);
if (!nextDiv) {
console.error('could not find next div for button ', item);
}
// attach an event listener for click that toggles visibility of the above elements
item.addEventListener('click', function() {
nextDiv.classList.toggle('hidden');
parent.classList.toggle('hidden');
});
}
})(document);
.hidden {
display: none;
}
<div id="base">
<button data-next="option-a" data-parent="base">Option A</button>
<button data-next="option-b" data-parent="base">Option B</button>
</div>
<div id="option-a" class="hidden">
<p>Option A</p>
</div>
<div id="option-b" class="hidden">
<p>Option B</p>
</div>
If you want to add new buttons dynamically (or change what your next items should be) you will need to attach the event listener when you create your other buttons. For instance, you can do something like the following:
(function(document) {
function onButtonClicked(event) {
const item = event.target;
// get references to the next item to show
const nextDivId = item.getAttribute('data-next');
const nextDiv = document.querySelector(`#${nextDivId}`);
if (!nextDiv) {
console.error('could not find next div for button ', item);
}
// The function toggle on classList either removes a class if it exists
// or adds it if it does not exist in the list of classes on the element
nextDiv.classList.toggle('hidden');
// check if container has an attribute for loading next buttons lazily
const lazyLoadLevel = nextDiv.getAttribute('data-level');
// if we found the attribute, load the contents
if (lazyLoadLevel) {
// cast lazyLoadedLevel to an integer (with +) since getAttribute returns a string
loadLevel(+lazyLoadLevel, nextDiv);
// since we have populated the container we can remove the attribute so that elements do not get added again
nextDiv.removeAttribute('data-level');
}
// get references to the parent item to hide
const parentId = item.getAttribute('data-parent');
const parent = document.querySelector(`#${parentId}`);
if (parent) {
parent.classList.toggle('hidden');
}
}
function addButton(parent, nextElementId, text) {
const newItem = document.createElement('button');
newItem.setAttribute('data-next', nextElementId);
newItem.setAttribute('data-parent', parent.getAttribute('id'));
newItem.textContent = text;
newItem.addEventListener('click', onButtonClicked);
parent.appendChild(newItem);
}
function loadLevel(level, container) {
switch (level) {
// depending on level you can define other buttons to add here
case 2:
{
addButton(container, 'option-a', 'Goto option a');
break;
}
}
}
// get all *existing* buttons that have the attribute data-next
// this is run once when the script loads, and will not attach listeners to dynamically created buttons
const buttons = document.querySelectorAll('[data-next]');
for (const item of buttons) {
// attach an event listener for click that toggles visibility of parent and next elements
// notice that we pass a reference to onButtonClicked. Even though it is a function we shouldn't call it *here*
item.addEventListener('click', onButtonClicked);
}
})(document);
.hidden {
display: none;
}
<div id="base">
<button data-next="option-a" data-parent="base">Option A</button>
<button data-next="option-b" data-parent="base">Option B</button>
</div>
<div id="option-a" class="hidden">
<p>Option A</p>
<button data-next="option-b" data-parent="option-a">Option B</button>
</div>
<div id="option-b" class="hidden" data-level="2">
<p>Option B. The contents of this div is loaded lazily based on the value of the attribute data-level</p>
</div>
At first, I was thinking this should be done entirely dynamically -- where the next container of buttons is created and inserted into the DOM when the button is clicked. But judging by your current attempts, it seems like you want to have all the buttons hardcoded into the source, hidden with CSS, and shown with DOM during the click event. Here is one way you can achieve that:
function handleButtonClick(button) {
const clickedID = button.id.substring(3);
const nextDiv = document.getElementById("buttons" + clickedID);
if (nextDiv) {
nextDiv.style.display = "block";
}
}
.hidden {
display: none;
}
<div id="buttons">
<button id="btn1" onclick="handleButtonClick(this)">Button 1</button>
<button id="btn2" onclick="handleButtonClick(this)">Button 2</button>
</div>
<div id="buttons1" class="hidden">
<button id="btn1a" onclick="handleButtonClick(this)">Button 1a</button>
<button id="btn1b" onclick="handleButtonClick(this)">Button 1b</button>
</div>
<div id="buttons2" class="hidden">
<button id="btn2a" onclick="handleButtonClick(this)">Button 2a</button>
<button id="btn2b" onclick="handleButtonClick(this)">Button 2b</button>
</div>
<div id="buttons1a" class="hidden">
<button id="btn1aa" onclick="handleButtonClick(this)">Button 1aa</button>
<button id="btn1ab" onclick="handleButtonClick(this)">Button 1ab</button>
</div>
<div id="buttons1b" class="hidden">
<button id="btn1ba" onclick="handleButtonClick(this)">Button 1ba</button>
<button id="btn1bb" onclick="handleButtonClick(this)">Button 1bb</button>
</div>
<div id="buttons2a" class="hidden">
<button id="btn2aa" onclick="handleButtonClick(this)">Button 2aa</button>
<button id="btn2ab" onclick="handleButtonClick(this)">Button 2ab</button>
</div>
<div id="buttons2b" class="hidden">
<button id="btn2ba" onclick="handleButtonClick(this)">Button 2ba</button>
<button id="btn2bb" onclick="handleButtonClick(this)">Button 21bb</button>
</div>
This just identifies which button was clicked, and uses that information to determine the next div to show, until there are no more divs that correspond to the one that was clicked.
I'm trying to toggle a div's class in pure javascript (unfortunately I cannot use jQuery). I've got some code working but it doesn't work for multiple instances of the div and I'd appreciate some help for that.
I can't give each element it's own specific ID, so I'd need a way to target only the div with a class of 'truncate' that is the parent of the particular button that is clicked. Currently I have hidden the results by default and am just toggling the 'show' class
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<div id="button">Show more</div>
</div>
collapse= document.getElementById('button');
collapse.onclick = function() {
collapse.parentElement.classList.toggle("show");
};
/* HIDE PLATES BY DEFAULT */
.truncate .result {
display: none;
}
/* SHOW RESULTS WHEN SHOW CLASS APPLIED */
.truncate.show .result {
display: block !important;
}
Thank you - help appreciated as always.
I think you need getElementsByClassName
(function() {
var collapse = document.getElementsByClassName('button');
for (var elIndex = 0; elIndex < collapse.length; elIndex++) {
collapse[elIndex].onclick = function() {
this.parentElement.classList.toggle("show");
};
}
})();
/* HIDE PLATES BY DEFAULT */
.truncate .result {
display: none;
}
/* SHOW RESULTS WHEN SHOW CLASS APPLIED */
.truncate.show .result {
display: block !important;
}
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<div class="button">Show more</div>
</div>
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<div class="button">Show more</div>
</div>
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<div class="button">Show more</div>
</div>
You should replace the id of Show more to class.
And use the following code.
collapse =document.getElementsByClassName('button');
for(let i = 0; i < collapse.length; i++){
let oneElement = collapse[i];
oneElement.addEventListener('click', function() {
oneElement.parentElement.classList.toggle("show");
})
}
Parse (loop over) all of your div.truncate elements and give themselves their own functionality via the Accordionize Function.
const Accordionize = el => {
const results = el.querySelectorAll('.result')
const toggleButton = el.querySelector('button')
let open = false
const _toggle = () => {
const action = open ? 'remove' : 'add'
results.forEach(item => item.classList[action]('show'))
open = !open
}
toggleButton.addEventListener('click', _toggle)
}
// get all div.truncate and apply them to their own instance of Accordionize
document.querySelectorAll('.truncate').forEach(Accordionize)
.truncate {
border: 2px solid red;
margin: 5
}
.result {
display: none;
}
.show {
display: block
}
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<button>Show more1</button>
</div>
<div class="truncate">
<div class="result">Result 3</div>
<div class="result">Result 4</div>
<button>Show more2</button>
</div>
<div class="truncate">
<div class="result">Result 5</div>
<div class="result">Result 6</div>
<button>Show more3</button>
</div>
<div class="truncate">
<div class="result">Result 7</div>
<div class="result">Result 8</div>
<button>Show more4</button>
</div>
I want to implement expandable menu. Only one heading should be expanded. When user clicks on another one, content of the previously
expanded heading should hide. I have used code from w3schools, but I don't know how to automatically hide previous heading.
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
<h2>Collapsibles</h2>
<p>A Collapsible:</p>
<button class="collapsible">Open Collapsible</button>
<div class="content">
<p>text</p>
</div>
<p>Collapsible Set:</p>
<button class="collapsible">Open Section 1</button>
<div class="content">
<p>text</p>
</div>
<button class="collapsible">Open Section 2</button>
<div class="content">
<p>text.</p>
</div>
<button class="collapsible">Open Section 3</button>
<div class="content">
<p>text</p>
</div>
Simply collapse opened collapsible on click by JS:
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
var content = this.nextElementSibling;
if (this.classList.contains("active")) {
content.style.opacity = 0;
} else {
if(node=document.querySelector(".collapsible.active")){
node.classList.toggle("active",false);
node.nextElementSibling.style.opacity = 0;
}
content.style.opacity = 1;
}
this.classList.toggle("active");
});
}
.content{
opacity:0;
transition:opacity 0.5s;
}
<h2>Collapsibles</h2>
<p>A Collapsible:</p>
<button class="collapsible">Open Collapsible</button>
<div class="content">
<p>text</p>
</div>
<p>Collapsible Set:</p>
<button class="collapsible">Open Section 1</button>
<div class="content">
<p>text1</p>
</div>
<button class="collapsible">Open Section 2</button>
<div class="content">
<p>text2</p>
</div>
<button class="collapsible">Open Section 3</button>
<div class="content">
<p>text3</p>
</div>
Or, to use with height, you'll need to add overflow-y:hidden to hide it completely:
var coll = document.getElementsByClassName("collapsible");
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
console.trace()
debugger
var content = this.nextElementSibling;
if (this.classList.contains("active")) {
content.style.height = 0;
} else {
if(node=document.querySelector(".collapsible.active")){
node.classList.toggle("active",false);
node.nextElementSibling.style.height = 0;
}
content.style.height = content.scrollHeight+"px";
}
this.classList.toggle("active");
});
}
.content{
height:0;
transition:height 0.5s;
overflow-y:hidden;
}
<h2>Collapsibles</h2>
<p>A Collapsible:</p>
<button class="collapsible">Open Collapsible</button>
<div class="content">
<p>text1</p>
</div>
<p>Collapsible Set:</p>
<button class="collapsible">Open Section 1</button>
<div class="content">
<p>text1</p>
</div>
<button class="collapsible">Open Section 2</button>
<div class="content">
<p>text2</p>
</div>
<button class="collapsible">Open Section 3</button>
<div class="content">
<p>text3</p>
</div>
A more readable way to do this is to divide your code in functions, like this:
<script>
function hideOthers(actual) {
var contentDivs = document.querySelectorAll('.content');
contentDivs.forEach(others => {
if (others !== actual) {
others.style.display = 'none';
}
});
}
function toggleDisplay(div) {
if (div.style.display === "block") {
div.style.display = "none";
} else {
div.style.display = "block";
}
}
function onContentLoaded() {
var collapsibleDivs = document.querySelectorAll(".collapsible");
collapsibleDivs.forEach(div => {
div.addEventListener('click', e => {
var clicked = e.srcElement;
var sibling = clicked.nextElementSibling;
toggleDisplay(sibling);
hideOthers(sibling);
})
})
}
document.addEventListener("DOMContentLoaded", onContentLoaded);
</script>
Notice I've just changed your JS script and I've used document.querySelectorAll to get all elements with a given class, forEach function to iterate over elements, arrow functions to provide callbacks and e.srcElement to get the clicked element on the click handler. Hope it help you. Welcome to SO!
The following codes makes div appear sequentially.
$(document).ready(function() {
$('.word1, .word2, .word3').each(function(fadeIn) {
$(this).delay(fadeIn * 500).fadeIn(1000);
});
});
.chat {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="chat word1">Word 1</div>
<div class="chat word2">Word 2</div>
<div class="chat word3">Word 3</div>
<div id="" class="">Word 4</div>
</body>
What I want to do is, I don't want it to appear in a sequence. I can do it by simply replacing elements in an html, for example I can do:
<div class="chat word2">Word 2</div>
<div class="chat word1">Word 1</div>
<div class="chat word3">Word 3</div>
However, I don't want to change anything on the html elements. I want to do it using javascript. At first, I thought javascript selector works like an array and I can replace
$('.word1, .word2, .word3') with $('.word2, .word1, .word3')
but it does not seems to work that way.
Is there a way to do this with Javascript?
Here be a solution if you do not want to change your HTML(and incase css also):
Keep the shuffle Position in array.
Iterate all div having class chat.
Put the DOM element in new array based on shuffle Position.
Iterate all element of new array and append in body.
$(document).ready(function() {
var shufflePosition=[1,0,2];//Keep the shufflePosition in array
var result=[];
//Iterate all div having class chat
$('.chat').get().forEach(function(entry, index, array) {
result[index]=array[shufflePosition[index]];
});
for (var i = result.length-1; i >= 0; i--) {
$( "body" ).last().prepend(result[i]);
//$(result[i]).show();
$(result[i]).delay(i*500).fadeIn(1000);
}
});
.chat {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="chat word1">Word 1</div>
<div class="chat word2">Word 2</div>
<div class="chat word3">Word 3</div>
<div id="" class="">Word 4</div>
</body>
You use a query selector:
var word1 = document.querySelectorAll(".chat", ".word1")[0];
This selects the first element with both classes .chat and .word1.
how about this
$(document).ready(function() {
$('.chat').delay(500).fadeIn(1000);
});
.chat {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="chat word1">Word 1</div>
<div class="chat word2">Word 2</div>
<div class="chat word3">Word 3</div>
<div id="" class="">Word 4</div>
</body>
I think the simplest solution, to not care about the order of the Divs, is:
$('.chat').each(function(fadeIn) {
$(this).delay(fadeIn * 500).fadeIn(1000);
});
You should define a common class for these randomly ordered elements, or wrap them with a parent element, eg:
$('.randomlysortedelements div').each(function(fadeIn) {
$(this).delay(fadeIn * 500).fadeIn(1000);
});
<body>
<div class="randomlysortedelements">
<div class="chat word3">Word 3</div>
<div class="chat word1">Word 1</div>
<div class="chat word2">Word 2</div>
</div>
<div id="" class="">Word 4</div>
</body>
You can shuffle your array length and prependTo to word4 something like this:
$(document).ready(function() {
elements = $('.word1, .word2, .word3');
let arrayData = [];
for(i=0;i<elements.length;i++){
arrayData.push(i);
}
shuffleArray(arrayData);
for(i=0;i<arrayData.length;i++){
$("body:last").prepend(elements.eq(arrayData[i]));
elements.eq(arrayData[i]).show()
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
});
.chat {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="chat word1">Word 1</div>
<div class="chat word2">Word 2</div>
<div class="chat word3">Word 3</div>
<div id="" class="word4">Word 4</div>
</body>