Loop 3 images from my Div background-image Property - javascript

I have a code to loop images but based on an Img source, but how to improve it to make it work for the "background-image" property of a div?
HTML
<div id="section2"></div>
CSS
#section2 {
background-image: 'url(..images/banner1.jpg');
}
JAVASCRIPT
<script type = "text/javascript">
(function() {
var i = 1;
var pics = [ "images/banner1.jpg", "images/banner2.jpg", "images/banner3.jpg" ];
var el = document.getElementById('section2');
function toggle() {
el.src = pics[i];
i = (i + 1) % pics.length;
}
setInterval(toggle, 3000);
})();
</script>
Thanks in Advance :)

One way would be to use CSS classes instead of sources.
JS:
<script type = "text/javascript">
(function() {
var i = 1;
var classes = [ "bgd-1", "bgd-2", "bgd-3" ]; // adjusted
var el = document.getElementById('section2');
function toggle() {
el.className = classes[i]; // adjusted
i = (i + 1) % classes.length; // adjusted
}
setInterval(toggle, 3000);
})();
</script>
CSS:
#section2.bgd-1 {
background-image: url('..images/banner1.jpg');
}
#section2.bgd-2 {
background-image: url('..images/banner2.jpg');
}
#section2.bgd-3 {
background-image: url('..images/banner3.jpg');
}
Note:
Use el.className += ' ' + classes[i]; to append a class name instead of replacing all element classes.

Related

change background when refreshed, but responsive

i currently have this javascript code in my head tag which makes the background change every time the page is refreshed. it works great, however, i would like to have different "image sets" (1.png, 2.png, 3.png vs 1mini.png, 2mini.png, 3mini.png), one for the desktop version and another one for the mobile version. any idea on how to do this?
<script>
function changeImg(imgNumber) {
var myImages = ["images/1.png", "images/2.png", "images/3.png",
"images/1mini.png", "images/2mini.png", "images/3mini.png" ];
var imgShown = document.body.style.backgroundImage;
var newImgNumber =Math.floor(Math.random()*myImages.length);
document.body.style.backgroundImage = 'url('+myImages[newImgNumber]+')';}
window.onload=changeImg;
</script>
`You can go for some queries depending on your device viewport.`
function changeBg(){
var width = window.innerWitdh;
var myImages = ["images/1.png", "images/2.png", "images/3.png",
"images/1mini.png", "images/2mini.png", "images/3mini.png" ];
if(width > 1200){ // lets say here is a desktop
document.body.style.backgroundImage = 'url('+ myImages[1] +')';
}else if(width < 1200 && width > 700){ // some smaller device
document.body.style.backgroundImage = 'url('+ myImages[2] +')';
}else { // this can be mobile
document.body.style.backgroundImage = 'url('+ myImages[3] +')';
}
}
Working Example
function changeImg(imgNumber) {
var myImages = [{
isMobile: true,
image: "https://cdn.pixabay.com/photo/2016/04/15/04/02/water-1330252__340.jpg"
},
{
isMobile: false,
image: "https://images.pexels.com/photos/531880/pexels-photo-531880.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
},
{
isMobile: true,
image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTptDddyBZG4i4cycd6ZIBP2wT8PQKhihUqenZF7GpzlvTZuPghGQ"
},
{
isMobile: false,
image: "http://sfwallpaper.com/images/background-wallpaper-images-3.jpg"
}
];
var imgShown = document.body.style.backgroundImage;
var filteredArray = [];
if (isMobile()) {
filteredArray = myImages.filter(function(el) {
return el.isMobile == true;
});
} else {
filteredArray = myImages.filter(function(el) {
return el.isMobile == false;
});
}
var newImgNumber = Math.floor(Math.random() * filteredArray.length);
console.log("newImgNumber", newImgNumber);
document.body.style.backgroundImage = 'url(' + filteredArray[newImgNumber].image + ')';
}
function isMobile() {
var match = window.matchMedia || window.msMatchMedia;
if (match) {
var mq = match("(pointer:coarse)");
return mq.matches;
}
return false;
}
window.onload = changeImg;
You can use media query with different css class that could be use as a background.
#media screen and (max-width: 768px) {
.img1 {
background-image: url("1.jpg");
}
.img2 {
background-image: url("2.jpg");
}
}
.img1 {
background-image: url("3.jpg")
}
.img2 {
background-image: url("4.jpg");
}
And change shown classes with function.
So you have one function and it is responsive for window size without any additional methods - simply in css file.
EDIT:
<script>
function changeImg(imgNumber) {
var myImages = ["img1", "img2", "img3"];
var newImgNumber =Math.floor(Math.random()*myImages.length);
document.getElementByClassName(myImages[newImgNumber]).show();}
window.onload=changeImg;
</script>
And you put display:none; in your css file. So you show only background that was 'randomly' picked.
<html>
<div class='background'>
<div class="img1"/>
<div class="img2"/>
<div class="img3"/>
Something like that.
You can set the background image by checking if the device is mobile or desktop.
eg:
i currently have this javascript code in my head tag which makes the background change every time the page is refreshed. it works great, however, i would like to have different "image sets" (1.png, 2.png, 3.png vs 1mini.png, 2mini.png, 3mini.png), one for the desktop version and another one for the mobile version. any idea on how to do this?
<script>
function changeImg(imgNumber) {
var mobileImages =["images/1mini.png","images/2mini.png","images/3mini.png"];
var desktopImages = ["images/1.png", "images/2.png", "images/3.png"];
var imgShown = document.body.style.backgroundImage;
//this code will return true when device is mobile
if (navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i)) {
var newImgNumber =Math.floor(Math.random()*mobileImages.length);
document.body.style.backgroundImage =
'url('+mobileImages[newImgNumber]+')';
}else{
var newImgNumber =Math.floor(Math.random()*desktopImages.length);
document.body.style.backgroundImage =
'url('+desktopImages[newImgNumber]+')';
}
}
}
window.onload=changeImg;
</script>

How do I supplant jQuery's toggleClass method with pure JavaScript?

How can I turn this piece of jQuery code into JavaScript?
$('#element').click(function(){
$(this).toggleClass('class1 class2')
});
I have already tried the following pieces of code, but to no avail.
First one is:
var element = document.getElementById('element'),
classNum = 0; // Supposing I know that the first time there will be that class
element.onmousedown = function() {
if (classNum === 0) {
this.classList.remove("class1");
this.classList.add("class2");
classNum = 1;
}
else if (classNum === 1) {
this.classList.remove("class2");
this.classList.add("class1");
classNum = 0;
}
}
Second one is:
var element = document.getElementById('element'),
classNum = 0; // Supposing I know that the first time there will be that class
element.onmousedown = function() {
if (classNum === 0) {
this.className -= "class1";
this.classList += "class2";
classNum = 1;
}
else if (classNum === 1) {
this.classList -= "class2";
this.classList += "class1";
classNum = 0;
}
}
Any answer that doesn't suggest that I stick with jQuery will be greatly appreciated.
[EDIT]
I've tried all of your solutions, but haven't been able to get it right. I believe it's because I didn't state clearly that the element has multiple classes like so:
class="class1 class3 class4"
And what I want is basically to replace class1 with class2 and toggle between them.
Update:
In response to comments, classList.toggle is a pure javascript solution. It has nothing to do with jQuery as one comment implies. If there is a requirement to support old versions of IE then there is a shim (pollyfill) at the MDN link below. And this shim, if needed, is far superior to the accepted answer.
Using classList.toggle certainly seems like the simplest solution. Also see Can I Use classList for browser support.
element.onclick = function() {
'class1 class2'.split(' ').forEach(function(s) {
element.classList.toggle(s);
});
}
Run the snippet to try
box.onclick = function() {
'class1 class2'.split(' ').forEach(function(s) {
box.classList.toggle(s);
stdout.innerHTML = box.className;
});
}
/* alternative
box.onclick = function() {
['class1', 'class2'].forEach(function(s) {
box.classList.toggle(s);
stdout.innerHTML = box.className;
});
}
*/
.class1 { background-color: red;}
.class2 { background-color: blue;}
.class3 { width: 100px; height: 100px; border: 1px black solid;}
click me:
<div id="box" class="class1 class3"></div>
<div id="stdout"></div>
classNum is a local variable.
Every time the event handler is called, you get a new variable, which has nothing to do with the value from the last call.
You want that to be a global variable.
Or, better yet, check classList.contains instead.
From: You might not need jQuery
$(el).toggleClass(className);
Is replaced by:
if (el.classList) {
el.classList.toggle(className);
} else {
var classes = el.className.split(' ');
var existingIndex = classes.indexOf(className);
if (existingIndex >= 0)
classes.splice(existingIndex, 1);
else
classes.push(className);
el.className = classes.join(' ');
}
Then simply wrap that function call within a document.getElementById('elementId').click
See fiddle: https://jsfiddle.net/2ch8ztdk/
var s = document.getElementById('element');
s.onclick=function(){
if(s.className == "class1"){
s.className = "class2"
} else {
s.className = "class1"
}
}
Your code is close, but your classNum variable isn't iterative. Try this:
var element = document.getElementById("element");
var numCount = 0;
element.addEventListener('click', function() {
if (numCount === 0) {
this.className = "";
this.className += " class1";
numCount++;
} else {
this.className = "";
this.className += " class2";
numCount = 0;
}
});
.class1 {
color: red;
}
.class2 {
color: blue;
}
<div id="element">click me</div>
you can use classList, but it only support IE 10+
Demo
var eles = document.querySelectorAll('#element');
var classNames = 'one two';
for(var i = 0; i < eles.length; i ++){
eles[i].onclick = function(e){
toggleClass.call(this, classNames);
}
}
function toggleClass(names){
var sp = names.split(' ');
for(var i = 0; i < sp.length; i++){
this.classList.toggle(sp[i]);
}
}
UPDATED MY ANSWER TO SUPPORT MULTIPLE CLASSES PER ELEMENT
https://jsfiddle.net/pwyncL8r/2/ This will now allow the element to already have n classes and still swap only one, retaining the other classes.
HTML
<div id="div1" style="width: 100px; height: 100px;" class="backBlack left100"</div>
<input type="button" id="swapButton" value="Css Swap" />
CSS
.backBlack {
background-color: black;
}
.backRed {
background-color: red;
}
.left100 {
margin-left: 100px;
}
JS
swapButton.onclick = function() {
var curClassIsBlack = (' ' + document.getElementById("div1").className + ' ').indexOf(' backBlack ') > -1
if (curClassIsBlack) {
document.getElementById("div1").className =
document.getElementById("div1").className.replace(/(?:^|\s)backBlack(?!\S)/g, '')
document.getElementById("div1").className += " backRed";
} else {
document.getElementById("div1").className =
document.getElementById("div1").className.replace(/(?:^|\s)backRed(?!\S)/g,'')
document.getElementById("div1").className += " backBlack";
}
}

Fade In only; not Fade Out - pure Javascript

I have the following code that fades in and out three objects, as see here...
http://ryanspahn.com/movies/testing.html
The code that drives that animation is pure JS and is seen below. Though I do not want it to cycle through and only want each object to fade in/stay visible on the page. Any idea how to change the below to do that?
var feedArr = Array("<img src='https://thingiverse-production-new.s3.amazonaws.com/renders/16/04/2d/b5/ed/smiley_face_thumb_small.jpg'>","<img src='http://www.mpaart.org/wp-content/uploads/2015/07/twitter-logo-round-50x50.png'>");
var tweetCount = 0;
function fadeOut(id,val){
if(isNaN(val)){ val = 9;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val>0){
val--;
setTimeout('fadeOut("'+id+'",'+val+')',90);
}else{return;}
}
function fadeIn(id,val){
if(isNaN(val)){ val = 0;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val<9){
val++;
setTimeout('fadeIn("'+id+'",'+val+')',90);
}else{return;}
}
function toogleFeeds(interval,val){
var realIntravel=interval
if(isNaN(val)){ val = 0;}
if(val == 0){
fadeOut('twitterFeed');
val=1;
realIntravel=1000;
}else{
document.getElementById('twitterFeed').innerHTML = feedArr[tweetCount];
tweetCount++;
if(tweetCount >= feedArr.length){ tweetCount = 0;}
fadeIn('twitterFeed');
val=0;
}
setTimeout('toogleFeeds("'+interval+'",'+val+')',realIntravel);
}
You can do something like this-
Of course this is only for 1 element, you can use same technique for multiple elements using class selectors or whatever.
The JS will look like this:
var val = 0;
var myInterval
function fadeIn() {
var id = "fadeInOnly";
var ele = document.getElementById(id);
ele.style.opacity = '0.' + val;
//For IE
ele.style.filter = 'alpha(opacity=' + val + '0)';
if (val < 9) {
val++;
} else {
clearInterval(myInterval);
return;
}
}
function setFade(){
myInterval = setInterval(fadeIn, 50);
}
The HTML:
<body onload="setFade();">
<div id="feedWrapper">
<img id="fadeInOnly" src='https://thingiverse-production-new.s3.amazonaws.com/renders/16/04/2d/b5/ed/smiley_face_thumb_small.jpg'>
</div>
fiddle example

Init an array using contents of spans

I have no Idea how to init my banner array with the text inside my spans. Do you have any Idea? Better to use javascript or JQuery?
<script language="javascript" type="text/javascript">
var i = 1;
function fun() {
var banner = new Array();
//How to init array here from inner text of spans?
i++;
document.getElementById("img1").src = "slide/" + banner[i] + ".jpg";
if (i == 3) //here 2 is number of images i want to display in the slide show
{
i = 0;
}
}
setInterval("fun()", 4000);
</script>
<div class="imagesContainer" style="display:none;">
<span>
73defe4b-9819-4e12-b351-3813686e0c83.gif
</span>
<span>
4c2ed116-500d-42ad-8aa5-983bf214d5d3.png
</span>
</div>
You can use .map()
var i = 1;
function fun() {
var banner = $('.imagesContainer span').map(function () {
return $.trim($(this).text())
}).get();
//How to init array here from inner text of spans?
i++;
document.getElementById("img1").src = "slide/" + banner[i] + ".jpg";
if (i == 3) //here 2 is number of images i want to display in the slide show
{
i = 0;
}
}
setInterval("fun()", 4000);
jQuery(function () {
var i = 0;
var banner = $('.imagesContainer span').map(function () {
return $.trim($(this).text())
}).get();
function fun() {
//How to init array here from inner text of spans?
i++;
if (i == banner.length) {
i = 0;
}
$('#img1').attr('src', '//placehold.it/128/' + banner[i])
}
setInterval(fun, 1000);
})
PoC: Demo
Here's how you can do it using jQuery:
var banner = [];
$('.imagesContainer span').each(function() {
banner.push($(this).text());
});
// you can now use the banner array here

Need Help In Javascript Text Typer Effect

I have a javascript text typer code:
CSS:
body
{
background-color:black;
}
#writer
{
font-family:Courier;
font-size:12px;
color:#24FF00;
background-color:black;
}
Javascript:
var text = "Help Please, i want help.";
var counter = 0;
var speed = 25;
function type()
{
lastText = document.getElementById("writer").innerHTML;
lastText+=text.charAt(counter);
counter++;
document.getElementById("writer").innerHTML = lastText;
}
setInterval(function(){type()},speed);
HTML:
<div id="writer"></div>
I want to know how can i use <br> tag (skipping a line or moving to another line). I tried many ways but failed, I want that if I Typed My name is Master M1nd. and then i want to go on the other line how would i go?
I've made a jQuery plugin, hope this will make things easier for you. Here is a live demo : http://jsfiddle.net/wared/V7Tv6/. As you can see, jQuery is loaded thanks to the first <script> tag. You can then do the same for the other <script> tags if you like, this is not necessary but considered as a good practice. Just put the code inside each tag into separate files, then set appropriate src attributes in the following order :
<script src=".../jquery.min.js"></script>
<script src=".../jquery.marquee.js"></script>
<script src=".../init.js"></script>
⚠ Only tested with Chrome ⚠
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
jQuery.fn.marquee = function ($) {
function findTextNodes(node) {
var result = [],
i = 0,
child;
while (child = node.childNodes[i++]) {
if (child.nodeType === 3) {
result.push(child);
} else {
result = result.concat(
findTextNodes(child)
);
}
}
return result;
}
function write(node, text, fn) {
var i = 0;
setTimeout(function () {
node.nodeValue += text[i++];
if (i < text.length) {
setTimeout(arguments.callee, 50);
} else {
fn();
}
}, 50);
}
return function (html) {
var fragment, textNodes, text;
fragment = $('<div>' + html + '</div>');
textNodes = findTextNodes(fragment[0]);
text = $.map(textNodes, function (node) {
var text = node.nodeValue;
node.nodeValue = '';
return text;
});
this.each(function () {
var clone = fragment.clone(),
textNodes = findTextNodes(clone[0]),
i = 0;
$(this).append(clone.contents());
(function next(node) {
if (node = textNodes[i]) {
write(node, text[i++], next);
}
})();
});
return this;
};
}(jQuery);
</script>
<script>
jQuery(function init($) {
var html = 'A <i>marquee</i> which handles <u><b>HTML</b></u>,<br/> only tested with Chrome. Replay';
$('p').marquee(html);
$('a').click(function (e) {
e.preventDefault();
$('p').empty();
$('a').off('click');
init($);
});
});
</script>
<p></p>
<p></p>
Instead of passing <br> char by char, you can put a \n and transform it to <br> when you modify the innerHTML.
For example (http://jsfiddle.net/qZ4u9/1/):
function escape(c) {
return (c === '\n') ? '<br>':c;
}
function writer(text, out) {
var current = 0;
return function () {
if (current < text.length) {
out.innerHTML += escape(text.charAt(current++));
}
return current < text.length;
};
}
var typeNext = writer('Hello\nWorld!', document.getElementById('writer'));
function type() {
if (typeNext()) setInterval(type, 500);
}
setInterval(type, 500);
Also probably you'll be interested in exploring requestAnimationFrame (http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/), for your typing animation :)

Categories