I created an array that stores the ids of buttons. Button ids are #red, #green, #blue and #yellow
I created another function the randomly selects a color and stores it inside of another array.
I am tying to iterate the second array using a for loop and use a fade in/out effect on the buttons so the outcome will be an ordered fade in and out effect.
For example:
array = ['red','green','blue'];
First the red button fades in and out then the green and lastly the blue.
The outcome I get is a fade in and out effect almost at the same time. Can anybody please provide a solution and tell me why it happens?
var buttonColours = ["red", "blue", "green", "yellow"];
var GamePattern = [];
function nextSequence() {
var randomNumber = Math.floor((Math.random() * 4));
var randomChosenColour = buttonColours[randomNumber]
GamePattern.push(randomChosenColour);
}
function playSequence(sequence) {
for (var i = 0; i < sequence.length; i++) {
$("#" + sequence[i]).fadeOut(1000).fadeIn(1000)
}
}
nextSequence()
nextSequence()
nextSequence()
playSequence(GamePattern)
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
<h1 id="level-title">Press A Key to Start</h1>
<div class="container">
<div lass="row">
<div type="button" id="green" class="btn green"></div>
<div type="button" id="red" class="btn red"></div>
</div>
<div class="row">
<div type="button" id="yellow" class="btn yellow"></div>
<div type="button" id="blue" class="btn blue"></div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
The issue with your code is because you run all the fade effects at the same itme.
You can simplify the approach and the code by randomising the order of your input array and then iterating through it to fade in/out the relevant elements, adding an incremental delay to each so that only one fade happens at a time in sequence. Try this:
// shuffle logic credit: https://stackoverflow.com/a/2450976/519413 #coolaj86
function shuffle(array) {
let currentIndex = array.length, randomIndex;
while (currentIndex != 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
}
return array;
}
var buttonColours = ["red", "blue", "green", "yellow"];
shuffle(buttonColours).forEach((id, i) => {
$('#' + id).delay(i * 2000).fadeOut(1000).fadeIn(1000);
});
.container .row {
display: inline-block;
}
.container .row .btn {
width: 100px;
height: 100px;
display: inline-block;
}
.btn.green { background-color: #0C0; }
.btn.red { background-color: #C00; }
.btn.yellow { background-color: #CC0; }
.btn.blue { background-color: #00C; }
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
<h1 id="level-title">Press A Key to Start</h1>
<div class="container">
<div class="row">
<div type="button" id="green" class="btn green"></div>
<div type="button" id="red" class="btn red"></div>
</div>
<div class="row">
<div type="button" id="yellow" class="btn yellow"></div>
<div type="button" id="blue" class="btn blue"></div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Javascript is by default asynchronous - meaning it won't wait for the fade in/out unless you explicitly tell it to do so.
I'd advise using a simple setTimeout command, see here for more information and alternatives
For example, if you change this part:
for (var i=0 ; i<sequence.length ; i++){
$("#" + sequence[i]).fadeOut(1000).fadeIn(1000)
}
To this:
for (var i=0 ; i<sequence.length ; i++){
setTimeout(function() {
$("#" + sequence[i]).fadeOut(1000).fadeIn(1000)
}, 2000)
}
It will wait 2000 miliseconds before going to the next point in the loop
I want to make a program that write out the textContent of the item that has clicked. For some reason this program only get the last element's content. Any idea what should I change inside the for loop?
var emailname = document.querySelectorAll(".name");
var gSenderName = document.getElementById('sname');
$('.name').click(function() {
for (var i = 0; i < emailname.length; i++) {
const sendername = emailname[i].textContent;
gSenderName.textContent = sendername;
}
});
.name:hover {
text-decoration: underline;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="name">first</div><br>
<div class="name">second</div><br>
<div class="name">third</div>
<br>
<div>Selected:
<div id="sname"></div>
</div>
You do not need the loop here at all. You can simply get the currently clicked element's text by using this object. I will also suggest you not mix up vanilla JS and jQuery unnecessarily:
var gSenderName = $('#sname');
$('.name').click(function(){
gSenderName.text($(this).text());
});
.name:hover {
text-decoration: underline;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="name">first</div><br>
<div class="name">second</div><br>
<div class="name">third</div>
<br>
<div>Selected:
<div id="sname"></div>
</div>
The loop runs and sets the text content of each item one after the other. Because each override the other, you always get the last one.
Just set the text content of the element that was clicked:
var gSenderName = document.getElementById('sname');
$('.name').click(e => {
gSenderName.textContent = e.target.textContent;
});
.name:hover {
text-decoration: underline;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="name">first</div><br>
<div class="name">second</div><br>
<div class="name">third</div>
<br>
<div>Selected:
<div id="sname"></div>
</div>
I am trying to change the color of background.
I am changing every odd results to light green(#f0f5f5) so when the result ends in even number,
I get big white space.
I would like to change background color of pagination section to light green when the result ends in even number.
Sear
search results displays only 5 results so it could be 2th and 4th.
search.addWidgets([
instantsearch.widgets.searchBox({
container: '#searchbox',
}),
instantsearch.widgets.hits({
container: '#Algolia_Result',
transformItems: function (items) {
return items.map(function (item) {
if (item.objectType === 'Startup') {
item._isDescription = isNotNull(item.description);
} else if (item.objectType === 'NEWS') {
item._isSource = isNotNull(item.source);
} else if (item.objectType === 'Comment') {
item._isComment = isNotNull(item.comment);
return item;
});
},
templates: {
empty: '<div id="empty">No results have been found for {{ query }}.</div><br>',
item: `
<a href="{{linkUrl}}" target="_blank">
<div class="algolia_container">
<div class="item1">
<div id="images"><img src="{{logoUrl}}" alt="{{hits-image}}" id="hits-image"></div>
<div id="objTyeps"><span class="objectType {{objectCss}}">{{objectType}}</span></div>
</div>
<div class="item2">
<div id="objectTitle">
<span id="titleForDisplay">{{#helpers.highlight}}{ "attribute": "titleForDisplay" }{{/helpers.highlight}}</span>
</div>
</div>
<div class="item3">
{{#_isLocation}}
<div id="location">{{#helpers.highlight}}{ "attribute": "location" }{{/helpers.highlight}}</div>
{{/_isLocation}}
</div>
</div></a>
`,
},
}),
instantsearch.widgets.pagination({
container: '#pagination',
}),
]);
#Algolia_Result > div > div > ol > li:nth-child(odd){background-color: #f0f5f5;}
.ais-Pagination-item {
display:inline;
padding: 5px;
margin: 0 5px;
border: 1px solid #E8E8E8;
border-radius:5px;
font-size:18px;
}
.ais-Pagination-list {
text-align: center;
height:45px;
padding-top: 10px;
}
.ais-Pagination-item:hover {
background-color: #DCDCDC;
transition: background-color .2s;
}
.ais-Pagination-item--selected{
background-color: #E8E8E8;
}
<div id="searchbox"></div>
<div id="results">
<div id="Algolia_Result"></div>
<div id="pagination"></div>
</div>
This is ok
This need be fixed as if the background color of pagination area is the same as the last result, it must be green
This is what I get in the console.
You can color background of the pagination row by using JavaScript to count the number of results and apply color if the number of results is even.
Check out the example below.
Example 1 is with an odd number of result rows and the CSS works fine, same as your working example.
Example 2 is with an even number of result rows and uses the JS code to style the pagination background.
// Count the rows
let numRows = document.querySelectorAll('#example-2 .row').length
// If the number of rows is even
if (numRows % 2 == 0) {
// Apply the background color to the pagination row
document.querySelector('#example-2 .pagination').style.backgroundColor = '#eee'
}
.container {
border: 1px solid #000;
margin-bottom: 5px;
}
.row:nth-child(odd) {
background-color: #eee;
}
Example 1
<div id="example-1" class="container">
<div>
<div class="row">Row 1</div>
<div class="row">Row 2</div>
<div class="row">Row 3</div>
</div>
<div>
<div class="pageination">Pagination Row</div>
</div>
</div>
Example 2
<div id="example-2" class="container">
<div>
<div class="row">Row 1</div>
<div class="row">Row 2</div>
<div>
<div>
<div class="pagination">Pagination Row</div>
</div>
</div>
EDIT: So in your example, you would add the following JavaScript.
<script>
let numRows = document.querySelectorAll('.ais-Hits-item').length
if (numRows % 2 == 0) {
document.querySelector('.ais-Pagination-list').style.backgroundColor = '#eee'
}
</script>
EDIT 2: Looking at your code sandbox I can see that the issue is that the JS that counts the number of rows is being run before the rows have been rendered by Algolia.
To solve this issue we need to place our row counting JS into an Algolia callback that is ran after the rows have been rendered. We can use the algolia search.on('render', ...) event callback.
Try this:
search.on('render', () => {
let numRows = document.querySelectorAll('.algolia_container').length;
if (numRows % 2 === 0) {
document.querySelector('#pagination').style.backgroundColor = 'red';
} else {
document.querySelector('#pagination').style.backgroundColor = 'transparent';
}
});
I'm trying to build a function that changes background(color a), box(color b) and text color(color a) when a user clicks on the refresh button. I've set the color array, but couldn't figure out how to loop the array properly. Could anyone please help?
var colors = [
["#808080", "#f08080"],
["#2f4f4f", "#cdcdc1"],
["#F3E4C3", "#191970"],
["#DD5C3D", "#495496"],
["#ffbdbd", "#bdffff"],
["#c9c9ff", "#282833"],
["#fff5ee", "#4682b4"]]
I think I can do something like this below:
$("#refresh").click(function(){
$("box").animate({
backgroundColor: colors[0][1],
}, 500);
$("box").css("color", colors[0][0]);
$("background").animate({
backgroundColor: colors[0][0],
}, 500);
//add something that triggers loop here
});
And my html below:
<body>
<section id="main" class="box" style="margin-bottom: 10px">
<div id="city"></div>
<div id="detail"></div>
<div id="icon"></div>
<div id="temperature"></div>
<div id="fcicon" class="inrow">
<div id="f">F</div><div style="opacity: 0.5">/</div><div id="c">C</div>
</div>
<div id="refresh"><i class="fa fa-refresh"></i></div>
</section>
I don't think you need a loop. Try the code below. However i would recommend you to make separate css classes and toggle between them.
var colors = [["#808080", "#f08080"],
["#2f4f4f", "#cdcdc1"],
["#F3E4C3", "#191970"],
["#DD5C3D", "#495496"],
["#ffbdbd", "#bdffff"],
["#c9c9ff", "#282833"],
["#fff5ee", "#4682b4"]];
$(document).on(function(){
var i=0;
$("#refresh").click(function(){
if(colors.length==i+1){
i=0;
}else{
i=i+1;
$("box").animate({
backgroundColor: colors[i][1],
}, 500);
$("section").animate({
backgroundColor: colors[i][0],
}, 500);
$("background").animate({
backgroundColor: colors[i][0],
}, 500);
});
}
});
Edited my example to use your HTML, works great. I changed the class from .container to .box, as that's what you're using.
Here it is as a fiddle, in case.
// Array of color pairs that we'll use for background
// colors, text colors and border colors.
var colors = [
["#808080", "#f08080"],
["#2f4f4f", "#cdcdc1"],
["#F3E4C3", "#191970"],
["#DD5C3D", "#495496"],
["#ffbdbd", "#bdffff"],
["#c9c9ff", "#282833"],
["#fff5ee", "#4682b4"]
];
// The counter refers to which pair in the array we're
// currently referencing.
var counter = 0;
// When the refresh div gets clicked,
$("#refresh").click(function() {
// check the counter and increment or reset it.
if (counter >= colors.length - 1) {
counter = 0;
} else {
counter++
}
// Now, we want to animate CSS attributes on the
// container object. We'll use the color pair
// we're currently pointing to for the background
// text and border colors.
$(".box").animate({
backgroundColor: colors[counter][1],
color: colors[counter][0],
borderColor: colors[counter][0]
}, 500);
});
.box {
position: relative;
border: 1px solid blue;
height: 200px;
width: 200px;
}
.box #city {
font-weight: bolder;
font-size: 14px;
}
#refresh {
position: absolute;
bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<section id="main" class="box" style="margin-bottom: 10px">
<div id="city">Worcester, MA</div>
<div id="detail"></div>
<div id="icon"></div>
<div id="temperature"></div>
<div id="fcicon" class="inrow">
<div id="f">F</div><div style="opacity: 0.5">/</div><div id="c">C</div>
</div>
<div id="refresh"><i class="fa fa-refresh"></i></div>
</section>
Added comments to make it a bit easier to follow.
you can simply keep track of the index by creating a closure.
function looper(){
let i = 0;
return function(){
$("box").animate({
backgroundColor: colors[i][1],
}, 500);
$("section").animate({
backgroundColor: colors[i][0],
}, 500);
$("background").animate({
backgroundColor: colors[i][0],
}, 500);
i++;
if(i === colors.length){
i = 0;
}
}
}
let change = looper();
now you can listen for the event and call the function "change" accordingly.
So I would store the value in the element via data(). Makes it really easy and reusable. Take a moment and read Decoupling Your HTML, CSS, and JavaScript.
The following code is reusable and extensible. Reusable by allowing multiple buttons to have different targets to refresh. Extensible by allowing you to add as many items to the animate as you want. Honestly I'd just put the color in the js-refresh button so each refresh button can have it's own array.
$(document).ready(()=>{
var colors = [
["#808080", "#f08080"],
["#2f4f4f", "#cdcdc1"],
["#F3E4C3", "#191970"],
["#DD5C3D", "#495496"],
["#ffbdbd", "#bdffff"],
["#c9c9ff", "#282833"],
["#fff5ee", "#4682b4"]];
$(".js-refresh").on('click', (e) => {
var $this = $(e.currentTarget);
var selector = $this.data('refresh-target');
$(selector).each((i,e)=>{
var $this = $(e);
var idx = $this.data('js-refresh-index') || 1;
idx = idx >= colors.length ? 1 : idx + 1;
$this
.data('js-refresh-index', idx)
.stop()
.animate({
backgroundColor: colors[idx-1][0],
}, 1)
.animate({
backgroundColor: colors[idx-1][1],
}, 500);
})
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script
src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"
integrity="sha256-H28SdxWrZ387Ldn0qogCzFiUDDxfPiNIyJX7BECQkDE="
crossorigin="anonymous"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<section id="main" class="box" style="margin-bottom: 10px">
<div id="city"></div>
<div id="detail"></div>
<div id="icon"></div>
<div id="temperature" class="refresh-1">Temp</div>
<div id="fcicon" class="inrow">
<div id="f">F</div><div style="opacity: 0.5">/</div><div id="c">C</div>
</div>
<div class="js-refresh" data-refresh-target=".refresh-1">
<i class="fa fa-refresh"></i>
</div>
</section>
JQuery Animate from their docs
Animation Properties and Values
All animated properties should be animated to a single numeric value, except as noted below; most properties that are non-numeric cannot be animated using basic jQuery functionality (For example, width, height, or left can be animated but background-color cannot be, unless the jQuery.Color plugin is used). Property values are treated as a number of pixels unless otherwise specified. The units em and % can be specified where applicable.
My Html and JavaScript
<!DOCTYPE html>
<html>
<head>
<title>Animate</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div class="row">
<select id="colors">
<option value="BlueWhite">Background: Blue, Color: White</option>
<option value="YellowBlue">Background: Yellow, Color: Blue</option>
<option value="WhiteRed">Background: White, Color: Red</option>
<option value="BlackWhite">Background: Black, Color: White</option>
</select>
<div id="main" class="box" style="margin-bottom: 10px">
<div id="city"></div>
<div id="detail"></div>
<div id="icon"></div>
<div id="temperature"></div>
<div id="fcicon" class="inrow">
<div id="f">F</div><div style="opacity: 0.5">/</div><div id="c">C</div>
</div>
</div>
<button id="refresh" class="btn btn-primary"><i class="fa fa-refresh"></i></button>
</div>
<script>
$(document).ready(function () {
var colors = {
"BlueWhite": {
"Background": "#0000ff",
"Color": "#ffffff"
},
"YellowBlue": {
"Background": "#FFFF00",
"Color": "#0000ff"
},
"WhiteRed": {
"Background": "#ffffff",
"Color": "#ff0000"
},
"BlackWhite": {
"Background": "#000000",
"Color": "#ffffff"
}
};
$("#refresh").click(function () {
var selected = $("#colors").val();
var colorObj;
if(colors[selected] != undefined) {
colorObj = colors[selected];
} else {
colorObj = colors["BlackWhite"];
}
$("#main").animate({
backgroundColor: colorObj.Background,
color: colorObj.Color
}, function () {
$(this).css("backgroundColor", colorObj.Background).css("color", colorObj.Color);
});
});
});
</script>
</body>
</html>
I have a few divs which are using the same class.
Inside the divs are three more divs with identical classes.
<div class="plane">
<div class="win1">Lorem ipsum</div>
<div class="win2">Dolor sit</div>
<div class="win3">amet.</div>
</div>
<div class="plane">
<div class="win1">Lorem ipsum</div>
<div class="win2">Dolor sit</div>
<div class="win3">amet.</div>
</div>
var allPlanes = $('.plane');
for (var i = 0; i < allPlanes.length; i++) {
var onePlane = allPlanes[i];
var baseHeight = 10;
$(onePlane + " .win1").css("height", parseInt(baseHeight*1));
$(onePlane + " .win2").css("height", parseInt(baseHeight*2));
$(onePlane + " .win3").css("height", parseInt(baseHeight*3));
}
(Don't mind about the names. It's just an example...)
Now I made an array with the outside divs and I can select the single divs inside. But I did not get the right syntax for the child divs inside.
Can anyone help?
My Fiddle: http://jsfiddle.net/SchweizerSchoggi/559xvww6/
Change you script to this:
var allPlanes = $('.plane');
var baseHeight = 10;
$(".plane > .win1").css("height", parseInt(baseHeight*1)+"px");
$(".plane > .win2").css("height", parseInt(baseHeight*2)+"px");
$(".plane > .win3").css("height", parseInt(baseHeight*3)+"px");
You don't need the for loop in such a case.
A prettier way:
var baseHeight = 10;
for (var i = 1; i <= 3; i++) {
$(".plane > .win"+i).css("height", parseInt(baseHeight*i)+"px");
}
http://jsfiddle.net/559xvww6/3/
If you don't want to use a for loop and want to dinamically configure from an array:
var baseHeight = 10;
$.map([1,2,3], function(i) {
$(".plane > .win"+i).css("height", parseInt(baseHeight*i)+"px");
});
http://jsfiddle.net/559xvww6/10/
Edit:: Just a side note: all these approachs are valid, but that doesn't mean that they are the best / most efficient ones. Feel free to use the one you like the most, understand it and try to use it or adapt it to your very personal situation. The "easiest" approach is surely the first one, but it is also the longest one.
isn't this one is better:
var base = 10;
$('.plane > div').css('height', function(){
return base*($(this).index()+1)
});
.plane {
background-color: #ccc;
border: solid 1px #cdcdcd;
margin-bottom: 15px;
}
.plane > .win1 { background-color: #ddd; }
.plane > .win2 { background-color: #eee; }
.plane > .win3 { background-color: #fff; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="plane">
<div class="win1">Lorem ipsum</div>
<div class="win2">Dolor sit</div>
<div class="win3">amet.</div>
</div>
<div class="plane">
<div class="win1">Lorem ipsum</div>
<div class="win2">Dolor sit</div>
<div class="win3">amet.</div>
</div>
You cannot use + operator between a jQuery object and a string.
The correct way to do it is this:
$(".win1", onePlane).css("height", parseInt(baseHeight*1));
$(".win2", onePlane).css("height", parseInt(baseHeight*2));
$(".win3", onePlane).css("height", parseInt(baseHeight*3));
Each of these queries translates to: select all elements with .winX that are inside the jQuery object onePlane.
I would use all the same class names inside the nest and then just do $('.plane:eq(0) .win:eq(2)').html()
alert( $('.plane:eq(0) .win:eq(2)').html() );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="plane">
<div class="win">Lorem ipsum</div>
<div class="win">Dolor sit</div>
<div class="win">amet.</div>
</div>
<div class="plane">
<div class="win">Lorem ipsum</div>
<div class="win">Dolor sit</div>
<div class="win">amet.</div>
</div>
if your classes are fixed then you can do with this code
$(".win1", $(".plane")).css("height", parseInt(baseHeight*1));
$(" .win2", $(".plane")).css("height", parseInt(baseHeight*2));
$(" .win3", $(".plane")).css("height", parseInt(baseHeight*3));
You can do using each loop of plane class.
$('.plane').each(function(){
baseHeight = 10;
$(this).find(".win1").css("height", parseInt(baseHeight*1));
$(this).find(".win2").css("height", parseInt(baseHeight*2));
$(this).find(".win3").css("height", parseInt(baseHeight*3));
});
Demo