1

So I want to randomly set a background-image on an element.

Here is what I am trying:

<div id="headImg"></div>

<script>

  $(document).ready(function() {

    var images = ['bg.jpg', 'bg2.jpg', 'bg3.jpg', 'bg4.jpg', 'bg5.jpg', 'bg6.jpg', 'bg7.jpg', 'bg8.jpg'];

    $('#headImg').css( 'background-image', 'url(<?php echo get_template_directory_uri(); ?>/assets/images/' + images[Math.floor(Math.random() * images.length)] + ')' );

  });

</script>

I am obviously doing something wrong since I cant get it to work.

This is also WordPress. So if I set and inline background image like this it works:

 style="background-image: url(<?php echo get_template_directory_uri(); ?>/assets/images/bg.jpg);"

But I want to use jQuery to randomly set the background image inline. Is this even possible.

Any help is greatly appreciated.

agon024
  • 1,007
  • 1
  • 13
  • 37
  • *Is this even possible* — Did it work when you tried it? You have a trailing comma in your `images` array declaration. – Jonny Henly Jun 27 '16 at 21:21
  • @JonnyHenly: No, not without a change or 2. – J. Allan Jun 27 '16 at 21:22
  • 1
    @agon024: What does `get_template_directory_uri();` return? – J. Allan Jun 27 '16 at 21:23
  • @JonnyHenly, The trailing comma should not matter. It is still valid JS. – Jinjubei Jun 27 '16 at 21:23
  • @Jinjubei does it not affect the length of the array? – Jonny Henly Jun 27 '16 at 21:26
  • Show us the final page source in browser (the part when you're changing the image). – Martin Heralecký Jun 27 '16 at 21:28
  • 1
    IE at the very least will throw an error from that trailing comma and fail to run your code. – Vectorjohn Jun 27 '16 at 21:33
  • Ok. Wow! all of this for a trailing slash that makes no difference :). I have updated the code :). – agon024 Jun 27 '16 at 21:36
  • @JefréN. get_template_directory_uri(); returns the my custom theme directory. – agon024 Jun 27 '16 at 21:36
  • @agon024 Returns what exactly? If there are some special characters, it may cause the problem. – Martin Heralecký Jun 27 '16 at 21:38
  • 1
    This works, as it is (http://codepen.io/anon/pen/GqWZyJ with made up path). What is going wrong exactly? Do you have a javascript error? You can debug this very easily, just inspect the element that should have a background and see what its background is. If it *doesn't* have one, then you have a javascript syntax error. Stick an alert or a console.log() in your .ready() method to make sure it's being run. Etc. What you have is correct though, so we'll need more information. – Vectorjohn Jun 27 '16 at 21:44
  • @JonnyHenly, from my testing it ignores the trailing comma because there is not data for it to put in at the end. – Jinjubei Jun 28 '16 at 14:42
  • @Jinjubei Most browsers ignore a *single* trailing comma, Internet Explorer on the other hand increases the length of the array. — [Trailing commas in JavaScript](http://stackoverflow.com/a/11306770/1241334) – Jonny Henly Jun 28 '16 at 22:06
  • 1
    @JonnyHenly, Ahhh the infamous IE causes an issue. Honestly so used to writing for a controlled environment these days I forget about that sometimes. – Jinjubei Jun 29 '16 at 13:41

2 Answers2

2

The reason this code fails is because <?php echo get_template_directory_uri(); ?> can only be evaluated when the page is requested from the server. (PHP is a server side language.)

Hence, this line accomplishes nothing when dynamically generated with jQuery:

 $('#headImg').css( 'background-image', 'url(<?php echo get_template_directory_uri(); ?>/assets/images/' + images[Math.floor(Math.random() * images.length)] + ')' );

If, however, you replaced <?php echo get_template_directory_uri(); ?> with the return value of get_template_directory_uri();, to form this:

$('#headImg').css( 'background-image', 'url((return value here)/assets/images/' + images[Math.floor(Math.random() * images.length)] + ')' );

Your code would run properly.

Edit:

As you can see from the comments below my post, people said--rightly so--that in certain cases, his code would've worked.

However, code that embeds php only works if the code is in the file being requested. (ie. It is inline code, rather than external code from different pages.) However, in this case, the jQuery was not in the same file ... That is why he had to remove the offending php tag.

In recap:

This solution was necessary because the javascript was not in the requested .php file. Hence, the PHP tags were not evaluated. (PHP tags mean nothing in javascript files.)

If, however, the javascript would have been in the requested PHP file, it would've worked fine.

J. Allan
  • 1,418
  • 1
  • 12
  • 23
  • Who tells you this isn't running on a server? – Jojo01 Jun 27 '16 at 21:40
  • @Jojo01: Huh? Could you please explain your question? Did you read my answer? – J. Allan Jun 27 '16 at 21:41
  • The php will echo in the location of the directory before the page is loaded, but as you said it needs to be on a server to work. Hence your answer implies that this page is not being requested from a server. But how do you know that? – Jojo01 Jun 27 '16 at 21:43
  • @Jojo01: When the jQuery changes the background image for `#headImg`, the *page is no longer on the server.* Hence, the code between the tags, **will not run.** It will, however, be invalid CSS. – J. Allan Jun 27 '16 at 21:45
  • If we assume that the code provided by the author of the question is in some _.php_ file, then the PHP code will be processed and will return the directory path. So, in browser, there won't be any ` – Martin Heralecký Jun 27 '16 at 21:45
  • Um. This is what I was thinking also. So after doing what you said, it does work. I replace it with the return value and it randomly changes on page refresh. Thanks for confirming my suspicions. – agon024 Jun 27 '16 at 21:46
  • I have myself echoed javascript inside javascript with php and it has worked. – Jojo01 Jun 27 '16 at 21:47
  • @Jojo01 then tell my why this isn't working if you know how to do it. Cause i feel he is right. – agon024 Jun 27 '16 at 21:48
  • Can you create another empty .php with this code? `

    No value

    `
    – Jojo01 Jun 27 '16 at 21:50
  • Guys, I just explained why it had to be done this way. Sorry, for any confusion. – J. Allan Jun 27 '16 at 21:51
  • I edited the comment with the code, does the text of the h1 change to what get_template_directory_uri(); returns? – Jojo01 Jun 27 '16 at 21:56
0

Since you have 7 images you can maybe just do it like this:

var rand = Math.floor(Math.random() * 7) + 1;
$('#headImg').css( 'background-image', 'url(<?php echo get_template_directory_uri(); ?>/assets/images/bg' + rand + '.jpg)' );

Basically you can just create a random number between 1 and 7, then add that number to bg and .jpg e.g bg5.jpg

Jojo01
  • 1,269
  • 4
  • 14
  • 35
  • Why the downvote? This would work, although you'd need to change the limit for the random number if you add or remove images. This also simplifies things a lot. – Jojo01 Jun 27 '16 at 21:33
  • 3
    It doesn't simplify anything at all, it enforces a naming convention on the images and doesn't even work since there is no bg1.jpg and has a hard-coded range. – Vectorjohn Jun 27 '16 at 21:35