mishmomo mishmomo - 1 month ago 10
PHP Question

Would a while loop be better for this? Doesn't this seem redundant?

I am trying to create a random background image picker. What I have works, but it seems clunky and redundant. Can I get help in figuring out a better way to write this?

Requirements:


  • Random background for page should be displayed each time the page is
    refreshed.

  • Each background has a specific blurb of text that goes with it, so
    the correct text needs to be displayed with each background.

  • Have a list of links to show the other backgrounds/text
    Currently-displaying background/text should not be listed in the
    index.



Example: if background3.jpg is displaying, the list should only have background1.jpg, background2.jpg, and background4.jpg.

PHP

$backgrounds =
array(
'cat1.jpg', 'cat2.jpg', 'cat3.jpg', 'cat4.jpg', 'cat5.jpg', 'cat6.jpg'); // array of image files

$randBg = rand(0, count($backgrounds)-1); // generate random number size of the array
$selectedBg = "$backgrounds[$randBg]"; // set variable equal to which random filename was chosen

$strings = array('This kitten has a filter', 'This cat is in the dark', 'This kitten has green eyes', 'This cat has a mask', 'This is Grumpy Cat', 'This cat is orange'); // array of strings, that correspond to each image

function showString($backgrounds, $randBg, $strings) {
for ($b = 0; $b < count($backgrounds); $b++) {
if ($b == $randBg) {
echo $strings[$b]; // Loop through the image array and print corresponding text from strings array
}
}
}


HTML

<div id="text">
<h1><?php showString($backgrounds, $randBg, $strings); ?></h1>
</div>
<div id="index">
<ul>
<li id="1">Filter</li>
<li id="2">The dark</li>
<li id="3">Green eyes</li>
<li id="4">Mask</li>
<li id="5">Grumpy</li>
<li id="6">Orange</li>
</ul>
</div>


CSS

body {
/* randomly selected background image */
background-image: url(images/<?php echo $selectedBg; ?>);
background-size: cover;
background-repeat: no-repeat;
}

div#text { /* the text from the respective background image goes in this div */
background-color: rgba(255, 255, 255, 0.8);
width: 50%;
margin: 10% auto 0 auto;
display: block;
text-align: center;
padding: 25px;
}

div#text h1 {
color: #000;
}

div#index { /* use this menu to view other background images */
background-color: rgba(255, 255, 255, 0.8);
width: 50%;
position: absolute;
margin-left: auto;
margin-right: auto;
bottom: 0;
}

div#index ul {
list-style-type: none;
overflow: hidden;
}

div#index ul li {
float: left;
padding: 25px;
}

div#index ul li:hover {
background-color: #000;
color: #fff;
cursor: pointer;
}


jQuery

var selected = $("li"); // make var for the list items
var bgsArray = [1, 2, 3, 4, 5, 6]; // make array of backgrounds
var strings = [ // make array of strings
"This kitten has a filter",
"This cat is in the dark",
"This kitten has green eyes",
"This cat has a mask",
"This is Grumpy Cat",
"This cat is orange"
];
var current = bgsArray[Math.floor(Math.random() * bgsArray.length)]; // get a background image randomly (can't be anything else or else the initial image is always the same on reload).
if ($("body").css("background-image", "url('images/cat" + current + ".jpg')")) { // check current background image against the random number
$("div#text h1").html("" + strings[current - 1]); // make sure correct text displays
$("li#" + current).css("display", "none"); // hide current displaying bg in index
$("li#" + current).siblings().css("display", "block"); // make sure all other index values are showing
}

$.each(selected, function() { // function to iterate through all list items
selected.click( function() { // function for clicking on list item

var li_id = $(this).prop("id"); // get the id of the <li> that was just clicked
var cssBg = "url('images/cat" + li_id + ".jpg')"; // create string for bg url with id
$("body").css("background-image", cssBg); // change page bg to new image with corresponding id
$("div#text h1").html("" + strings[li_id - 1]); // change the text
if ($("body").css("background-image", cssBg)) { // hide the <li> for the bg that's currently displaying, but show all others
$("li#" + li_id).css("display", "none");
$("li#" + li_id).siblings().css("display", "block");
}
});
});


My goal is to learn how to conceptualize refactoring this (if that makes sense), because I know there is a much neater way to write it. Are both PHP and jQuery even required? Should I be using AJAX? I used jQuery to minimize HTTP requests after the initial pageload. If it's more efficient to use one language, I'd rather go that way. Thank you for any and all assistance.

Answer

Not entirely sure from your description, but it seems you don't need php. You can just show a random image using JS alone. Also, it is cleaner to use a map to connect the image to the blurb of text.

E.g.:

var imageToText = { "imageNameA": "cat text A", "imageNameB": "cat text B", ... }

flow: Based on size of map, fetch imageName + corresponding text

Also, talking about the event handlers a bit

You have:

var selected = $("li"); // make var for the list items ... $.each(selected, function() { // function to iterate through all list items selected.click( function() { // function for clicking on list item ... }) }) ...

This can be refactored to:

$("li").click(function(){ var $el = $(this); //do something... })

hth

Comments