Below is a code I am running to display a pair of images each day. I have been unable to have it display the images randomly, but instead each day it selects the next image in the Array (not at random). Javascript is not my specialty and I have been unsuccessful in making it select a new random image in both arrays each day.
I have also been unsuccessful in making it select them every 12 hours instead of each day, which is what I would prefer it to do. It must display the same ones for every person who views it for that period, until the timer resets, if possible.
<script type="text/javascript"><!--
var imlocation = "https://s31.postimg.org/";
function ImageArray (n) {
this.length = n;
for (var i =1; i <= n; i++) {
this[i] = ' '
}
}
function linkArray (n) {
this.length = n;
for (var i =1; i <= n; i++) {
this[i] = ' '
}
}
image = new ImageArray(4);
image[0] = 'v85buoebv/Day2.png';
image[1] = 'djdl322kr/Evening2.png';
image[2] = 'arubcg423/Night2.png';
image[3] = 'xf9kiljm3/Morning2.png';
link = new linkArray(11);
link[0] = 'q4xda5xdn/CLOUDY.png';
link[1] = '7141ttkjf/Heavyrain.png';
link[2] = 'gzp0gatyz/lightrain.png';
link[3] = 'xc3njrxob/Medium_Rain.png';
link[4] = 'x0m770h8b/NO_WEATHER.png';
link[5] = 's38mlwf97/omgrain.png';
link[6] = 'btigj04l7/Special_Weather.png';
link[7] = 'b59m025vf/WEREALLGONNADIErain.png';
link[8] = 'ubmt38md7/Windy.png';
link[9] = 'x0m770h8b/NO_WEATHER.png';
link[10] = 'x0m770h8b/NO_WEATHER.png';
var currentdate = new Date();
var imagenumber = currentdate.getDay();
document.write('<div id="NOTICEME"><center><img src="' + imlocation + image[imagenumber] + '"><img src="' + imlocation + link[imagenumber] + '"></center><br><div id="mowords">[center][img]' + imlocation + image[imagenumber] + '[/img][img]' + imlocation + link[imagenumber] + '[/img][/center]</div></div>');
//--></script>
I used this code as a base to go on. But no matter how I toy with it, it won't give me a random image from the array. Also, the div ID "mowords" and "NOTICEME" is an ID I am using for CSS reasons that has nothing to do with this code.
Edit:
Maybe going for random is the wrong way to do this. Is there a way to make the link = new linkArray select the date (as in 1 - 31) and the image = new ImageArray select the day (as in 1 - 7) like it is currently doing? It will create variance and the illusion of randomness in the long run.
If you know your arrays' indices, and they are integers, then you can use the following to get a pseudo-random integer between min and max:
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
Now, however, your approach has been giving you certain "consistency" in your results, i.e. each day of the week giving you a certain image on every page show.
If you wish to implement randomness into it, you won't get such consistent results, meaning that on every page show, the image will be random independent of the day of the week or time of day.
To address this issue, you can take several approaches:
Have a server-side scripting language define the images (random or not) and save the "daily"/12-hour preferences into a .json/.js file, which then can be read by the JavaScript running in the browser. With this approach you would probably set the "refresh" rate via adding Expires headers on the .js file handling the parsing of the configuration file created by your server-side script -> https://gtmetrix.com/add-expires-headers.html
The other approach is to redefine your image selection logic based on the current date/time. However, the obvious downfall to that, is that you rely on the date and time of the user's computer, which can't always be trusted, so you have to work around that.
I would advise to look into a server-side scripting solution - PHP/Perl would do fine for this purpose.
UPDATED:
Have not tested, but try this (as per your comments):
<script type="text/javascript"><!--
var imlocation = "https://s31.postimg.org/";
function ImageArray (n) {
this.length = n;
for (var i = 0; i <= n; i++) {
this[i] = ''
}
}
function linkArray (n) {
this.length = n;
for (var i = 0; i <= n; i++) {
this[i] = ''
}
}
image = new ImageArray(6);
image[0] = 'v85buoebv/Day2.png';
image[1] = 'djdl322kr/Evening2.png';
image[2] = 'arubcg423/Night2.png';
image[3] = 'xf9kiljm3/Morning2.png';
image[4] = '';
image[5] = '';
image[6] = '';
link = new linkArray(30);
link[0] = 'q4xda5xdn/CLOUDY.png';
link[1] = '7141ttkjf/Heavyrain.png';
link[2] = 'gzp0gatyz/lightrain.png';
link[3] = 'xc3njrxob/Medium_Rain.png';
link[4] = 'x0m770h8b/NO_WEATHER.png';
link[5] = 's38mlwf97/omgrain.png';
link[6] = 'btigj04l7/Special_Weather.png';
link[7] = 'b59m025vf/WEREALLGONNADIErain.png';
link[8] = 'ubmt38md7/Windy.png';
link[9] = 'x0m770h8b/NO_WEATHER.png';
link[10] = 'x0m770h8b/NO_WEATHER.png';
link[11] = '';
link[12] = '';
link[13] = '';
link[14] = '';
link[15] = '';
link[16] = '';
link[17] = '';
link[18] = '';
link[19] = '';
link[20] = '';
link[21] = '';
link[22] = '';
link[23] = '';
link[24] = '';
link[25] = '';
link[26] = '';
link[27] = '';
link[28] = '';
link[29] = '';
link[30] = '';
var currentdate = new Date();
var dM = currentdate.getDate() - 1;
var dW = currentdate.getDay();
//var imagenumber = currentdate.getDay();
document.write('<div id="NOTICEME"><center><img src="' + imlocation + image[dW] + '"><img src="' + imlocation + link[dM] + '"></center><br><div id="mowords">[center][img]' + imlocation + image[dW] + '[/img][img]' + imlocation + link[dM] + '[/img][/center]</div></div>');
//--></script>
You use the function getDay() on the currentDate, therefore it will not change throughout a single day. Have a look at http://www.w3schools.com/jsref/jsref_getday.asp where you notice that its an integer from 0 to 6, and the week starts on sunday.
Therefore today (wednesday august 03 is 3) you should see image[3] and link[3]. Tomorrow you should get an error because you will reference outside of the image array i.e. image[4] will throw an index out of bounds exception.
Well, here goes my first answer here ever!
JavaScript is client-side code, so if the JavaScript code is what is determining the random number (rather than server-side code), you can't guarantee everyone accessing the site sees the same thing.
You could, however, use the date and time as a seed to generate what could appear random:
var btn = document.getElementById('btn');
btn.onclick = function () {
var d = new Date();
// getHours() results in an integer 0-23
var h = d.getUTCHours();
var chooser;
//Pick a multiplier based on the time of day.
if (h < 12) {
chooser = 1.15;
} else {
chooser = 1.87;
}
//Change upperLimit to whatever the upper limit of your array may end up being.
var upperLimit = 10;
//Generate the result
var pseudoRand = parseInt((d.getUTCFullYear() + d.getUTCMonth() + d.getUTCDay()) * chooser % upperLimit);
btn.textContent = pseudoRand;
}
Fiddle: https://jsfiddle.net/tapjzg94/
That code replaces the text of the button with an integer from 0 to upperLimit that should be the same for everyone who clicks on it, avoiding time zone issues with the UTC versions of the Date functions.
You could mix and match the date functions however you want, so long as they are all numbers that don't change on a rapid basis (year/month/date/day vs. minutes/seconds/milliseconds).
Related
I have this function that shows two random images picked from a folder. Is there any chance I can modify the code so that I won't have the same image twice as result?
Thanks in advance.
var theImages = new Array()
theImages[0] = 'img/dyptichs/f-1.jpg'
theImages[1] = 'img/dyptichs/f-2.jpg'
theImages[2] = 'img/dyptichs/f-3.jpg'
theImages[3] = 'img/dyptichs/f-4.jpg'
theImages[4] = 'img/dyptichs/f-5.jpg'
var j = 0
var p = theImages.length;
var preBuffer = new Array()
for (i = 0; i < p; i++){
preBuffer[i] = new Image()
preBuffer[i].src = theImages[i]
}
var WI1 = Math.round(Math.random()*(p-1));
var WI2 = Math.round(Math.random()*(p-2));
function showImage1(){
document.write('<img src="'+theImages[WI1]+'">');
}
function showImage2(){
document.write('<img src="'+theImages[WI2]+'">');
}
You can do something like this:
var WI1 = Math.round(Math.random()*(p-1));
var WI2 = Math.round(Math.random()*(p-1));
while (WI2 === WI1) {
WI2 = Math.round(Math.random()*(p-1));
}
We keep generating a new number until it's different from WI1, ensuring it is unique.
The way I'd personally handle that is to randomise the array and then just grab the first 2 entries. That way you still pick 2 at random, but you guarantee not to get the same 2.
var theImages = new Array()
theImages[0] = 'img/dyptichs/f-1.jpg'
theImages[1] = 'img/dyptichs/f-2.jpg'
theImages[2] = 'img/dyptichs/f-3.jpg'
theImages[3] = 'img/dyptichs/f-4.jpg'
theImages[4] = 'img/dyptichs/f-5.jpg'
var randomImages = theImages
.concat()
.sort(function () {
return Math.random() > 0.5
? 1
: -1;
})
.slice(0, 2);
function showImage1() {
document.write('<img src="' + randomImages[0] + '">');
}
function showImage2() {
document.write('<img src="' + randomImages[1] + '">');
}
Edit: including the original array for a complete solution
var WI1 = Math.floor(Math.random()*p);
var WI2 = Math.floor(Math.random()*(p-1));
if (WI2 >= WI1) {
WI2 += 1;
}
Use floor instead of round and subtract 1, because with round you get twice less chance to get first or last element.
The if trick is slightly better than a loop in this case, though the loop is easier to apply to a more complex case.
I am trying change iframe src automatically with java script. But it's works in randomly. I want this works on by order and also change milliseconds to minutes..!
var pages=new Array();
pages[0]="http://www.virtusa.com";
pages[1]="https://www.listertechnologies.com/";
pages[2]="https://intellectdesign.com/";
var time=600000; // this is set in milliseconds
function pageChange() {
var rand=Math.floor(Math.random()*pages.length);
document.getElementById("frame").src=pages[rand];
setTimeout("pageChange()",time);
}
onload=pageChange;
var pages = new Array();
pages[0] = "http://www.virtusa.com";
pages[1] = "https://www.listertechnologies.com/";
pages[2] = "https://intellectdesign.com/";
var index = 0;
var minute = 60000;
var time = 10 * minute;
function pageChange() {
var rand = pages[index];
document.getElementById("frame").src = rand;
setTimeout(pageChange, time);
index = index == pages.length - 1 ? 0 : index + 1;
}
onload = pageChange;
In past web development I have always tried to descend from an id when constructing a selector in javascript, previously in jQuery and more recently using document.querySelector()/.querySelectorAll(). This was for performance reasons. I was following advice in posts like this (http://www.artzstudio.com/2009/04/jquery-performance-rules/#descend-from-id).
For example:
$('#new-address-form input.address')
could be significantly faster than
$('.address')
Even when there was only one element on the page with a class of address. If there were a lot of different classes in the DOM, this could be a lot faster in some browsers (I'm looking at you IE<8).
But, experientially, it seems today that this is no longer the case. Can anyone point me to some documentation or code, for open-source browsers, that would confirm that modern browsers index elements by class?
The difference in performance is there, but it may not be significant unless you're working with a very large markup.
I setup a benchmark JS Fiddle that creates 20,000 div tags each nested 10 levels deep. Then attempts to select one at random based on class, and again based on ID with a descendant class.
I've benchmarked it here: https://jsfiddle.net/0wyLfnz8/14/
Results
Selecting by ID then descendant class was on average .018ms in Chrome
Selecting by ID then descendant class was on average 39.33ms in IE
Selecting by class alone was on average 12.178ms in Chrome
Selecting by class alone was on average 51.386ms in IE
Again, those results are in milliseconds with 500 tests over 20,000 HTML elements
Code for Benchmarking
$(document).ready(function() {
var d = new Date();
var st = d.getTime();
var start = st;
var et;
var max = 20000;
var numberOfTests = 500;
var elementDepth = 10;
for(var i = 1; i < max; i++) {
//lets make a random class too
r = Math.floor((Math.random() * 10) + 1);
var depth = "";
for(var j = 1; j<elementDepth;j++) {
depth += '<div class="depth' + j + '"></div>'
}
$('body').append('<div id="d'+i+'">'+depth+'<div class="depth'+elementDepth+'"><div class="c'+i+' r'+r+'">Hello, I am div number '+i+'</div></div></div>');
}
d = new Date();
var duration = d.getTime() - st;
console.log('Generating divs took ' + (duration/1000) + ' seconds');
idDuration = 0;
idTests = 0;
for(var i = 0; i < numberOfTests; i++) {
//choose a random div to select
r = Math.floor((Math.random() * max) + 1);
d = new Date();
st = d.getTime();
var tagbyID = $('#d'+r+ '.c'+r);
d = new Date();
et = d.getTime();
duration = et - st;
//console.log('Selecting by ID took ' + duration + ' milliseconds');
idDuration += duration;
idTests++;
}
console.log('---');
classDuration = 0;
classTests = 0;
for(var i = 0; i < numberOfTests; i++) {
//choose a random div to select
r = Math.floor((Math.random() * max) + 1);
d = new Date();
st = d.getTime();
var tagbyClass = $('.c'+r);
d = new Date();
et = et;
duration = d.getTime() - st;
//console.log('Selecting by class took ' + duration + ' milliseconds');
classDuration += duration;
classTests++;
}
console.log('---');
d = new Date();
console.log('total duration: ' + ((d.getTime() - start)/1000) + " seconds");
console.log('---');
console.log('Selecting by ID took '+idDuration+' milliseconds total over '+idTests+' tests.');
console.log('Selecting by class took '+classDuration+' milliseconds total over '+classTests+' tests.');
console.log('---');
console.log('Average time for ID selection using $(\'#parentID .childClassName\') was: ' + (idDuration / idTests)+" milliseconds")
console.log('Average time for class selection using $(\'.className\') was: ' + (classDuration / classTests)+" milliseconds")
})
I may have answered my own question. I created a jsperf, but I would value more test data or improvements.
http://jsperf.com/should-we-always-descend-by-an-id/6
EDIT: In my test case it looks like jQuery is actually faster when you DON'T descend from an id, but the clear performance winner (cross-browser) is document.getElementsByClassName().
I have a function that is supposed to add 10 random images to a div by generating a number at random. This is the function:
function Images()
{
clore();
var total = 133;
var gif = 3;
var name = "FileName";
var i = 0;
while (i < 10)
{
var num = random.nextInt(total - 1 + 1) + 1;
if(num > (total - gif))
{
var type = ".gif";
}else{
var type = ".jpg";
}
var elem = document.createElement("img");
elem.src = 'images/' + name + '/' + num + type;
document.getElementById("DIV").appendChild(elem);
i++;
}
}
clore() - Clears the innerhtml of the div
var total - the total number of ALL images in the folder
var gif - the total number of .gif images in the folder
var name - the name of the folder the images are in
The images are named 1 to 133, all of them are .jpg except the last three which are .gif.
So it goes: 1.jpg.....130.jpg then 131.gif.....133.gif .
I know the function is running because the clore function clears the div but nothing happens after that.
I also know I am not using any reserved terms as I have changed all of the names repeatedly?
The issue is the line where you have:
var num = random.nextInt(total - 1 + 1) + 1;
Instead it should be:
var num = Math.floor(Math.random() * total) + 1;
why is my function returning the same result?
I would like to input all the values from the “ping” function to an array and then output that array in html.
I run the function 3 times but all three times the result is the same. Can you tell me why?
(The domains are just an example by the way, cant put originals here)
var str = ' ';
var t=[];
var n= 2;
var arr = ["www.google.com","www.example.com","www.example2.com"];
var results = [];
var finalurl = '';
function fun1(){
for (var i=0; i < arr.length; i++){
str = "http://" + arr[i] + "/images/";
finalurl = str + "image-l.gif" + "?id=" + (new Date()).getTime();
ping(finalurl);
textt += results[i] + " ";
$(‘#ping’).html(textt);
}
}
var ping = function(finalurl) {
var l = 0;
t.push((new Date()).getTime());
if(t.length > n) {
p=t[2]-t[1];
results.push(p);
}
else {
var img = new Image;
$(img).load(function() {
ping();
}).attr('src', finalurl);
}
}
//small part of html:
<h2>run</h2>
<h1 id=“ping”> </h1>
This generates three urls (the length of arr) but only attempts to show two (the value of n). The urls are different each time, but you are limiting them in ping so the new ones are not used.
Try setting n to higher number, you will see it will load more images each click - as it currently stands it tries to load more in a single click (3) than it allows (2).
Note: even if those urls are different, the images may be the same, this happens if the server ignores the id parameter... which probably does as it requires additional configuration for the server to handle requests to a ".gif" resource (which is not a known servcer side scripting language) - by default the server will just return the resource image-l.gif.
By the way: At $(‘#ping’) those are the wrong quotes. Also textt is not defined - I did define it as var textt = ''; for my tests.