Home Events! Entrance Everyone Wiki Search Login Register

Welcome, Guest. Please login or register. - Thinking of joining the forum??
November 23, 2024 - @443.08 (what is this?)
Forum activity rating: Three Stars Posts: 31/1k.beats Unread Topics | Unread Replies | My Stuff | Random Topic | Recent Posts    Start New Topic
News: :happy: Open the all windows! Your mind needs storms and air! :happy:

+  MelonLand Forum
|-+  World Wild Web
| |-+  ✁ ∙ Web Crafting
| | |-+  ☔︎ ∙ I need Help!
| | | |-+  JS: Is there a simpler way to do this?


« previous next »
Pages: [1] Print
Author Topic: JS: Is there a simpler way to do this?  (Read 345 times)
JackFrost
Full Member ⚓︎
***


#MAYSGILLIAM2024

⛺︎ My Room

View Profile WWW

First 1000 Members!BUG!?!Joined 2022!
« on: October 05, 2024 @112.55 »

Hey, I need help with something JavaScript related. I use this script on multiple parts of my site, it grabs and displays a random image from a folder on my site and changes on reload. This makes it so a random image pops up every time you see it!
Is there a simpler/cleaner way to do this? Preferably with as little code as possible to make sure nothing goes wrong on lower end viewers, even without JavaScript perhaps? I just feel like this can't be THE easiest way to do this, it looks cluttered and messy.


* JS.PNG (74.14 kB, 1010x783 - viewed 26 times.)
Logged



Coffee addict, Gunpla builder, SMT fan.
Slix
Casual Poster ⚓︎
*


⛺︎ My Room

View Profile WWW

#1 Poliwag Fan !poliwag masterJoined 2024!
« Reply #1 on: October 05, 2024 @290.63 »

If you have access to PHP on your server, you could use a simple PHP script that gets a random image from a directory and use that in your code. An example I found is here: https://stackoverflow.com/questions/4478783/select-random-file-from-directory
Logged

ajazz
Casual Poster ⚓︎
*


⛺︎ My Room

View Profile WWW

Joined 2024!
« Reply #2 on: October 05, 2024 @515.63 »

bouncing off of @Slix, the cleanest way to do it would be to have the server just send you the list of all the paths in /images/fakeads and have the js load each one from that. that way it'd be totally automatic and you wouldn't have to edit anything on the client every time you add / remove an ad.

however, even aside from that it could be made a little cleaner on the eyes. for example:
Code
// var is basically totally phased out these days - use "let" for variables that you will change the value of and "const" for everything else
// further reading: https://medium.com/@darshan.unadkat/avoid-using-var-in-javascript-422394ed11a3
const imageURLs = [
  "xpango_banner_nintendo_wii.gif",
  "tumblr_2007b2855590c0c2f86701200737e24b_007bc878_400.png",
  "PS2FREE.gif",
  // ...the rest of the images
].map((basename) => `/images/fakeads/${basename}`); // `backticks` allow you to format strings easier!

function getImageTag() {
  const src = imageURLs[Math.floor(Math.random() * imageURLs.length)];
  // it's generally good for images to have an explicit width / height!
  // that way the browser can reserve the space for the image even before it's loaded
  const img = `<img width=${540} height=${75} src=${src} alt="A fake advertisement."/>`;
  const randomAd = document.querySelector(".yourdiv");
  randomAd.innerHTML = img;
}

// this makes it so the image only starts loading when the rest of the page is done loading
window.addEventListener("DOMContentLoaded", getImageTag);

also, document.write() is very powerful black magic and it is probably best to stay away. from mdn:
Quote
This method has very idiosyncratic behavior. In some cases, this method can affect the state of the HTML parser while the parser is running, resulting in a DOM that does not correspond to the source of the document (e.g. if the string written is the string "<plaintext>" or "<!--"). In other cases, the call can clear the current page first, as if document.open() had been called. In yet more cases, the method is simply ignored, or throws an exception. Users agents are explicitly allowed to avoid executing script elements inserted via this method. And to make matters even worse, the exact behavior of this method can in some cases be dependent on network latency, which can lead to failures that are very hard to debug. For all these reasons, use of this method is strongly discouraged. Therefore, avoid using document.write() — and if possible, update any existing code that is still using it.
Logged

hello, check out my website (silly) or My Website (serious)
xwindows
Casual Poster
*

⛺︎ My Room

View Profile

Joined 2024!
« Reply #3 on: October 05, 2024 @599.56 »

Preferably with as little code as possible to make sure nothing goes wrong on lower end viewers, even without JavaScript perhaps?
Yeah, don't inflict JavaS'creep on your viewer unless absolutely necessary.

If you are considering a server-side approach and have no special requirement regarding different on-page setup for each different diced image, it would be easiest to just hard-code the image reference in your HTML to point to a (server-side thingamajig). And let that thingamajig dice out an image for you--- usually via a HTTP 302 "Found" redirect to one of the actual image files.

I referred to that stuff as a (server-side thingamajig), because it could be many kind of server-side stuffs you can interchangeably use for this purpose; as I'll elaborate...



In case of PHP, @Slix already hinted about some part of it; but I will note that using PHP `rand()` like in examples linked there would usually leave (few-)first and (few-)last image(s) in the array underused-- because of imperfect randomness distribution of such pseudorandom algorithms. Using the max dicing range then modulo the result with total items would have a much better randomization result.

PHP example of server-side thingamajig with random-modulo and redirection approach I mentioned: `randomimage.php`...

Code
<?php
$images = array(
	"image1.jpg",
	"image2.jpg",
	"image3.jpg"
);
$target = $images[rand() % count($images)];
header("Location: ".$target, true, 302);
?>
Which would be called from HTML using a plain:

Code
<img src="randomimage.php" alt="Random picture">
This should work on any PHP version from 4 to 8. Tested on:
  • PHP 5.16.3 running under Apache 2.4 via its `mod_php`; CentOS GNU/Linux 7 x86-64.
  • PHP 8.2.24 running under Nginx 1.26.2 via PHP-FPM; Fedora GNU/Linux 39 x86-64.

Very terse and effective, right?



But if you got a distaste for PHP like me, and you were lucky enough to use a server that allow you to write a shell script CGI program (1), you might just dice stuff Quick&Dirty (TM) way with GNU `shuf` and a bit of here-document, then call it a day.

Shell script CGI example of server-side thingamajig: `randomimage.sh`...

Code
#!/bin/sh
echo "Status: 302"
echo "Content-Type: text/plain"
printf "Location: "
shuf -n 1 << 'EOF'
image1.jpg
image2.jpg
image3.jpg
EOF
echo
Which would be called from HTML using a plain:

Code
<img src="randomimage.sh" alt="Random picture">
Tested with GNU Bash 5.2.26 as `sh` and GNU Coreutils 9.3 `shuf`, running under Nginx 1.26.2 via fcgiwrap 1.1.0; Fedora GNU/Linux 39 x86-64.

Note that in a shell script approach, there is even an easier way to let it pick images from current folder without you having to explicitly list them too.



However, if you're on a server with 90s-style Perl CGI support, it can be used for this as well: so here is a Perl CGI example of server-side thingamajig using random-modulo approach: `randomimage.pl`...

Code
#!/usr/bin/perl
@images = (
	"image1.jpg",
	"image2.jpg",
	"image3.jpg"
);
$target = $images[int(rand(65535)) % scalar(@images)];
print "Status: 302\n";
print "Content-Type: text/plain\n";
print "Location: ".$target."\n";
print "\n";
Which would be called from HTML using a plain:

Code
<img src="randomimage.pl" alt="Random picture">
This should work with any Perl 5 version (likely Perl 4 too, but don't quote me on this) and any CGI-supporting web server from the current millennium. Tested with:
  • PHP 5.16.3 running under Apache 2.4; CentOS GNU/Linux 7 x86-64.
  • Perl 5.38.2 running under Nginx 1.26.2 via fcgiwrap 1.1.0; Fedora GNU/Linux 39 x86-64.



If you're using Apache web server with access to your site's `<VirtualHost>` configuration, you don't even need PHP or CGI program; you can even set up a file with mappings containing lists of images you would like like to roulette out, and dice that out directly in `.htaccess` using `mod_rewrite`'s directives.

However, as it require configuration in `<VirtualHost>` section; if you're on shared hosting, it would require you to ask your hosting's support technician to put that in; so I'm not going to bore you with this novelty approach unless you (or others) would like to know more about it.

In any case, you can be most terse about the filenames listed within the (server-side thingamajig) in question, if you put that thingamajig in the same folder as your images. Remember to use web-safe file and directory names (2), and replace paths in the examples with the actual image paths (absolute or relative-to-the-server-side-thingamajig) you're using. You can even use URL which point to image on other servers in these as well.

P.S. All code samples in this post are written by me and released to public domain under Creative Commons Zero 1.0.



(1) Commercial web hosting services don't usually allow this; but it is more common in a pubnix and tilde realm. (If you don't know what pubnix and tilde are; you may as well skip over this shell script section)

(2) Technically, the so-called filenames in these thingamajigs are URL; feel free to use percent escapes if you're feeling adventurous.
« Last Edit: October 06, 2024 @374.65 by xwindows » Logged
JackFrost
Full Member ⚓︎
***


#MAYSGILLIAM2024

⛺︎ My Room

View Profile WWW

First 1000 Members!BUG!?!Joined 2022!
« Reply #4 on: October 05, 2024 @632.80 »

bouncing off of @Slix, the cleanest way to do it would be to have the server just send you the list of all the paths in /images/fakeads and have the js load each one from that. that way it'd be totally automatic and you wouldn't have to edit anything on the client every time you add / remove an ad.

Yeah, don't inflict JavaS'creep on your viewer unless absolutely necessary.

If you are considering a server-side approach and have no special requirement regarding different on-page setup for each different diced image, it would be easiest to just hard-code the image reference in your HTML to point to a (server-side thingamajig). And let that thingamajig dice out an image for you--- usually via HTTP 302 "Found" redirect to one of the actual image file.


And which one of those works on neocities? Sorry if its a dumb question, I have literally 0 knowledge past html lol
Logged



Coffee addict, Gunpla builder, SMT fan.
xixxii
Full Member ⚓︎
***


they/them

⛺︎ My Room

View Profile WWW

Web 1.0 Picture Size Expertthe xixxiiJoined 2024!
« Reply #5 on: October 05, 2024 @668.31 »

And which one of those works on neocities? Sorry if its a dumb question, I have literally 0 knowledge past html lol

neocities does not have php support. there is no way to randomize anything with just html and css. the way you have it done at the moment is the way it will work on neocities as far as i know!
Logged

JackFrost
Full Member ⚓︎
***


#MAYSGILLIAM2024

⛺︎ My Room

View Profile WWW

First 1000 Members!BUG!?!Joined 2022!
« Reply #6 on: October 05, 2024 @676.09 »

neocities does not have php support. there is no way to randomize anything with just html and css. the way you have it done at the moment is the way it will work on neocities as far as i know!

Well is there a way to at least make it cleaner looking? Like have it just be a list of the images instead of that big mess there?
Logged



Coffee addict, Gunpla builder, SMT fan.
xixxii
Full Member ⚓︎
***


they/them

⛺︎ My Room

View Profile WWW

Web 1.0 Picture Size Expertthe xixxiiJoined 2024!
« Reply #7 on: October 05, 2024 @678.09 »

Well is there a way to at least make it cleaner looking? Like have it just be a list of the images instead of that big mess there?

i'm not sure what you mean - the code in the image in your original post IS just a list of images and then the code snippet to randomize from that list?
Logged

Slix
Casual Poster ⚓︎
*


⛺︎ My Room

View Profile WWW

#1 Poliwag Fan !poliwag masterJoined 2024!
« Reply #8 on: October 05, 2024 @776.86 »

Everyone else here submitted good suggestions! :)

Well is there a way to at least make it cleaner looking? Like have it just be a list of the images instead of that big mess there?

If the images are all in the same folder, instead of giving the full file path for each array item, you could just use the image names ("ps2banner.gif") and then at the end of the script, add the full file path before you output the random image (img += "/images/fakeads/"). That would make the image url array much easier to look at and edit!
Logged

xwindows
Casual Poster
*

⛺︎ My Room

View Profile

Joined 2024!
« Reply #9 on: October 06, 2024 @377.11 »

And which one of those works on neocities? Sorry if its a dumb question, I have literally 0 knowledge past html lol
None of them, unfortunately. NeoCities is strictly a static hosting site, meaning they do not allow you to run any sort of server-side program; so you have no choice but to use JavaScript for your "random" effect. However, there are few points which you can improve...

make sure nothing goes wrong on lower end viewers, even without JavaScript perhaps?
When a user doesn't run JavaScript, ideally, he should see just a fixed image in place of that random stuff. This fixed image can be one of the images from your list (1), or even a completely different one not in the list.

You can accomplish what you said by actually having a real `<img>` element in HTML code which is marked specifically (2) but pointing to that fixed image. Then when JavaScript managed to run, make the script change that specific element to point to one of the images from your random list. This also make it easier to lay out and edit your HTML pages, since you would have a real `<img>` element you can see, style, and move around in the code now.

I use this script on multiple parts of my site
Did you mean you're trying to do this on multiple HTML files?

  • If so, then it's a bad idea to write this random-image script in a `<script>` tag. Write it to a separate file once, and reference it from each HTML page using something like this instead (closing tag must still be included)...
Code
<script type="text/javascript" src="random_ads.js"></script>
  • But if not, then feel free to write that random-image code right inside the `<script>` tag. (3)



(1) And you can even use different fixed image on different pages on your site; which covers up the fact that this decorative function was not working.

(2) There are two ways to mark specific HTML element for later reference:

  • Set its `id` attribute to some specific value. This value must be unique inside that document.
  • Set its `class` attribute to some specific value (or even multiple values separate by space). Multiple elements are allowed to share the same `class` value.

In the example code which I would give you on the next post, the random-placeholder would be marked using `class` attribute-- to allow you to have multiple random images in the same page if you wanted to.

(3) To guard against pre-script era browsers spilling the JavaScript code into the page, I would suggest that you write such inline `<script>` tag like:

Code
<script type="text/javascript"><!--
	/* Actual JavaScript code goes here. */
//--></script>
Note that JavaScript syntax explicitly allows this trick.
Logged
xwindows
Casual Poster
*

⛺︎ My Room

View Profile

Joined 2024!
« Reply #10 on: October 06, 2024 @378.56 »

(Continued from the last post)

The example code I'm going to introduce you to does the following:

  • Wait for HTML part of the page finish loading; and once it does...
  • Run through all `<img>` elements in the page to find ones which have "random_ads" in `class` attribute.
  • On each matching element, dice one filename from the list, prepend a fixed folder prefix, and set that as the tag's `src` attribute.

With theory out of the way, here is the actual JavaScript code:

Code
/* `var` works in JavaScript since its earliest beginning;
   don't coerce users onto an upgrade treadmill just for "fashion". */
var randomAdsPrefix = "/image/fakeads/";
var randomAdsImages = [
	"image1.png",
	"image2.png",
	"image3.png"
];

/* This function returns a URI of random "ads" image, prefixed with path. */
function randomAdsDice() {
	return randomAdsPrefix + randomAdsImages[Math.floor((Math.random() * 65535)) % randomAdsImages.length];
}

/* This functions runs as soon as the HTML (only just HTML) finished loading;
   to change each `<img>` element with "random_ads" as one of values
   in its `class` attribute, to display an image diced from `imageURLs`. */
function randomAdsReplace() {
	var i;
	var imageTag;
	var classMatch = /(^|\s)random_ads(\s|$)/;
	
	for(i=0;i<document.images.length;i++) {
		imageTag=document.images[i];
		if(classMatch.exec(imageTag.className)) {
			imageTag.src=randomAdsDice();
		}
	}
}

/* This registers the above function to run when the HTML finished loading. */
window.onload=randomAdsReplace;
You can use this by including this JavaScript code to your HTML page by any means possible: but make sure you do so within `<head>` tag, and also replace "image1.png", "image2.png", ... with your actual image filename (without folder). Then, in your HTML `<body>`, just put in one or more images using a code like this:

Code
<img class="random_ads" src="path/to/your/placeholder/image.png" alt="[Random banner]">
^ Don't forget to replace "path/to/your/placeholder/image.png" with actual placeholder image you use.

You can put this image anywhere on the page, including having more than one of them using different placeholder image, or mixing among other regular images. The only thing which distinguishes such images as random placeholder is a "random_ads" value in their `class` attribute.

Also, it is important to know that this code assumes that...

  • Images you're trying to dice all come from a single folder. (The "/image/fakeads/" folder written in the code)
  • You don't have any other JavaScript code which try to use `<body onload=...>` event.

Side note: I wrote this sample code using the oldest-possible JavaScript constructs that are still working today, which mean it works on any browser from mid-2000s (1), to the latest ones you download and install right now.

This script has been tested with:

  • Firefox 2.0.0.20 (GNU/Linux 32-bit)
  • Opera Classic 11.51 (GNU/Linux 32-bit)
  • Debian Iceweasel 10.0.12 (GNU/Linux 32-bit)
  • Pale Moon 25.8.1 (GNU/Linux 32-bit)
  • Firefox 128.2.0 ESR (GNU/Linux 32-bit)

P.S. All code samples in this post are written by me and released to public domain under Creative Commons Zero 1.0.



(1) My sample code relies on JavaScript version 1.5 and browser's support of W3C DOM Level 2 (circa 2003). While it is technically possible to target browsers older than this point in time, such code would likely fail on today's browsers unless very ugly workarounds were added.

When encountered with this code, such uber-old browsers would show the same page as when JavaScript was disabled-- thus being usable anyway.
Logged
Pages: [1] Print 
« previous next »
 

Vaguely similar topics! (3)

Your favourite ways to socialise offline

Started by Deckade (Tolo)Board ☞ ∙ Life on the Web

Replies: 3
Views: 1048
Last post January 23, 2023 @707.48
by Corrupted Unicorn
Simple ways to create and upload a large art gallery?

Started by morrysillusionBoard ☔︎ ∙ I need Help!

Replies: 7
Views: 2080
Last post July 12, 2022 @876.92
by morrysillusion
Ways our Retro Web differs from the original Old Web

Started by MemoryBoard ☞ ∙ Life on the Web

Replies: 6
Views: 1466
Last post January 09, 2024 @773.09
by xero333

Melonking.Net © Always and ever was! SMF 2.0.19 | SMF © 2021, Simple Machines | Terms and Policies Forum Guide | Rules | RSS | WAP | Mobile


MelonLand Badges and Other Melon Sites!

MelonLand Project! Visit the MelonLand Forum! Support the Forum
Visit Melonking.Net! Visit the Gif Gallery! Pixel Sea TamaNOTchi