Delayed loading GIF image from CSS background - html

This is my situation; I am displaying ads on my website but I want to display a specific banner if a visitor is using an ad blocker. First thing I've looked for is a script that detects the ad blocker, but after trying a few different scripts it seems most of them no longer work (at least, I couldn't get them to work).
So I gave up on that and went with a different solution. Displaying a CSS background image behind the ad so that if the ad isn't shown, the image is. Because a typical ad takes a moment to load I made the background image a GIF image with 2 seconds of transparency. This works like a charm the first time, but when you reload the page or open a different page the GIF animation doesn't play and instantly displays the last frame, skipping the transparency.
I've tried adding random stuff behind the URL in the CSS, which didn't work. I've tried a data/inline version of the image, that didn't seem to work either. I'm kinda running out of solutions.
The CSS:
.ads {
position: relative;
top: 15px;
float: right;
height: 60px;
width: 468px;
background-image: url('/images/ads/ads_top.gif?randomstuff=39485')
}
I'm basically looking for either;
1) A way to show an alternative image if the ad is blocked (that is still actual and works).
2) A way to delay a CSS background image from being loaded.
3) A way to prevent a GIF from being cached or forced to replay the animation on each pageload.
Any of these would fix my problem. Hope someone is able to help.
Thanks!

Look this link. It is very simple and I don't think you need comments. Another question is how to set up time to each image.
Time to use some jQuery:
Your html code:
<div class='ads'></div>
<div class='ads'></div>
And the css code:
.ads {
position: relative;
top: 15px;
float: right;
height: 60px;
width: 468px;
}
Your jQuery code:
$(".ads").each(function() {
var timestamp = $.now();
$(this).css("background-image", "url('/images/ads/ads_top.gif?"+timestamp+"')");
});
Your jQuery code have to be placed into the .js file. Do you have some js files? If yes, then add my code into onload handler. If you don't have any create new file, say, scripts.js and put this code into it:
$(document).ready(function()
{
$(".ads").each(function() {
var timestamp = $.now();
$(this).css("background-image", "url('/images/ads/ads_top.gif?"+timestamp+"')");
});
}
Explanation:
.ready function means that all instructions in body of this
function will be read and started on page load. You don't need them
to work before page loaded, right?
$(".ads") — we get element with selector .ads (with class ads).
$(".ads").each(function() { /* body */ } — .each function means that we will assign instructions from function body to all elements with selector .ads
var timestamp = $.now(); — getting timestamp and assigning it into variable
$(this).css("background-image", "url('/images/ads/ads_top.gif?"+timestamp+"')"); — adding css property to $(this) element (this element is current element with selector .ads)
Thats all. Simple. Now you have file scripts.js with content above. Put it somewhere on your site, where you usually put your media files. For example, {root}/media/ <-- here.
The last thing you should do is link your new js file and jQuery library. Note, that jQuery library have to be linked before file, using $ variable.
Add next code to the <head></head> tag to your view:
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="/media/script.js"></script>
Don't forget to do all js actions in onload handler.
Hope this will help. Tell me about result, please.
JSFIDDLE

A possible solution for option 1, is to check with javascript (or preferably jquery) if the banner is visible. (You probably need to put a setTimeout around it, because as far as I know the page js loads first, and after that the adblocker js.
var ads = $('.ads').filter(':visible');
if(!ads.length) {
//do your alternative image showing magic here
}
A possible solution for option 2 might be to link to a php script and put a sleep(2); inside it, with after that the appropriate headers and print/echo of the image.

Related

Active state and display:none causes link not to work

Consider the following fiddle: http://jsfiddle.net/GMA76/
On the links active state I want to replace the content of the a tag, then it should continue to follow the link. However when I style it as shown in the fiddle and here:
a div:first-child{
display:block;
}
a div:last-child{
display:none;
}
a:active div:first-child{
display:none;
}
a:active div:last-child{
display:block;
}
The link doesn't work the first time you click it. It only replaces the content and then it seems the redirection fails.
How would I fix that?
Browsers don't take well to content changing on the :active event. Even if it did work, a CSS-only solution would likely mean that the user wouldn't even see the change in content before the new page had loaded (or started to load with a white screen). I tested a lot with the :after pseudo-selector and the content property, but this didn't work either.
And rightly so. Changes to content should only be done with a language like Javascript. This is a logic issue and is outside of the scope of a styling language. Therefore, I would suggest using Javascript.
I've created a quick fiddle here using Javascript with jQuery (doesn't need jQuery it but it's easier) to switch the text in the link and then go to the new page exactly 1 second afterwards. This way you only need to have the original link in the HTML rather than hiding separate links with CSS. There are more flexible and extensible ways to do this if it's not just for one or two links but for the sake of an example, take a look at the fiddle.
This is the jQuery:
$(".switch-link").click(function(){
$(this).text("Test Two");
var href = $(this).attr('href');
setTimeout(function(){
window.location = href
}, 1000);
return false;
});
1000 is the delay between the text changing and the browser starting to load the new page, you can change this to suit your needs.

how to fix chrome flicker on iframe page reload

Chrome flickers when reloading content in iframes. Can this be avoided in any way, thinking of:
Wrapping a-links with js that does some magic.
Meta-tags in content-html. (I have source control over the html in the iframes)
Please note that the content-type in the iframe may vary (pdfs, html, images) so if ajax is the only way out here, does it reflect the http-content-type back to the iframe?
Please visit the demo at http://jsfiddle.net/2tEVr/
Excerpt of fiddle:
<iframe name="if" width="800" height="600"></iframe>
UPDATE
The solution that worked best for me was to replace regular href's with ajax-requests, repopulating the body-area, (solution 4 below) Flickering is gone but comes at a price of akward debugging since sync between content and "view-source" is lost on ajax-request.
Also, since the content-type in my case may change, the method for performing the ajax-request had to have some brains and possibly fall back to regular location request.
regards,
#user247245: From your question, its not entirely clear how you (want to) use the iframe. Does it reload periodically, or once when the whole webpage loads?
Solution 1: Different background color
In case you just want to avoid the ugly white, and avoid over-complication. Set a different background color in your HTML header of the framecontents.html file, like so:
<!DOCTYPE html>
<html style="background-color: #F48;">
This way, while the CSS file loads,parses, and gets applied, the background is not #fff.
Solution 2: Transparent iframe
While there is no content, the iframe should simply not be visible. Solution:
<iframe src="/framecontents.html" allowTransparency="true" background="transparent"></iframe>
Ofcourse dont use this in combination with solution 1, you'll shoot yourself in the foot.
Solution 3: Preload iframe page
In case you are loading the iframe later (such as user clicking a link), consider preloading its contents. Hide this in near the top of your (parent) page:
<iframe src="/framecontents.html" style="position: absolute; width: 0px; height: 0px"></iframe>
But i'd advise using solution 2 instead.
Solution 4: If doing a mobile web interface:
See how jQuery Mobile did it. We built a web interface that had to feel like a native app, so without reload flashes. jQM fixed that. Basically does a background ajax call to retrieve the full HTML contents, then extracts the body (the "page" div to be more precise) and then replaces the contents (with a transition if you like). All the while a reload spinner is shown.
All in all this feels like more like a mobile application: no reload flashes. Other solutions would be:
Solution 5: Use JS to inject CSS:
See answer by jmva, or http://css-tricks.com/prevent-white-flash-iframe/ .
Solution 6: use JS to inject CSS (simple version)
<script type="text/javascript">
parent.document.getElementById("theframe").style.visibility = "hidden";
</script>
<iframe id="theframe" src="/framecontents.html" onload="this.style.visibility='visible';"></iframe>
You could ofcourse leave out the <script> part and add style="visibility:hidden;" to the iframe, but the above would make sure that the frame is visible for visitors with JS disabled. Actually, i'd advise to do that because 99% of visitors has it enabled anyway, and its simpler and more effective.
A common trick is to display the iframe just when it's full loaded but it's better to not rely on that.
<iframe src="..." style="visibility:hidden;"
onload="this.style.visibility='visible';"></iframe>
The same trick a bit optimized using JS.
// Prevent variables from being global
(function () {
/*
1. Inject CSS which makes iframe invisible
*/
var div = document.createElement('div'),
ref = document.getElementsByTagName('base')[0] ||
document.getElementsByTagName('script')[0];
div.innerHTML = '­<style> iframe { visibility: hidden; } </style>';
ref.parentNode.insertBefore(div, ref);
/*
2. When window loads, remove that CSS,
making iframe visible again
*/
window.onload = function() {
div.parentNode.removeChild(div);
}
})();
Extracted from css-trick
If you have to switch between different sites and that trick of onload isn't working the only viable solution would be destroy and create the iframe programatically.
Try adding transform: translate3d(0, 0, 0); on a parent element.
I had an issue where the iframe was taller than its parent (parent has overflow: hidden). The iframe's overflown portion was flickering on each video loop on Chrome (YouTube iframe API).
Forcing hardware acceleration this way was the only thing that worked for me.
A simpler solution that worked in my case was just adding this CSS to the iframe
will-change: height;
min-height: 400px;

Blogger CSS issue: Styles don't get loaded - randomly

I have this blog which I give support from time to time for a client. It uses those dynamic views from blogger. My task was to change the blog's header and insert my client's logo.
I know how to do it and it is working just fine, EXCEPT that sometimes the images from the headers just don't get loaded and some elements are showed without style. The CSS for that block is not loaded for some reason. There is a similar question here: Images are SOMETIMES there . I've got the exact same behavior: The first time I open the site the header styles are there. If I reload the page, it goes away and reappears randomly as I continue to reload the page.
This happens in any browser - IE, Chrome, Firefox.... you name it. And it seems that this issue is around there since 2009, It would be nice if Google could get rid of it someday. Until there, does anyone have a clue about how to work around this problem??
Somethings to note:
There is no console errors.
The blog views work, despite of this issue.
Thanks in advance.
Edit:
How the image was inserted:
A blog post was created and the logo was uploaded in it.
I copied the link from this post.
Custom CSS was inserted using the "Add CSS" option, in MODELS->ADVANCED->ADD CSS. (this is a literal translation, I'm getting it from a language other than English)
The <h1> was edited in order to hide the text and show the logo as a background image. Like so:
background: transparent url('http://1.bp.blogspot.com/-IWokMKhUVbg/UaCJ_ZULa2I/AAAAAAAAAs4/908V5umDsLM/s1600/myfakelogo.png') no-repeat scroll 13px 5px;
float: left;
margin-left: 73px;
margin-top: 10px;
text-align: left;
text-indent: -99999px;
width: 420px;
The <h3> tag was hidden using display: none;
Note that this is not a CSS problem because it actually works. The issue here is that it SOMETIMES FAILS. So a workaround would be, perhaps, changing the way I upload the Image. Or maybe not because the styles are not being loaded either, not only the images...
Go to Dashboard, select Template from the pulldown menu, and Edit HTML. Then scroll down until you see the following lines at the bottom of the template:
<script language='javascript' type='text/javascript'>
setTimeout(function() {
blogger.ui().configure().view();
}, 0);
</script>
</body>
</html>
Change the timeout value from 0 to 1000:
<script language='javascript' type='text/javascript'>
setTimeout(function() {
blogger.ui().configure().view();
}, 1000);
</script>
</body>
</html>
Credit for this trick

chrome/opera anchor shift away after adding dom elements

Say I have a URL: http://rythmengine.org/doc/expression.md#transformer
Immediately after the page is loaded, the anchor is shown correctly, however I have a script to automatically add some iframes across the page, chrome/opera will later on shift away from the anchor #comment, firefox and IE (10) are all good.
Any idea how to fix it in Chrome/opera?
I do not know if I would implement this or not since the iframes do take a noticeable amount of time to load and the user might already be scrolling around the page and get jolted back to the hash element but here is a solution I came up with using jQuery.
Since the iframes are being replaced in the document after it initially loads you can use the .load() function which normally never fires if you just have it on the document.
Demo on this page and edit the fiddle here.
Just add this jQuery code into your script tag where you replace all of the pre code:
Code:
$('iframe').load(function() {
moveToHash();
});
// Scroll to the url hash element
function moveToHash()
{
var hashElem = $(window.location.hash);
// If the hash elment exists
if(hashElem.length)
{
window.scrollTo(hashElem.position().left, hashElem.position().top);
}
}
Edit: had a few mistakes and unnecessary in the code that are now fixed.
When every iframe ends loading tell the browser to go to that hash
$('iframe').load(function() {
document.location.href = document.location.hash;
});

link to anchor near bottom of page

I'm doing some documentation where I make heavy use of anchors for linking between pages on a wiki.
see here:
http://code.google.com/p/xcmetadataservicestoolkit/wiki/ServicesExplained#Platform_Data_Structures
The feature that really makes this work well is when the browser shows the anchor at the absolute top of the pane. When it gets confusing is when linking to an anchor shows the anchor half-way down the page since the page is scrolled down all the way
see here:
http://code.google.com/p/xcmetadataservicestoolkit/source/browse/trunk/mst-common/src/java/xc/mst/utils/Util.java#227
My solution in the wiki (first link) was to put a blank image at the bottom of the page simply to make the browser show the anchor right at the top. Is there a better way to do this? Is there a way to do it in the second link (in which I can't add a blank image)?
Putting a blank image at the bottom of your page is a bad idea, since it will expand your document to a unnecessary height.
You could throw in some javascript to apply an effect to the anchor you just travelled to, to highlight it wherever it is.
Without altering the height of your document (i.e. adding extra padding at bottom), you'll always have this issue.
However, using bit of JS/jQuery, the user experience can be improved considerably:
On clicking a named anchor:
Instead of jumping in a flash (broswer's default behavior), add a smooth scroll
add an highlight to indicate current selection (this helps tremendously in 2nd case as the user can clearly see what is current)
Created a demo to illustrate the concepts: http://jsfiddle.net/mrchief/PYsyN/9/
CSS
<style>
.current { font-weight: bold; }
</style>
JS
function smoothScroll(elemId) {
// remove existing highlights
$('.current').css({backgroundColor: "transparent"}).removeClass('current');
var top = $(elemId).offset().top;
// do a smooth scroll
$('html, body').animate({scrollTop:top}, 500, function(){
// add an highlight
$(elemId).animate({backgroundColor: "#68BFEF" }, 500, function () {
// keep tab of current so that style can be reset later
$(elemId).addClass('current');
});
});
}
// when landing directly
if (document.location.hash) {
smoothScroll(document.location.hash);
}
$('a[href*="#"]').click(function() {
// utilizing the fact that named anchor has a corresponding id element
var elemId = $(this).attr('href');
smoothScroll(elemId);
});
You can create a absolutre positioned pseudo-element with a great height to targeted block using just the following CSS (for the second link in your post:
#nums td:target a::before {
content: '';
position: absolute;
height: 700px;
}
The height must be around the height of the viewport, so the best solution is to create these styles on the fly using js. But if you don't wan't to use js, just use height: 1000px or more — if you don't mind a gap at the bottom of course.
The best part: it's only CSS and there would be no gap when no anchors are targeted.
Edit: just a sneak peek into the future: if the vw/vh units would come to other browsers (now it's only in IE9), this could be awesomely done with just CSS using height: 100vh :)
You could use Javascript / jQuery to create a white div that has the necessary height needed to put your element at the top of the browser window, and you could even remove this upon scrolling away.
However I would highly recommend against doing so as this will expand your page where it isn't needed. It's a lot smarter to simply style the tag upon going there (through Javascript / jQuery) so it pops out to the viewer, for instance by setting the font-weight to bold or changing the background-color.
I would probably use a combination of jQuery and PHP for this:
PHP(somewhere right after your <body> element):
<?php
$anchor = explode('#', $_SERVER['REQUEST_URI']);
$anchor = $anchor[1];
echo '<div id="selected-anchor" anchor="'.$anchor.'"></div>';
?>
And then the jQuery:
<script type="text/javascript">
$(function(){
$('#selected-anchor').css('background-color', '[Whatever highlight color you want]');
});
</script>
Hope this helps.