I have a selection of HTML pages (Lets say 30) and I want to have a randomise button, so that when the button is pressed, it displays one of the 30 pages randomly.
Ive found several scripts around the net that seem to do the trick, however they seem a bit 'hacky' and was wondering what the simplest, cleanest solution to this is?
Thanks in advance!
if var arr was your array you could get a random value using this :
var value = arr[Math.floor(Math.random() * arr.length)];
This generates a random number between 0 and the length of your array.
You can then navigate to that url ...
window.location = value;
Update
Simple demo : http://jsfiddle.net/ESSAc/1/
Added a simple onclick attribute to a button :
<input type="button" onclick="runme()" value="Click Me!" />
to execute this function :
function runme() {
var arr = ["http://www.bbc.co.uk/", "http://www.yahoo.com/", "http://www.stackoverflow.com/"];
var value = arr[Math.floor(Math.random() * arr.length)];
alert("Would navigate to : " + value);
// window.location = value; // remove the comment at the beginning to actually navigate
}
I don't know if it's 'hacky' or not, but I'd do it this way:
jQuery('#sumfin').onclick( function() {
jQuery.get(
'someurlthatreturnsjsonwitharandomurl.php',
{},
function (data) {
window.location = data.url;
},
'json'
);
}
Then just have an array of pages in a server-side script.
Related
I'm writing a choose your own adventure program where If a specific option is chosen (example to wait) the user gets a random number between 1-10 to do push ups(the push-ups would be the user clicking on the prompt "ok" button however many times the random number is equal to) here's my code so far but I keep getting errors. I'm a complete noob so go easy on me.
var count = Math.floor((Math.random() * 10) + 1);
var setsOf10 = false;
function pushUps() {
alert("Nice! Lets see you crank out " + pushUps + "!");
}
if (setsOf10 == pushUp) {
alert("Nice! Lets see you crank out " + pushUp + "!");
setsOf10 = true;
}
for (var i=0; i<count; i++){
pushUps();
}
else {
alert("Really, thats it? Try again");
}
while ( setsOf10 == false);
}
After playing with this some more I can tell i'm close but still don't have it. and again, I'M NOT ASKING YOU TO SOLVE THIS FOR ME JUST NEED POINTERS AS TO WHAT IM DOING WRONG OR MISSING. Here's what I have, Its giving me my random number I just need it to allow me to click the "ok" button however many times the random number has assigned me.
var pushUpSets = Math.floor((Math.random() * 10) + 1);
function pushUps(){
alert(pushUpSets);
if (pushUpSets < 3){
var weak = "Thats it? Weak sauce!";
alert(weak);
}
else{
alert("Sweet lets get some reps in!");
}
for (i=0; i>3; i++){
pushUps(pushUpSets);
}
}
Here, the make a choice button is just dummy to allow us to go to do push ups. Each click decrements our count.
// This is important, we use this event to wait and let the HTML (DOM) load
// before we go ahead and code.
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#choice').addEventListener('click', makeChoice);
});
function makeChoice() {
// Call a method to set random pushups and setup the click event
setUpPushUp();
// Here we change the display style of the push up section so that it shows to the player.
document.querySelector('.activity').style.display = 'block';
}
// The pushups variable is declared at the document level
// This way our setUpPushUp and doPushUp functions have easy access.
let pushUps = 0;
function setUpPushUp() {
// Create a random number of pushups, in sets of 10.
// We add an extra 1 so we can call the doPushUp method to initialize.
pushUps = (Math.floor((Math.random() * 10)+1)*10)+1 ;
// Add a click event to the push up button and call our doPushUp method on each click.
document.querySelector('#push').addEventListener('click', doPushUp);
// This is just an init call, it will use the extra 1 we added and place test in our P tag.
doPushUp();
}
function doPushUp() {
// Get a reference to our output element, we will put text to player here.
let result = document.querySelector('p');
// They have clicked, so remove a push up.
pushUps--;
// See if the player has done all the required push ups (i.e. pushUps is 0 or less.)
if (pushUps > 0) {
result.innerText = `You need to crank out ${pushUps} pushUps`;
} else {
result.innerText = 'Nice work!';
}
}
.activity {
display: none;
}
<button id="choice">Make a choice !</button>
<div class="activity">
<p></p>
<button id="push">Push</button>
</div>
So I've tried several things to fix this but nothing seems to work. it was working OKAY earlier but something happened and now I cant get it to display a random image from a JS array in the target div.
renamed all the image files so they had no spaces
edited document.getElementById("profPic").innerHTML = '<img src="'+imagesArray[num]+'">'; several times to no avail
Checked SO for solutions/work around but concluded it must be something to do with the file formatting that i am unaware of.
Tried putting displayImage(); in the div container. Also tried with document.write
var imagesArray = ["img/mascotImages/CCF2_(281).jpg", "img/mascotImages/CCF2_(282).jpg"];
function displayImage() {
var num = Math.floor(Math.random() * (imagesArray.length + 1));
document.getElementById("profPic").innerHTML = '<img src="' + imagesArray[num] + '">';
}
function myFunction(e) {
if ((e.target.id === 'mySearch' && e.keyCode === 13) || e.target.id === 'searchButton') {
e.preventDefault();
var searchValue = document.getElementById("mySearch").value;
for (var i = 0; i < users.length; i++) {
if (users[i]['last_name'] === searchValue) {
document.getElementById("usernameOut").innerHTML = (users[i].username);
document.getElementById("firstNameOut").innerHTML = (users[i].first_name);
displayImage();
return;
}
}
}
}
<div id="return">
<div id="profPic"></div>
<!--profPic-->
<div id="usernameOut"></div>
<!--usernameOut-->
<div id="firstNameOut"></div>
<!--firstNameOut-->
</div>
What is supposed to happen is that when the user searches something in a search box, data from another array is displayed in <div id="usernameOut"> and <div id="firstNameOut"> etc. I wanted a random picture to display also when the user clicked search/hit enter.
Is something wrong with the naming conventions of the files? are they in one too many folders? i'm sure this is something very simple, but it's had me staring at it for several hours.
Arrays indexes start with 0, not 1. Therefore, with only 2 images in your array, the max index should be 1. But your code Math.floor(Math.random() * (imagesArray.length+1)) can at times return 2.
Just get rid of the +1:
Math.floor(Math.random() * imagesArray.length)
I have a series of pages named "page-1" "page-2" "page-3" ..."page-99". Is there a way to make a navigation so that whenever I click the "next" button it goes to the next page, and if I click "previous" it will go to the previous page depending on what the current page number is. I was wondering if there is a javascript solution to this since I have never used PHP.
next <!--it will go to page-3-->
previous <!--it will go to page-1-->
This should get you started (starting with your original code).
$('a[class^=page]').click(function(e){
e.preventDefault();
var num = this.className.split('-')[1]; //2
var nav = $(this).attr('data-nav');
if (nav == 'next'){
num = parseInt(num)+1;
//window.location.href = "page-"+num+'.html';
}else{
num--;
//window.location.href = "page-"+num+'.html';
}
alert('Navigating to: [ page-' +num+ '.html ]');
});
a{padding:10px;border:1px solid #ccc;border-radius:5px;text-decoration:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
next <!--it will go to page-3-->
previous <!--it will go to page-1-->
Of course, this would be easier:
$('a[class^=page]').click(function(e){
e.preventDefault();
var num = this.className.split('-')[1]; //2
//window.location.href = "page-"+num+'.html'; //The "real" code
alert('Navigating to: [ page-' +num+ '.html ]'); //For demo purposes only
});
a{padding:10px;border:1px solid #ccc;border-radius:5px;text-decoration:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<a href="#" class="page-1" >next</a> <!--it will go to page-3-->
<a href="#" class="page-3" >previous</a> <!--it will go to page-1-->
And this would be easiest (using the file name):
//className *starts with* nav-
$('[class^=nav-]').click(function(e){
e.preventDefault();
var fileName = location.pathname.split("/").slice(-1);
var fileName = 'http://page-2.html'; //FOR DEMO ONLY
//alert(fileName); //should respond page2.html
var num = fileName.split('-')[1]; //2
var nav = this.className.split('-')[1]; //next
if (nav == 'next'){
num = parseInt(num)+1;
//window.location.href = "page-"+num+'.html';
}else{
num = parseInt(num)-1;
//window.location.href = "page-"+num+'.html';
}
alert('Navigating to: [ page-' +num+ '.html ]'); //For demo purposes only
});
a{padding:10px;border:1px solid #ccc;border-radius:5px;text-decoration:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<a href="#" class="nav-next" >next</a> <!--it will go to page-3-->
<a href="#" class="nav-prev" >previous</a> <!--it will go to page-1-->
You can do this with PHP or JS. But in either case you first need to be able to programmatically determine the page number of the currently displayed page.
You mention PHP, is this WordPress or some other similar CMS?
Okay so you mentioned that this is a basic website, but we still need to be able to pull that currentPageID. We could do this a few ways, the coolest would probably be to take it from the url, so let's do that.
To get the number from the url structure you mention in comments (hostname.com/page-1.html):
// Let's first grab the url and pull just the last segment, in case there are numbers anywhere else in the url.
var url = window.location.href;
var array = url.split('/');
var lastSegmentOfUrl = array[array.length-1];
// Next, let's regex that last segment for the first number or group of numbers
var reg = /\d+/;
var currentPageID = lastSegmentOfUrl.match(r); // That's it!
// Then some basic math to get the next and previous page numbers
var previousPageID = currentPageID - 1;
var nextPageID = currentPageID + 1;
// And finally we change the href values on the next and previous <a> elements
document.getElementById('previous').href('/page-' + previousPageID + '.html');
document.getElementById('next').href('/page-' + nextPageID + '.html');
This will keep working forever assuming your url structure stays the same insofar as the last segment only has the current page number and no other numbers, and also that the next and previous anchor tags ID's don't change.
Here is a method using location.pathname and String.prototype.replace, no extra templating required!
Update Includes check that page exists before fetching.
// Check that a resource exists at url; if so, execute callback
function checkResource(url, callback){
var check = new XMLHttpRequest();
check.addEventListener("load", function(e){
if (check.status===200) callback();
});
check.open("HEAD",url);
check.send();
}
// Get next or previous path
function makePath(sign){
// location.pathname gets/sets the browser's current page
return location.pathname.replace(
// Regular expression to extract page number
/(\/page\-)(\d+)/,
function(match, base, num) {
// Function to increment/decrement the page number
return base + (parseInt(num)+sign);
}
);
}
function navigate(path){ location.pathname = path; }
var nextPath = makePath(1), prevPath = makePath(-1);
checkResource(nextPath, function(){
// If resource exists at nextPath, add the click listener
document.getElementById('next')
.addEventListener('click', navigate.bind(null, nextPath));
});
checkResource(prevPath, function(){
// If resource exists at prevPath, add the click listener
document.getElementById('prev')
.addEventListener('click', navigate.bind(null, prevPath));
});
Note that this will increment the "page-n" portion of the path, even if you are in a sub-path. It will also work for non-html extensions.
E.g.,:
mysite.com/page-100/resource => mysite.com/page-101/resource
or
mysite.com/page-100.php => mysite.com/page-101.php
I'm trying to open build a system which opens a new link every time an anchor tag is clicked. I tried using random function but at times it opens the same link again and again. But whereas as I want the link to open in an order and follow the cycle.. That is if I have three links, the user clicking the anchor text first time will open the first link, then second, then third and later again the first link..
This means the link must change if a different user clicks.
Here is a code that I found which uses random function..
<script type="text/javascript'>
function random_3(){
var myrandom=Math.round(Math.random()*2)
var link1="http://www.codingforums.com"
var link2="http://www.cssdrive.com"
var link3="http://www.dynamicdrive.com"
if (myrandom==0)
window.location=link1
else if (myrandom==1)
window.location=link2
else if (myrandom==2)
window.location=link3
}
</script>
<form>
<input type="button" value="random link!" onClick="random_3()">
</form>
so can someone help me out with this?
I tried using random function but at times it opens the same link again and again
You're probably getting the same link several times in succession due to the random calculation that you're using.
Try the following instead:
var myrandom=Math.floor(Math.random()*3);
You should get a better distribution this way.
Now, regarding your original question, if you want a persistent state to be kept between page reloads, so that each time the link is different, you'll probably need to use cookies or localStorage for storing what was the last used index for that user.
Example:
var links = ['http://www.codingforums.com', 'http://www.cssdrive.com', 'http://www.dynamicdrive.com'];
function nextLink() {
var index = localStorage.getItem('lastPos') || -1;
index = (index + 1) % links.length;
localStorage.setItem('lastPos', index);
return links[index];
}
What you need to do is save the index of the link, and then increase it every time so that you cycle through the links in order.
Here's a working example of what you want:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<script>
urls = ['http://domain1.com','http://domain2.com', 'http://domain3.com', 'http://domain4.com'];
var urlIndex = 0;
function openUrl(){
url = urls[urlIndex % urls.length];
window.location = url;
urlIndex ++;
}
</script>
Get a link
</body>
</html>
Here's a demo :)
First of all, you have to list your links in an array. Second, you have to define a variable that hold the last opened link's index in that array, to void a successive opening of the same link (indeed it's a URL). In general you may follow something like the following code:
urls = ['http://domain1.com','http://domain2.com', 'http://domain3.com', 'http://domain4.com'];
var lastUrl = '';
function getRandomIndex(arr){
return Math.floor(Math.random() * ((arr.length+1) - 1));
}
function openUrl(){
url = urls[getRandomIndex(urls)];
do {
if (url == lastUrl){
url = urls[getRandomIndex(urls)];
}
else{
lastUrl = url;
//Using alert instead of window.location for testing
alert(url)
//window.location = url;
}
}
while (lastUrl != url);
}
Then for test:
Click here for test
This is an online Demo
Reference: Generating random whole numbers in JavaScript in a specific range?
Edit
According your comment, the requirement is pretty easier, instead of choosing according to random value, you will define lastUrl as an integer store and every time the openUrl() is called, it will be increased by 1 after checking its value if it is greater than urls array length or not as follows:
Modified openUrl
urls = ['http://domain1.com','http://domain2.com', 'http://domain3.com', 'http://domain4.com'];
//lastUrl Index in urls array
// Global variable
var lastUrl = 0;
function openUrl(){
if (lastUrl > (urls.length - 1)){
//reset it to 0
lastUrl = 0;
}
else{
url = urls[lastUrl];
lastUrl++;
alert(url)
//window.location = url;
}
}
var myrandom = 0;
function random_3(){
myrandom += 1;
var link1="http://www.codingforums.com";
var link2="http://www.cssdrive.com";
var link3="http://www.dynamicdrive.com";
if (myrandom==1)
window.open('http://www.codingforums.com','_blank');
else if (myrandom==2)
window.open('http://www.cssdrive.com','_blank');
else if (myrandom==3)
window.open('http://www.dynamicdrive.com','_blank');
else if (myrandom>3)
window.open('http://www.codingforums.com','_blank');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<form>
<input type="button" value="random link!" onClick="random_3()">
</form>
You can count click like user click on button and basis on this manage.
I have a javascript function that filter dom elements based on a input text changes, so:
$(".input").keyup(function(e) {
filter();
});
var cache = $(".dom");
var filter = function() {
cache.each(function() {
// if field contains some text show else hide
}
};
My problem happens when there are many dom elements to filter, the whole pages gets inaccessible because of the synchronous processing (like the example above). Im trying to come out with a solution that dont locks the entire page with synchronous processing.
The problem is NOT related to the filter logic (it's completely trivial), it's NOT related to the jquery or javascript itslef, it's related to the synchronous processing and the quantity of dom elements.
As JavaScript is single threaded, the only real way to sort this out is to split the long-running job into a series of shorter jobs, and use setTimeout() with a short time delay at the end of each section to kick off the next one. This gives your UI and other JavaScript events a chance to update.
You can update large set of dom nodes by placing them in a queue and process only a few elements on each setTimeout "tick". In pseudo-code:
on(event):
queue = DOM nodes to be updated
setTimeout(update)
update:
queue.slice(0, limit).each(...update a node...)
queue = queue.slice(limit) // remove processed nodes
if (queue.length > 0) setTimeout(update) // repeat...
See http://jsfiddle.net/Etsmm/2/ for a complete working example.
Upd: The first version had problems with Chrome (related to its' "display" bug), adding a fix as per this answer appears to have done the trick.
Or doing it elsewhere through an ajax request if's really too long ?
And, maybe, some kind of: first step, select all IDs to be hidden in an array, then, settimeout, then in a second step, hiding them like 50 per 50 ?
Also, maybe processing that having the container of all those elements himself hidden, and then, once done, reshowing it may be faster ?
For this kind of purposes I generally prefer Ben Alman's message queuing library. It has also different alternatives. This one is quite successful on throttling.
https://github.com/cowboy/jquery-message-queuing/
Here below a throttling sample
http://benalman.com/code/projects/jquery-message-queuing/examples/throttling/
thank you all for your help. I came up with a solution based on Ben Clayton response, but Im still looking for ideas and investigating the thg435 solution. Any comments will be apreciated.
<script type="text/javascript">
$(document).ready(function () {
var cache = $(".whatever");
var wait = 0;
var input = $("#input");
var regex = null;
input.keyup(function (e) {
go.index = 0;
clearTimeout(wait);
wait = setTimeout(go.start, 500);
});
var filter = function (i) {
var one = cache.eq(i - 1);
one.text().match(regex) ? one.show() : one.hide();
go.index++;
setTimeout(go.filter, 10);
};
go = {
index: 0,
filter: function () {
go.index == 0 || go.index > cache.length ? null : filter(go.index);
},
start: function () {
go.index = 1;
var search = input.val();
search = search.replace(new RegExp("[a]", "gi"), "[aàáâã]");
search = search.replace(new RegExp("[e]", "gi"), "[eéê]");
search = search.replace(new RegExp("[i]", "gi"), "[ií]");
search = search.replace(new RegExp("[o]", "gi"), "[oóô]");
search = search.replace(new RegExp("[u]", "gi"), "[uú]");
search = search.replace(new RegExp("[c]", "gi"), "[cç]");
regex = new RegExp(search, "gi");
go.filter();
}
}
});
</script>
<input type="text" id="input" />
<span class="whatever">lalala</span>
<span class="whatever">leléLÉ</span>
<span class="whatever">lololo</span>
<span class="whatever">lululu</span>