Change Div and Body Class on Refresh - javascript

I'm using this Backstretch plugin to apply a stretched background image to my body element.
$("body.apples").backstretch("/apples.jpg");
$("body.oranges").backstretch("/oranges.jpg");
$("body.pears").backstretch("/pears.jpg");
I want my body class to change on refresh, so it shows the different background images on refresh. I'm also trying to work out how to only show the related .wrapper div below when the page is refreshed.
<body class="apples">
<div class="wrapper apples">
<h1>Something about Apples</h1>
<p>Some content</p>
</div>
<div class="wrapper oranges">
<h1>Something about Oranges</h1>
<p>Some content</p>
</div>
<div class="wrapper pears">
<h1>Something about Pears</h1>
<p>Some content</p>
</div>
</body>
I've managed to get the .wrapper div to change on refresh with this bit of JS:
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
function RandomFruit() {
var r = randomFromTo(1, $('.wrapper').length);
$('.wrapper').hide().eq(r - 1).show();
}
$(document).ready(function() {
RandomFruit();
});
I've got a working demo here: http://codepen.io/realph/pen/KCEtB
For some reason, I can't work out how to make the background and .wrapper div change.
Any help with this is appreciated. Thanks in advance.

Maybe you can do it with an if else statement? And you would only need 1 wrapper
if ( $("body").hasClass("yourfruithere") ) {
$(".wrapper").html("<h1>Something about this fruit</h1><p>some content</p>");

You can detect the class of the body after the page loads, store that class as a variable, and show only the related content that also has that class:
fiddle
HTML:
<div class="oranges">
<p class="oranges">Oranges</p>
<p class="apples">Apples</p>
<p class="pears">Pears</p>
</div>
jQuery:
$(function() {
var activeClass = $('div').attr('class');
$('p').hide(),
$('p.' + activeClass).show();
});
This function runs on document load just as a demo, but you would want to make sure you store the body's class as a variable after it loads on the page and is dynamically set by your other JS. Otherwise you may end up with a class of null.

I don't know how comfortable you are working with objects in javascript, but here is one solution to your problem:
Create a Fruit object that contains the class name for the body, its own element, and its own image. Each fruit object would have a Show() method that would change the class of the body element, the background image, and show itself. It would also have a Hide() method for hiding itself.
Create an array of Fruit objects, and randomize an index. Call Hide() on all of them, and then Show() on the chosen one.
Here is one implementation:
var run = function () {
var apples = new Fruit(
'apples',
$('.apples'),
'apple.jpg');
var oranges = new Fruit(
'oranges',
$('.oranges'),
'orange.jpg');
var pears = new Fruit(
'pears',
$('.pears'),
'pear.jpg');
var fruitBasket = new FruitBasket([apples, oranges, pears]);
fruitBasket.displayRandomFruit();
}
var Fruit = function (className, element, image) {
this.show = function () {
$(element).show();
$('body').backstretch(image);
$('body').removeClass().addClass(className);
}
this.hide = function () {
$(element).hide();
}
}
var FruitBasket = function (fruitList) {
this.displayRandomFruit = function () {
var randomFruitIndex = Math.floor(Math.random() * fruitList.length);
for (var i = 0; i < fruitList.length; i++) {
fruitList[i].hide();
}
fruitList[randomFruitIndex].show();
}
}
$(document).ready(function () {
run();
});
Here it is on jsfiddle.

Related

Using an attribute value to add custom links for each images in my wordpres gallery

I'm using Elementor Pro for my photography website and i want to set custom links for each image in the gallery. By default, i can only set a global link which is the same for each image so that's not great.
In fact, i want to set a custom link which will redirect the user to the shop page of the specific image.
I found some code online (thanks to elementhow !) and it's really close to what i want, but i still need to change some things. The thing is a have to manually write all the links in an array and it's not convenient (close to 100 files and growing, if i change the order, i have to reorder the links, etc).
Here's the code i currently use :
<style>.e-gallery-item{cursor: pointer;} </style>
<script>
document.addEventListener('DOMContentLoaded', function () {
var filteredImages = document.querySelectorAll('.e-gallery-item');
//Edit the links HERE
var links = [
'https://www.mywebsiteurl.com/product/product-name1/',
'https://www.mywebsiteurl.com/product/product-name2/',
'https://www.mywebsiteurl.com/product/product-name3/',
'https://www.mywebsiteurl.com/product/product-name4/',
];
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function () {
location = links[i];
});
};
for (var i = 0; i < filteredImages.length; i++) {
_loope(i);
}
});
</script>
I would like to use an attribute value in the algorithm to generate the link automatically for each image. I have the process in my mind, but i don't know how to code this...
Here's the code of one image ,i can set what value i want in "alt".
<div class="e-gallery-image elementor-gallery-item__image e-gallery-image-loaded" data-thumbnail="......" data-width="1024" data-height="768" alt="product-name";"></div>
I would like to use the "alt" attribute to create a unique url for each file, with this format :
'https://www......com/product/product-name/'
"product-name' will take the value of the "alt" attribute of each image.
I tried to change this part of the code (replace "links[i]" by trying to get the attribute value using filteredImages[i].getAttributes) but without success...
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function () {
location = links[i];
});
};
Can someone give me some tips about how to do that ? I spend 2 years without coding so i'm a bit rusty...
I think this does what you'd like it to, as you have already done you can cycle through each image link using a class.
You can get the value of alt using the .attr() function and then replace the href value of the link.
DEMO
// Cycle through each image using common class
$(".e-gallery-image").each( function() {
// Get value of 'alt' for clicked item
alt = $(this).attr("alt");
// Update href value
$(this).attr("href", "https://www.mywebsiteurl.com/product/" + alt );
});
// Prove that its worked
$(".e-gallery-image").click( function() {
// Confirm all is correct
console.log($(this).attr("href"));
// Assign url to window
location.href = $(this).attr("href");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="e-gallery-image" href="test.com" alt="product1">Product 1</div>
<div class="e-gallery-image" href="test.com" alt="product2">Product 2</div>
<div class="e-gallery-image" href="test.com" alt="product3">Product 3</div>
<div class="e-gallery-image" href="test.com" alt="product4">Product 4</div>
<div class="e-gallery-image" href="test.com" alt="product5">Product 5</div>
In fact it was really simple. I tried to target a parent element and it worked ! If anyone is interested, here's the code i use :
document.addEventListener('DOMContentLoaded', function () {
var filteredImages = document.querySelectorAll('YOUR_SELECTOR');
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function() {
location = "YOUR_WEBSITE_URL" + filteredImages[i].querySelector("YOUR_SELECTOR").getAttribute("alt");
});
};
for (var i = 0; i < filteredImages.length; i++) {
_loope(i);
}
});

Get variables from button css in Javascript and use them as id

Hi I need a bit of help modifying my script. What I want to do:
I have a small and easy script. It changes the class of an container so I have influence on the behaviour and looking of the container. In my scenario the buttons open a div with a music player.
My problem is that I need to declare all buttons as a script. The button ID is in my case the onclick function (see code).
So when I have 10 or twenty links I need also everytime to modify the script. My idea is to have a script wich gets feed their variables by id's and classes of containers. So I need not to modify the script file.
// JavaScript Document
function AudioFF() {
var FFplayer = document.getElementById(x);
if (FFplayer.classList.contains("audio-hidden")) {
FFplayer.classList.remove("audio-hidden");
FFplayer.classList.add("audio-shown");
} else {
FFplayer.classList.remove("audio-shown");
FFplayer.classList.add("audio-hidden");
Array.prototype.slice.call(document.querySelectorAll('audio')).forEach(function(audio) {audio.pause();});
}
};
dbbtn.onclick = function() {
x = "deepblue";
AudioFF();
};
swbtn.onclick = function() {
x = "spacewalk";
AudioFF();
};
fbtn.onclick = function() {
x = "forest";
AudioFF();
};
drbtn.onclick = function() {
x = "dreamrhythm";
AudioFF();
};
My idea was to use the same class of a button as an id for the container who needs to fade in with a string. The button has e.g. the class btn_a, btn_b … etc. The containers has the id btn_a, btn_b … I wanted the script to catch the class of the button and use this classname as a variable for getElementById. The closebutton is also using the same script to close the container. Thanks for help :-)
I will recommend to use data attribute instead
example like this:
//register listener like this
var btns = document.querySelectorAll('[data-music]');
btns.forEach(function(elm) {
elm.addEventListener('click', function(e) {
//your function
console.log(this.dataset.music);
})
})
<!--your links-->
<div id="m1"></div>
<div id="m2"></div>
<div id="m3"></div>
<!--just add data-music attribute make it the same with your div id and all set-->
<button data-music="m1">play m1</button>
<button data-music="m2">play m2</button>
<button data-music="m3">play m3</button>
You should be able to set a data tag attribute to the buttons and just read the variable from that:
<button id="myButton" data="variableForMyButton" />
document.getElementById(myButton).onClick = function(e){
x = e.target.getAttribute('data')
}
If multiple params are required you add additional data tags:
<button id="myButton" data="variableForMyButton" data-action="someSweetAction" />
Thanks guys, that was what I was looking for. My function is now like this:
The play button and closebutton are working.
<button data-music="m1">Deep Blue</button>
<div id="m1">Container Content</div>
var btns = document.querySelectorAll('[data-music]');
btns.forEach(function(elm) {
elm.addEventListener('click', function(e) {
//function
var FFplayer = document.getElementById((this.dataset.music));
if (FFplayer.classList.contains("audio-hidden")) {
FFplayer.classList.remove("audio-hidden");
FFplayer.classList.add("audio-shown");
} else {
FFplayer.classList.remove("audio-shown");
FFplayer.classList.add("audio-hidden");
Array.prototype.slice.call(document.querySelectorAll('audio')).forEach(function(audio) {audio.pause();});
}
})
})
And here in jquery. Thanks to you all. You show me the way :-)
jQuery (document).ready(function($){
var btns = $('[data-music]');
$(btns).each(function() {
$('[data-music]').on('click', function(e) {
var FFplayer = $(this).data('music');
$("#" + FFplayer).toggleClass("audio-hidden audio-shown");
});
});
})

Loop through element and change based on link attribute

Trying to figure this out. I am inexperienced at jQuery, and not understanding how to loop through elements and match one.
I have 3 divs:
<div class="first-image">
<img src="images/first.png">
</div>
<div class="second-image">
<img src="images/second.png">
</div>
<div class="third-image">
<img src="images/third.png">
</div>
And off to the side, links in a div named 'copy' with rel = first-image, etc.:
...
Clicking the link will fade up the image in the associated div (using GSAP TweenMax)
Here is the function I've been working on to do this... but I am not fully understanding how to loop through all the "rel" elements, and make a match to the one that has been clicked on.
<script>
//pause slideshow on members to ledger when text is clicked, and show associated image
$(function() {
$('.copy').on('click','a',function(e) {
e.preventDefault();
var slideName = $(this).attr('rel');
$("rel").each(function(i){
if (this.rel == slideName) {
console.log(this);
}
});
//var change_screens_tween = TweenMax.to('.'+slideName+'', 1, {
//autoAlpha:1
//});
});
});
</script>
What am I doing wrong? I don't even get an error in my browser. :-(
Thanks to the answer below, I got farther. Here is my revised code.
$('[rel]').each(function(k, v){
if (v == slideName) {
var change_screens_tween = TweenMax.to('.'+slideName+'', 1, {
autoAlpha:1
});
} else {
var change_screens_tween = TweenMax.to('.'+slideName+'', 1, {
autoAlpha:0
});
}
});
});
This is starting to work, but makes the screenshots appear and then instantly fade out. And it only works once. Any thoughts?
Add brackets around rel, like so:
$('[rel]').each(function() {
if ($(this).attr('rel') == slideName) {
console.log(this);
}
});

HTML/jQuery Limit no. of divs in container

(firstly I recommend seeing the related image)
I have 3 container having same class .container. Also, user can add child divs dynamically into the containers. The user will start adding divs (that is .parent) by clicking '.add' div inside each '.parent'.
The containers can have at max 3 div. If the user has added 3 divs already then the next div should go in the second container and so on. Once the last container(the third one) is full, an alert should pop up saying "You cannot add anymore divs."
I have two questions:
Using jquery how can I limit the number of '.parent' divs per container to 3. If the user tries to add another it is added to container 2 (unless container 2 has 3 child divs, then it would go to container 3)?
Once the container of page 3 is full (3 divs) an alert should pop up saying "You cannot add anymore divs".
The only snippet of code that I have is not working. Please help me with the code. I am novice in all this stuff.
Thanks in advance.
Related image: [1]: http://i.stack.imgur.com/zi78d.png
Sample code:
<html>// the containers
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>//divs that are supposed to be appended
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>. . .
</html>
.
<script>
var $pages = $('.container');
var child = '$('.add ').parent()';
$(".add").on('click', function () {
var childAdded = false;
$pages.each(function () {
var $container = $(this);
if ($container.children().length < 3) {
$container.append.('child');
childAdded = true;
return false;
}
});
if (!childAdded) {
alert("You can not add any more divs");
}
});
</script>
Several problems in your code
You want the instance of the parent class when you click on the button, not all .parent
You have syntax errors using quotes around jQuery objects that shouldn't be there.
Here's a simple approach using filter() method.
$(".add").on('click', function () {
/* filter $pages down to first available one with space */
var $page=$pages.filter(function(){
return $(this).children().length < 3;
}).first();
if( !$page.length ){ /* if no elements returned from filter, they are all full */
alert("You can not add any more divs");
}else{
/* get instance of parent based on button that was clicked which is "this" */
var $parent=$(this).closest('.parent');
$page.append( $parent );
}
});
DEMO
filter() API docs
You have to track the amount of divs you have added yourself. Then, use this information to determine which .container you should put it in. Something like this:
var added = 0;
...
$(".add").on('click', function () {
var target;
if(added<3) {
target = $pages[0];
} else if (added<6) {
target = $pages[1];
} else if (added<9) {
target = $pages[2];
} else {
alert("You can not add any more divs");
return
}
$(target).append($(this).parent());
added += 1;

Keeping buttons in place when using .hide()

Not sure if this is because I'm new to meteor or if I am making an error in my syntax with my HTML or jQuery. Ideally I would like the whole grid to stay in place when a button is clicked. For example if you clicked the button in the middle of the grid there would be a empty spot where that button was before. My question is, why is it that when I click a button the button disappears but moves the whole grid and what do I do to fix this?
HTML:
<head>
<title>bubblepopper</title>
</head>
<body>
<center>{{> grid}}</center>
</body>
<template name ="grid">
<div id="container">
{{#each buttons}}
<button class="button" type="button"></button>
{{/each}}
</div>
</template>
JS:
Buttons = new Meteor.Collection("buttons");
if (Meteor.isClient) {
player = prompt("What is your name?")
Template.grid.buttons = function () {
}
Template.grid.buttons = function () {
var list = [];
for(var i=1; i<=64; i++){
list.push({value: i});
}
return list;
};
Template.grid.events({
'click .button': function(ev) {
$(ev.target).hide()
}
});
}
if (Meteor.isServer) {
}
.hide() works by adding the style display: none to the element. This removes the space used by the element in the rendered page.
If you want to make something invisible but keep its space on the page, use the visibility style:
$(ev.target).css('visibility', 'hidden');
To restore it, set the visibility to visible.

Categories

Resources