Simple image rotation with pure javascript, no jQuery - javascript

trying to come up with very simple image rotation using pure javascript without jQuery.
Something that I could call like that and it could place the image in same spot rotating it one by one.
rotator('<img src="image1.gif"/ >','<img src="image1.gif"/ >');
maybe someone could suggest a way of doing it? thank you.
UPDATE: By Rotation I meant, one disappears, another appears. Not angle rotation.

This sort of steps beyond the call of duty and probably isn't the best solution but nonetheless. A full Javascript function (handles by tag not by image)
<html>
<head>
<script>
/*rotate
desc: Rotate a set of first level child objects based on tag name
params:
id = Rotate elements container id
tag = Tag (nodeName - see textNode issue) of DOM objects to be cycled
*/
function rotate(id, tag)
{
/*Normalise string for later comparison*/
tag = tag.toLowerCase();
/*Get container DOM Object*/
var el = document.getElementById(id),
visibleIdentified = false;
hasBeenSet = false,
firstMatchingChild = false;;
/*Iterate over children*/
for(i = 0; i < el.childNodes.length; i++){
/*Set child to var for ease of access*/
var child = el.childNodes[i];
/*If element has the correct nodeName and is a top level chlid*/
if(child.parentNode == el && child.nodeName.toLowerCase() == tag){
/*Set first matching child in case the rotation is already on the last image*/
if(!firstMatchingChild)
firstMatchingChild = child;
/*If child is visible */
if(child.style.display == "block"){
/*Take note that the visible element has been identified*/
visibleIdentified = true;
/*Toggle its visibility (display attribute)*/
child.style.display = "none";
/*Once the visibile item has been identified*/
}else if(visibleIdentified){
/*If the next item to become visible has been set*/
if(hasBeenSet){
/*Toggle visibility (display attribute)*/
child.style.display = "none"
}
/*Catch the next item to become visible*/
else{
/*Toggle visibility (display attribute)*/
child.style.display = "block";
/*Take note that the next item has been made visible*/
hasBeenSet = true;
}
}
}
}
/*If the hasBeenSet is false then the first item is to be made visible
- Only do so if the firstMatchingChild was identified, more or less redundant
exception handling*/
if(!hasBeenSet && firstMatchingChild)
firstMatchingChild.style.display = "block";
}
/*Declare cycle*/
setInterval("rotate('test','div')",1000);
</script>
</head>
<body>
<!-- Example container -->
<div id="test">
<div style="display:block">fire</div>
<div style="display:none">water</div>
<div style="display:none">shoe</div>
<div style="display:none">bucket</div>
</div>
</body>
</html>

Your specific question I haven't seen before, but your basic premise has been asked many times. The reason why you can't find a call like
rotate('<img src="1" />', '<img src="2" />');
is because it is a bad idea according to programming practices. You are mixing content with script. Client-side web design relies on sandboxing certain features to speed development and make debugging easier. Content, Styling and Scripting are the major areas. Here you mix content (images) with scripting. You should really use one of the many existing image rotation scripts that rely on taking existing markup and rotating them.
<img src="a" />
<img src="b" />
<script>rotateImages();</script>
If you want to do it your way then you will need to parse your strings and then create element nodes based on them. Honestly I don't think its worth the time to code one up in that format unless this is for curiosity's sake.

I am going to answer my own question as I came up with solution by my own. Sorry if I did not explain well and I hope it could be useful to someone as well. I had to avoid jQuery for a special reason, sometimes its just has to be that way. Here is the code, feel free to comment and improve... a working version is here http://jsbin.com/oxujuf/3
function rotator(options) {
var a = options.delay;
var b = options.media;
var mediaArr = [];
for(var i = 0, j = b.length; i < j; i++) {
mediaArr.push(b[i].img);
}
document.write('<div id="rotatorContainer"></div>');
var container = document.getElementById('rotatorContainer');
var Start = 0;
rotatorCore();
function rotatorCore() {
Start = Start + 1;
if(Start >= mediaArr.length)
Start = 0;
container.innerHTML = mediaArr[Start];
setTimeout(rotatorCore, a);
}
}
And then later you may call it like that, with a simple API.
rotator({
delay : 3500,
media : [{
img : '<img src="http://lorempixel.com/output/abstract-h-c-149-300-7.jpg" width="149" height="300" border="0" />'
}, {
img : '<img src="http://lorempixel.com/output/abstract-h-c-149-300-2.jpg" width="149" height="300" />'
}]
});

This is covered on many older forums and blogs.
Here are a couple links:
http://www.go4expert.com/forums/showthread.php?t=1012
http://www.reachcustomersonline.com/2008/03/19/09.38.04/?doing_wp_cron=1326819656

Related

How to reoder video tiles in Jitsi?

Last year, I wrote a bookmarklet that allowed to reorder Jitsi video tiles in alphabetic order.
Unfortunately, the script does not seem to work with the recent Jitsi versions anymore.
I have already adjusted the access to the required elements, this is working fine again.
However, the order: n attribute of the elements is ignored know, even when I set the parent to display:flex, remove the position: absolute and the left|top:n px.
I played around with the CSS and looked into documentation, but given I am no frontender, I am currently stuck.
How can I change the CSS, so that the tiles are reordered?
As a clarification, I am only looking for where I need which changes in the CSS, no scripted solution. I can take care of the scripting. Achieving a swap of two video tiles while not breaking the look would be sufficient probably.
The below information are not necessary, but might be helpful to answer the question.
Below is a screenshot showing the position in the DOM tree:
DOM tree leading to the video tiles (seems I need more reputation to embed the image)
And here is the the javascript that allows to directly access the elements:
var numberOfVideos;
function getNumberOfParticipants(){
// works
}
function getNameOfParticipant(i){
var container = $('#remoteVideos')[0];
var jChildren = $(container).children();
var jChildren2 = jChildren[1].firstChild.children;
return [jChildren2[i].getElementsByClassName("displayname")[0].innerHTML, jChildren2[i] ];
}
function sortParticipants(){
numberOfVideos = getNumberOfParticipants();
var names = new Array();
//only applicable in tiles mode!
for(i=0; i<numberOfVideos; i++) {
names[i] = new Array (2);
names[i] = getNameOfParticipant(i);
}
//sort Array
names.sort((a, b) => a[0].localeCompare(b[0]));
//reorder the tiles
for(i = 0; i < numberOfVideos; i++){
$(names[i][1]).css('order', i); //this is the line that worked in 2021, but the `order` attribute is now being ignored
}
}
https://github.com/kaiyazeera/jitsi-bookmarklets/blob/master/alphabeticSort-auto0.js
The problem could be solved by modfying the global CSS:
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = ".videocontainer { position:relative !important; top: unset !important; left: unset !important; text-align:center;overflow:hidden; }"
var css2 = document.createElement("style");
css2.type = "text/css";
css2.innerHTML = ".tile-view .remote-videos > div {flex-wrap:wrap;}"
document.body.appendChild(css)
document.body.appendChild(css2)

Assigning string to div value from javascript function across pages

I have a web app that outputs the results of a function as a double. The function compares two text documents and returns the percentage indicating the percentage of similarity between the two documents. When the user clicks a Compare button, the function runs and takes the user from the compare.jsp page to the results.jsp page, and displays a loading-bar that is filled in like so:
<div id="levenshtein-distance"
class="ldBar label-center levenshtein-distance"
data-preset="fan"
data-value="${result.percentage}"
data-stroke="">
</div>
This works fine, the fan bar gets the correct percentage. However, I am also trying to color the fan bar using the data-stroke value based on this percentage. I have a simple javascript function to do this, but can't figure out how to pass the value. I've tried running the function in the body tag of the results.jsp page using "onload", but this doesn't work. Here is my JavaScript function:
function barSetLD(percent) {
var red = "red";
var green = "green";
var orange = "orange";
var elem = document.getElementById("levenshtein-distance");
if (percent <= 40.00) {
elem.setAttribute("data-stroke", green);
} else if (percent > 40.00 && percent <= 70.00) {
elem.setAttribute("data-stroke", orange);
} else {
elem.setAttribute("data-stroke", red);
}
}
I've done quite a bit of searching and can't seem to find an example that helped me solve this. Any help is very much appreciated.
////Update:
Trinh, that worked to change the color, thanks! My problem now is that I do, in fact, have multiple 'levenshtein-distance' ids and I am looping through them. So currently everything is being set to the same color. I should have mentioned this initially, sorry. I am comparing multiple pairs of files and outputting the loading-bar for each pair. If you have some idea about how to resolve the looping issue, that would be great, but thanks for the original solution either way! I updated my javascript function as follows:
function barSetLD(percent) {
var red = "red";
var green = "green";
var orange = "orange";
var elem = document.querySelectorAll("[id^=levenshtein-distance]");
for (var i in elem) {
if (percent <= 40.00) {
elem[i].setAttribute("data-stroke", green);
} else if (percent > 40.00 && percent <= 70.00) {
elem[i].setAttribute("data-stroke", orange);
} else {
elem[i].setAttribute("data-stroke", red);
}
}
}
And the full bit of code with the html loop is, and I am now calling the barSetLD(percent) at the very bottom of the page as you suggested:
<c:forEach items="${studentResults}" var="result" varStatus="loop">
<div id="levenshtein-distance"
class="ldBar label-center levenshtein-distance"
data-preset="fan"
data-value="${result.percentage}">
</div>
</c:forEach>
<script type="text/javascript">
barSetLD("${result.percentage}");
</script>
Put your code at the very bottom of the page where all DOM has been loaded. Or at least make sure <div id="levenshtein-distance"/> exist and fully loaded before calling this document.getElementById("levenshtein-distance");. Also double check if you have multiple levenshtein-distance id...

Generate array of image in javascript inside <div>

I need to make the background image in div tag and it has to change automatically, I already put the array of images inside the javascript, but the images is not showing when i'm run the site.The background should behind the menu header.
This is the div
<div style="min-height:1000px;position:relative;" id="home">
below of the div is containing the logo, menu and nav part.
<div class="container">
<div class="fixed-header">
<!--logo-->
<div class="logo" >
<a href="index.html">
<img src="images/logo.png" alt="logo mazmida" height="142" width="242">
</a>
</div>
<!--//logo-->
This is the javascript
<script>
var imgArray = [
'images/1.jpg',
'images/2.jpg',
'images/3.jpg'],
curIndex = 0;
imgDuration = 2000;
function slideShow() {
document.getElementID('home').src = imgArray[curIndex];
curIndex++;
if (curIndex == imgArray.length) { curIndex = 0; }
setTimeout("slideShow()", imgDuration);
}
slideShow();
You have a few issues with your script. I've made a live JSbin example here:
https://jsbin.com/welifusomi/edit?html,output
<script>
var imgArray = [
'https://upload.wikimedia.org/wikipedia/en/thumb/0/02/Homer_Simpson_2006.png/220px-Homer_Simpson_2006.png',
'https://upload.wikimedia.org/wikipedia/en/thumb/0/0b/Marge_Simpson.png/220px-Marge_Simpson.png',
'https://upload.wikimedia.org/wikipedia/en/a/aa/Bart_Simpson_200px.png'
];
var curIndex = 0;
var imgDuration = 1000;
var el = document.getElementById('home');
function slideShow() {
el.style.backgroundImage = 'url(' + imgArray[curIndex % 3] + ')';
curIndex++;
setTimeout("slideShow()", imgDuration);
}
slideShow();
</script>
There are a few issues with your script:
On the element since it's a div not an img, you need to set style.backgroundImage instead of src. Look at https://developer.mozilla.org/en-US/docs/Web/CSS/background for other attributes to related to background image CSS
Also it's document.getElementById
Optimizations
And you can use mod % trick to avoid zero reset
Use setInterval instead of setTimeout
Further optimzations
Use requestAnimationFrame instead of setTimeout/setInterval
I suggest getting familiar with your browser debugging tools which would help identify many of the issues you face.
document.getElementID('home').src = imgArray[curIndex]
You are targeting a div with an ID of home, but this is not an Image element (ie ,
But since you want to alter the background colour of the DIV, then you use querySelector using javascript and store it in a variable, then you can target the background property of this div (ie Background colour).
I hope this helps.
You are trying to change the src property of a div, but divs do not have such property.
Try this:
document.getElementById('home').style.backgroundImage = "url('" + imgArray[curIndex] + "')"
This changes the style of the target div, more precisely the image to be used as background.
As you want to change the background image of the div, instead of document.getElementID('home').src = imgArray[curIndex] use
document.getElementById("#home").style.backgroundImage = "url('imageArray[curIndex]')";
in JavaScript or
$('#home').css('background-image', 'url("' + imageArray[curIndex] + '")'); in jquery.
To achieve expected result, use below option of using setInterval
Please correct below syntax errors
document.getElementID to document.getElementById
.src attribute is not available on div tags
Create img element and add src to it
Finally use setInterval instead of setTimeout outside slideShow function
var imgArray = [
'http://www.w3schools.com/w3css/img_avatar3.png',
'https://tse2.mm.bing.net/th?id=OIP.ySEgAgJIlDQsIQTu_MeoLwHaHa&pid=15.1&P=0&w=300&h=300',
'https://tse4.mm.bing.net/th?id=OIP.wBAPnR04OfXaHuFI9Ny2bgHaE8&pid=15.1&P=0&w=243&h=163'],
curIndex = 0;
imgDuration = 2000;
var home = document.getElementById('home')
var image = document.createElement('img')
function slideShow() {
if(curIndex != imgArray.length-1) {
image.src = imgArray[curIndex];
home.appendChild(image)
curIndex++;
}else{
curIndex = 0;
}
}
setInterval(slideShow,2000)
<div style="position:relative;" id="home"></div>
code sample - https://codepen.io/nagasai/pen/JLKvME

Placing elements within a container div into an array - jQuery or JavaScript

I have a div that contains a number of Instagram images, produced by the instafeed.js plugin. After running the plugin, the resultant HTML looks like this:
<div id="instafeed">
<a><img /></a>
<a><img /></a>
<a><img /></a>
etc...
</div>
I am trying to find a way to load the contents of this div into an array; I believe that the easiest way would be to just take the tags, which is fine.
I'm pretty inexperienced with both JS and jQuery, which is why I'm having difficulty achieving this and I've not been able to find any forum posts that quite do what I'm hoping to achieve.
So far, all I'm trying to do is load the contents of the div into an array and print it back out to the document, which should (in my mind anyway) add the tags back into the HTML. I'm trying with both JavaScript and jQuery and having little success with either. I'd appreciate any thoughts:
JS:
var containerDiv = document.getElementById('instafeed');
var pics = containerDiv.getElementsByTagName('img');
console.log(pics); //Tells me at least that I have an array of img
for (var i = 0; i < pics.length; i++) {
document.write(pics[i]);
} //Seemingly does nothing
jQuery:
(I'm really sorry if this code is just all wrong, I really don't know jQuery very well at all)
$(document).ready(function() {
var pics = [];
$('#instafeed').find('img').each(function() {
pics.push($(this));
});
for (i = 0; i < pics.length; i++) {
console.log(pics[i]);
}
});
Any thoughts, tips or pointers would be much appreciated.
Edit:
Just to add a little background to my problem, to avoid causing any more confusion.
I'm trying to pull four random images from a user-specific Instagram feed for display on a website. instafeed.js can pull just four images and it can randomise the images, but Instagram itself always sends the four most recent images, so the plugin is just randomising the order of the same four pictures each time.
I'm trying to let the plugin send through every picture, which will go into the div instafeed. From here I want to load all of the contained images into an array so that I can randomly pick four images for display on the site.
JQuery code that you write is correct. Only you need the div where you need to put the images.
$(document).ready(function() {
var pics = [];
$('#instafeed').find('img').each(function() {
pics.push($(this));
});
for (i = 0; i < pics.length; i++) {
$('div#yourDiv').append(pics[i]);
}
});
See the line of the for()
You can extract only the SRC of the images and then make like you want
$('#instafeed').find('img').each(function() {
pics.push($(this).attr('src'));
});
console.log(pics); // returns an array of src.
Thank you to everyone who has tried to help me along with this. It turns out that the problem I was having stemmed from my query attempting to run before instafeed.js had been able to pull the images through from Instagram, and so there was nothing for it to find in the div. I've managed to fix this with a setTimeout.
For anyone who is interested, and just in case anyone else might come across this in future with a similar problem, here is my complete code (it's a little inelegant I'm sure, but I'm still a relative novice at JS.)
function snagImages() {
var pics = [];
$('div#instafeed').find('img').each(function() {
pics.push($(this).attr('src'));
});
reduceGallery(4, pics);
}
function reduceGallery(limit, pics) {
if (limit === undefined) {
limit = 4;
}
var gallery = [];
while (gallery.length < limit) {
var j = Math.floor(Math.random() * pics.length);
if ( gallery.indexOf(pics[j]) > -1) {
continue;
}
gallery.push(pics[j]);
}
displayPics(gallery);
}
function displayPics(gallery) {
for (var i = 0; i < gallery.length; i++) {
document.getElementById('gallery').innerHTML += '' + '<img src="' + gallery[i] + '" alt="Gallery Image" />' + '';
}
}
var userFeed = new Instafeed( {
options
});
userFeed.run();
setTimeout(function() { snagImages() }, 500);

Manipulating the correct <div> when there are two or more that have the same ID

I operate a phpBB forum, on which I have installed this Syntax Highlighter MOD. Today, I started working on a feature that will use two DIVs to make the code box appear in full screen on the page. The DIV on which the user clicks to load the box in full screen will always have the same ID, but the syntax highlighter has a DIV ID which is random each time the page is loaded. I am having an issue with the DIV on which the user clicks always loading the first instance of the code box in full screen, regardless of which version of the DIV the user clicks on.
If you are have a hard time understanding what I am saying, here is an ugly, but usable demo. To make the ugly orange box load in full screen, click on the blue image above it. Each blue image is in its own DIV, both of which have the ID 'first'. The first ugly orange box has the ID 'testDIV' and the second has the ID 'testDIV2'. The code is written in such way that the DIV of each ugly orange box should be determined based on the DIV of the button. While my code works for this, it only works to find the first orange box.
Here is the code that I wrote that forms the demo.
<!-- HTML div Guniea Pigs -->
<div id="first" align="right"><img src="http://cdn2.iconfinder.com/data/icons/metro-uinvert-dock/128/Full_Screen.png" height="24" width="24" onclick="toggleFullScreen()" id="viewToggleImg" style="cursor:pointer"></div>
<div id="testDIV">DIV 1</div>
<!-- Round 2 -->
<div id="first" align="right"><img src="http://cdn2.iconfinder.com/data/icons/metro-uinvert-dock/128/Full_Screen.png" height="24" width="24" onclick="toggleFullScreen()" id="viewToggleImg" style="cursor:pointer"></div>
<div id="testDIV2">DIV 2</div>
<!-- div Styling, to help us see our guinea pigs. -->
<style>
body{
background:#000;
}
#testDIV{
background:#F58B00;
max-height:100px;
}
#testDIV2{
background:#F58B00;
max-height:100px;
}
</style>
<!-- JavaScript that will control the way that the page behaves on page toggling. THIS IS WHAT IS MOST IMPORTANT! -->
<script>
function toggleFullScreen(){
var toggleDIV = document.getElementById("first"); // This stores the ID of the toggle DIV.
var testDIV = document.getElementById("first").nextElementSibling; // Since the div ID will fluctuate each time during page load, this will acquire it for us using the previous div in relation to it.
if (document.getElementById("viewToggleImg").src == "http://cdn2.iconfinder.com/data/icons/metro-uinvert-dock/128/Full_Screen.png")
{
// If we are in here, then we are toggling to full screen.
document.getElementById("viewToggleImg").src='http://cdn2.iconfinder.com/data/icons/metro-uinvert-dock/128/Exit_Full_Screen.png';
document.getElementById("viewToggleImg").style.marginRight ='20px';
toggleDIV.style.position = 'fixed';
toggleDIV.style.top = '0px';
toggleDIV.style.bottom = '0px';
toggleDIV.style.left = '0px';
toggleDIV.style.right = '0px';
toggleDIV.style.background = '#FFF';
toggleDIV.style.paddingTop = '10px';
testDIV.style.position = 'fixed';
testDIV.style.top = '44px';
testDIV.style.bottom = '1px';
testDIV.style.left = '1px';
testDIV.style.right = '1px';
testDIV.style.maxHeight = 'none';
}
else
{
// If we are in here, then we are toggling back to original page view.
document.getElementById("viewToggleImg").src='http://cdn2.iconfinder.com/data/icons/metro-uinvert-dock/128/Full_Screen.png';
document.getElementById("viewToggleImg").style.marginRight = '0px';
toggleDIV.style.position = 'static';
toggleDIV.style.background = 'none';
toggleDIV.style.paddingTop = '0px';
testDIV.style.position = 'static';
testDIV.style.maxHeight = '100px';
}
}
</script>
Could someone please offer some advice on how to resolve this issue?
The easiest way to fix this would be passing a reference to clicked element (viewToggleImg) using the this keyword:
onclick="toggleFullScreen(this)"
Then get the related elements through DOM traversal methods:
function toggleFullScreen(viewToggleImg){
var toggleDIV = viewToggleImg.parentNode;
var testDIV = toggleDIV.nextElementSibling;
And use those variables throughout your function. Updated pen
Though, I'd suggest using jQuery for easily doing such tasks in a non-obtrusive way and shimming compatibility with older browsers (nextElementSibling does not work for IE<9, in case you need/want to support it).
Though, you don't need jQuery for something so small that is already working, so here's the patched version using feature detection for nextElementSibling else the shim outlined in this answer:
function nextElementSibling( el ) {
do { el = el.nextSibling } while ( el && el.nodeType !== 1 );
return el;
}
function toggleFullScreen(viewToggleImg){
var toggleDIV = viewToggleImg.parentNode;
var testDIV = toggleDIV.nextElementSibling || nextElementSibling(toggleDIV);
//...
Pen & fullpage demo (tested in IE8)
Or with jQuery:
var testDIV = $(toggleDIV).next()[0];

Categories

Resources