1

I'm trying to change the background image using javascript. I've set the background up like this;

body {
    background: black;
    overflow-x: hidden;
    overflow-y: hidden;
}
  
body:before {
    overflow-x: hidden;
    overflow-y: hidden;
    content: "";
    position: absolute;
    background: url('http://www.dafont.com/forum/attach/orig/1/6/166803.jpg');
    background-size: cover;
    z-index: -1; /* Keep the background behind the content */
    height: 100%; width: 100%; /* Using Glen Maddern's trick /via @mente */
    transform: scale(1);
    filter: blur(13px);
}

I'm using the above CSS to create a background image with a blur that does not affect elements placed above it. This works. My issue is I would like to change the background image at random intervals. I am unable to do so. I have used;

document.body.style.backgroundImage
$('body').css( 'background-image', artUrl );
document.getElementById('body')

All have failed, I think the issue maybe due to the fact the image is set in body:before. Is there anyway to change the background image using javascript and still be able to have a blur without effecting elements above it? Any help would be appreciated.

Kevin Jantzer
  • 9,215
  • 2
  • 28
  • 52
Rick
  • 46
  • 1
  • 5
  • 1
    You JS is meaningless. Is that all the code you have? – ibrahim mahrir Apr 20 '17 at 18:00
  • 2
    Possible duplicate of [Changing CSS pseudo-element styles via JavaScript](http://stackoverflow.com/questions/4481485/changing-css-pseudo-element-styles-via-javascript) – Heretic Monkey Apr 20 '17 at 18:04
  • 1
    How is it meaning less, those are the 3 most common ways of changing the background, and all have failed, what more do you need? – Rick Apr 20 '17 at 18:05
  • meaningless in the context you posted it in. I thought your code is literally that. – ibrahim mahrir Apr 20 '17 at 18:07
  • *`Using Glen Maddern's trick /via @mente`* sorry for the bummer but that's no-one's trick. Nothing tricky there, it's just the way it is handling absolute elements. – Roko C. Buljan Apr 20 '17 at 18:17
  • Possible duplicate of [How to apply a CSS 3 blur filter to a background image](http://stackoverflow.com/questions/20039765/how-to-apply-a-css-3-blur-filter-to-a-background-image) – Christoph Apr 20 '17 at 18:52
  • I am able to access the pseudo-element in the following manner; `document.styleSheets[1].cssRules[1].style.background = 'url("' + artUrl + '") 0% 0% / cover';` Its ugly but it works, I think it will change when I make CSS changes to the document, but at least now I know what I am looking for. – Rick Apr 20 '17 at 19:07

4 Answers4

0

You are correct that it has something to do with the pseudo element. Unfortunately there isn't a way to manipulate this with JavaScript. You could, however, use JavaScript to create a style tag that would have a higher specificity.

var css = 'body:before { background: url(\'dblogo_150.png\') }';
var style = document.createElement('style');
style.appendChild(document.createTextNode(css));

document.head.appendChild(style);
adam-beck
  • 5,659
  • 5
  • 20
  • 34
0

You can just create new classes with attached pseudo elements to do this, and use Javascript to switch between them. For example your CSS might look like:

.background--first:before {
  background: url(first.jpg);
}

.background--second:before {
  background: url(second.jpg);
}

.background--third:before {
  background: url(third.jpg);
}
djfdev
  • 5,747
  • 3
  • 19
  • 38
  • Of course it is, since after all he is targeting the pseudo element, not the actual body element. And you cannot apply classes to pseudo elements. – Christoph Apr 20 '17 at 18:12
  • The urls are unknown before the document is loaded. They are completely random, so this will not work, but thanks for the help. – Rick Apr 20 '17 at 18:14
0

Use a separate element that you'll blur;
don't use body neither body:before or :after, why complicate, right?!

Use several child elements, hide all but first, set a transition and a .show in CSS, handle (actually toggle) that class using JS (jQuery in our case)

/**
 *   BACKGROUND FADER
 */
(function(){ 
  
  var $slides = $("#background").children(),
      tot = $slides.length, // how many slides
      c = 0,                // simple counter
      itv;
  
  function anim() {
    c = ++c % tot; // c = random? Do what you like
    $slides.removeClass("show").eq( c ).addClass("show");
  }
  
  itv = setInterval(anim, 3000); // Start loop!
  
}());
/*QuickReset*/ *{margin:0;box-sizing:border-box;}html,body{height:100%;font:14px/1.4 sans-serif;}


body{
  color:#fff;
  background: black;
}

#background{
  position: fixed;
  top:0; left:0;
  height: 100%; width: 100%;
  z-index: -999;
  filter: blur(10px);
  overflow:hidden;
}

#background > div{
  position: absolute;
  top:0; left:0;
  height: 100%; width: 100%;
  background: none 50% / cover;
  transition: 1s; -webkit-transition: 1s;
}

#background > div + div{  /* all but first one */
  opacity: 0;
}
#background > div.show{   /* class handled by jQuery */
  opacity:1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div id="background">
  <div style="background-image:url(http://placehold.it/800x600/0bf/fff?text=0);"></div>
  <div style="background-image:url(http://placehold.it/800x600/f0b/fff?text=1);"></div>
  <div style="background-image:url(http://placehold.it/800x600/0fb/fff?text=2);"></div>
</div>

<!-- put other page content here. -->

<h1>Hello world</h1>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
-1

Edited : There is no way to select the pseudo element, but you can add style to the page like this:

try change this:

$('body').css( 'background-image', artUrl );

To

$('body').append('<style>body:before{background: url(' + src + ')}</style>');

The style appends to the page will override the one in css file.

var src = 'https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif';

$('body').append('<style>body:before{background: url(' + src + ')}</style>');
body {
    background: black;
    overflow-x: hidden;
    overflow-y: hidden;
}
  
body:before {
    overflow-x: hidden;
    overflow-y: hidden;
    content: "";
    position: absolute;
    background: url('https://yt3.ggpht.com/-v0soe-ievYE/AAAAAAAAAAI/AAAAAAAAAAA/OixOH_h84Po/s900-c-k-no-mo-rj-c0xffffff/photo.jpg');
    background-size: cover;
    z-index: -1;
    height: 100%; width: 100%; 
    transform: scale(1);
    filter: blur(13px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<html>
  <head></head>
  <body></body>
</html>

enter image description here

Siegen
  • 943
  • 10
  • 13
  • The background-image is on the pseudo-element, so changing it on the body won't have any effect – Christoph Apr 20 '17 at 18:19
  • also isn't just `overflow: hidden;` *simpler?* – Roko C. Buljan Apr 20 '17 at 18:20
  • also this does not answers the bg image change at random and I see no point in putting an enormous useless google doodle gif as demo () – Roko C. Buljan Apr 20 '17 at 18:21
  • @RokoC.Buljan It totally would answer the question, why the change is not working, if there wasn't the real problem that you cannot easily manipulate pseudo elements. The overflow is just c&p from the question. – Christoph Apr 20 '17 at 18:24
  • @Christoph that's why I tought initially that djfdev suggested about using 3 distinct elements :D than after your comment realized noones actually passing the *useful answer* line here. – Roko C. Buljan Apr 20 '17 at 18:26
  • So this answer has promise, he was correct the jQuery method was improperly constructed, however this simply places the new image under the old one. The old one has transparencies so I can see the new image beneath it. My goal is to completely replace the previous image. I will keep tinkering with this. Thanks for the help. – Rick Apr 20 '17 at 18:29
  • I edited the answer, the above code should work as the append style will replace the on defined in the css file – Siegen Apr 20 '17 at 18:47