I'm using the Overlay plugin from jQuery Tools: http://flowplayer.org/tools/overlay/index.html to display a full size image when a link is clicked, but the overlay is displayed immediately and shows the image loading.
I'd like to change this behavior and wait until the image is loaded before launching the overlay. The Overlay plugin has an onBeforeLoad property to which a callback function can be attached. But, of course, the overlay display resumes as soon as this callback is executed, and will not wait for the image load event to be fired.
The plugin has a few API methods, but they don't seem very helpful for my purpose.
In my example below, the two lines I've commented out should give you an idea of what I thought might work, but doesn't.
Here's a simplified test case: http://jsfiddle.net/GlauberRocha/9jkU5/
Any idea?
var $trigger = $("#trigger"),
api;
$trigger.overlay({
fixed: true,
mask: {
color: "#000",
opacity: .8
},
onBeforeLoad: function() {
console.log("onBeforeLoad");
api = $trigger.data("overlay"); // see http://flowplayer.org/tools/overlay/index.html "Scripting API"
//api.close(); // Temporarily "close" the overlay?
setTimeout(function() { // This will be replaced by the image load event
console.log("Waiting is over!");
//api.load(); // Load the overlay now?
}, 2000);
},
onLoad: function() {
console.log("onLoad");
}
});
Ok, I think I understand what you are wanting. To prevent the overlay from loading, you need to return false, but only if the image is not yet loaded. See if this JSFIDDLE helps:
var $trigger = $("#trigger"),
api;
var imageLoaded = false;
$trigger.overlay({
fixed: true,
mask: {
color: "#000",
opacity: .8
},
onBeforeLoad: function() {
console.log("onBeforeLoad");
api = $trigger.data("overlay"); // see http://flowplayer.org/tools/overlay/index.html "Scripting API"
//api.close(); // Temporarily "close" the overlay?
if(!imageLoaded){
setTimeout(function() { // This will be replaced by the image load event
console.log("Waiting is over!");
api.load(); // Load the overlay now?
}, 2000);
imageLoaded = true;
return false;
}
},
onLoad: function() {
console.log("onLoad");
}
});
I've modified my code. This version seems to work (see http://jsfiddle.net/GlauberRocha/rwtvK/). The main difference comes from the way the API method is called ($trigger.overlay().load() vs $trigger.data("overlay").load()). This inconsistency is present in the jQuery Tools docs and examples.
$(function () {
var $trigger = $("#trigger");
$trigger.overlay({
fixed: true,
mask: {
color: "#000",
opacity: .4
},
onBeforeLoad: function () {
if (typeof this.init === "undefined") {
this.init = true;
setTimeout(function () { // This will be replaced by the image load event handler
console.log("OK, let's show it!");
$trigger.overlay().load(); // Load the overlay
}, 5000);
console.log("Not now!");
return false;
}
}
});
});
Related
I'm using a qTip2 tooltip to display a little notification at the bottom-left of the browser window when an update has occurred to certain elements on the page (so that the user is aware that a page save might be required to persist the change).
That was working reasonably well under my old test environment (Windows Vista, Firefox 52). However, with Windows 10 and Firefox Quantum (57.0.4), I'm seeing a console message which says:
This site appears to use a scroll-linked positioning effect. This may
not work well with asynchronous panning.
The warning links to a MDN page which talks about asynchronous scrolling, and indeed I'm now seeing a delayed qTip2 element-reposition when scrolling the page.
JSFiddle which demonstrates the issue - click the button and scroll the rendered context to see the effect.
I'd appreciate it if someone could recommend a solution that would eliminate the scroll/position-update delay. Thank you.
JSFiddle script:
<button id='mybutton'>Press me</button>
<div style='height: 1000px'></div>
function delay(ms)
{
var d = $.Deferred();
setTimeout(function()
{
d.resolve();
}, ms);
return d.promise();
}
function qTipHint(titleTxt, contentTxt, anchorElement, timeOut, topCenter)
{
if (anchorElement.length > 0)
{
var locationMy = '';
var locationAt = '';
if (topCenter)
{
locationMy = 'top center';
locationAt = 'bottom center';
}
else
{
locationMy = 'bottom left';
locationAt = 'bottom left';
}
var test = anchorElement.qtip(
{
content:
{
text: contentTxt,
title: titleTxt
},
show:
{
effect: function()
{
$(this).slideDown();
}
},
hide:
{
event: '',
effect: function()
{
$(this).slideUp();
}
},
style:
{
classes: 'qtip-jtools',
tip: false
},
position:
{
my: locationMy,
at: locationAt,
target: anchorElement
}
});
var api = test.qtip('api');
api.show();
delay(timeOut).then(function()
{
api.destroy();
});
}
}
$('#mybutton').click(function()
{
qTipHint('Title', 'Some hint text', $(window), 10000, false);
})
I've come to the conclusions I was trying to force the qTip2 library into a role for which it was not intended.
I've switched to Bootstrap Notify as an alternative, and it does a very satisfactory job.
I have managed to implement the smoothState.js plugin on my website and it works nicely, but my other very simple jQuery plugin will not work, wich starts with:
$(document).ready()
I need to refresh the page in order for it to work again.
I've read the smoothState documentation and it says I should wrap your plugin initializations in a function that we call on both $.fn.ready() and onAfter — but I'm farely new to programming, so I'm asking for your help.
How can I make my jQuery plugins work with smoothState?
You need to wrap scripts that are initiated with $(document).ready() in a function, and then call that function when you need it.
For example, let’s say this is your current script:
$(document).ready(function() {
$('.btn--homepage').click(function(e) {
e.preventDefault();
var goTo = $(this).attr('href');
$('#page').addClass('is-exiting');
$(this).addClass('exit-btn');
setTimeout(function() {
window.location = goTo;
}, 260);
});
});
It’ll work fine when the page loads as it’s wrapped in $(document).ready(function()), but as the page won’t be reloading when using Smoothstate, we need a way to call the snippet both when the page originally loads and when smoothstate loads content. To do this we’ll turn the above snippet in to a function like this:
(function($) {
$.fn.onPageLoad = function() {
$('.btn--homepage').click(function(e) {
e.preventDefault();
var goTo = $(this).attr('href');
$('#page').addClass('is-exiting');
$(this).addClass('exit-btn');
setTimeout(function() {
window.location = goTo;
}, 260);
});
};
}(jQuery));
As you can see, we’ve swapped $(document).ready(function()) with the function wrapper, everything else stays the same.
So now we’ve got a function all we need to do is call it when the page loads and in Smoothstate.
To call it when a page loads all we need to do is this:
$(document).ready(function() {
$('body').onPageLoad();
});
And to trigger it in Smoothstate we need to call it in the InAfter callback like this:
onAfter: function($container) {
$container.onPageLoad();
}
And here's an example Smoothstate script showing where to put the onAfter callback:
$(function() {
var $page = $('#main');
var options = {
prefetch : true,
pageCacheSize: 4,
forms: 'form',
scroll: false,
onStart: {
duration: 1200,
render: function($container) {
$container.addClass('is-exiting');
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 0,
render: function($container, $newContent) {
$container.removeClass('is-exiting');
$container.html($newContent);
$('html, body').scrollTop(0);
}
},
onAfter: function($container) {
$container.onPageLoad();
}
};
var smoothState = $('#main').smoothState(options).data('smoothState');
});
Happy to provide further assistance if needed.
What's wrong with this code? Probably a lot cus I'm new to jquery. I'm trying to fadeIn the page then fade the background to a different one the fade up and in the nav and set it up so the links will fade the page out and bring in the new page. The code I have now isn't quite working and I think some syntax and formatting is the problem.
$(document).ready(function() {
$('body').fadeIn(1500);
});
$('#background').addClass('background');
setTimeout(function() {
$('#background').addClass('background-blured');
}, 1500);
$("h1").delay(2000).animate({
top: -50,
opacity: 1,
}, 700, function() {
// Animation complete.
});
$('.link').click(function() {
event.preventDefault();
newLocation = this.href;
$('body').fadeOut(500, newpage);
});
function newpage() {
window.location = newLocation;
}
});
Thanks!
$(document).ready triggers as soon as the DOM is fully loaded. Any javascript outside of the $(document).ready block is run while the browser is still loading the page. so if your $('#background') element is not yet loaded to the DOM jQuery cannot add the 'background' class to it. And more than likely only some of your $('.link') elements will have the click event listener added since they weren't yet loaded when the javascript ran. That's why you should embed such things inside the $(document).ready function.
$(document).ready(function() {
$('body').fadeIn(1500);
$('#background').addClass('background');
setTimeout(function() {
$('#background').addClass('background-blured');
}, 1500);
$("h1").delay(2000).animate({
top: -50,
opacity: 1,
}, 700, function() {
// Animation complete.
});
$('.link').click(function() {
event.preventDefault();
newLocation = this.href;
$('body').fadeOut(500, newpage);
});
});
function newpage() {
window.location = newLocation;
}
Notice with proper indentation you can easily see what is inside the $(document).ready function. Also notice you don't put standard functions like your newpage() function inside the $(document).ready.
I have a popup window using fancybox which I would like to add some timings to, show after 1 second maybe and disappear after 5. I cant figure out where to add any delays in the code i am using, please can anyone help?
<script type="text/javascript">
jQuery(document).ready(function ($popup) {
$popup("#hidden_link").fancybox({
onComplete: function () {
$popup("#fancybox-img").wrap($popup("<a />", {
href: "mylink.html",
target: "_blank",
// delay: 9000 would like a delay ideally
}));
}
}).trigger("click");
});
</script>
<a id="hidden_link" href="images/myimage.jpg" style="visibility:hidden;"></a>
You can use $.fancybox.open(), see details here - Can you explain $.fancybox.open( [group], [options] ) params and if I can add youtube link as href?, and $.fancybox.close().
setTimeout(function(){
$.fancybox.open(...)
}, 1000);
setTimeout(function(){
$.fancybox.close(...)
}, 5000);
If your link is not going to be visible, you may rather open fancybox programmatically using the $.fancybox.open() method and close it using the $.fancybox.close() method.
As pointed out, you could use setTimeout() to delay the execution of either those methods like :
jQuery(document).ready(function ($popup) {
// open with delay
setTimeout(function () {
$popup.fancybox({
href: 'images/image01.jpg',
onComplete: function () {
$popup("#fancybox-img").wrap($popup("<a />", {
href: "mylink.html",
target: "_blank"
}));
// close with delay
setTimeout(function () {
$popup.fancybox.close();
}, 9000); // setTimeout close
}
});
}, 2000); // setTimeout open
}); // ready
See JSFIDDLE
Note: this is for fancybox v1.3.4.
for some reason I can't input text in my newsletter input field now that I display it in a fancybox popup window. Any idea what the issue is and how to fix this? See http://jsfiddle.net/6G8YR/
Many thanks,
function openFancybox() {
setTimeout( function() {$('#newspopup').trigger('click'); },1000);
}
$(document).ready(function() {
var visited = $.cookie('visited');
if (visited == 'yes') {
return false;
} else {
openFancybox();
}
$.cookie('visited', 'yes', { expires: 0.0001 });
$('#newspopup').fancybox({
helpers : {
overlay : {
css : {
'background' : 'rgba(58, 42, 45, 0.3)'
}
}
}
});
});
$(document).on('click', function(e) {
if(e.target === $('.visitwebsitebtn')[0]) {
$.fancybox.close();
}
});
Ok I figured out the problem, but only ran into other kinds of issues. The problem is that, there is an event that exists that causes your fancybox to refresh everytime someone happens to click on it.
This is why you are unable to write anything in the input. I have a temporary solution that is really ugly but it works.
$('#email').on('click', function(e){
e.stopPropagation();
});
Upon clicking the email input, your fancybox won't refersh. I tried applying this to your #newspopup but it blocs $('#newspopup').trigger('click'); so your fancybox never opens at the start.
Here is a Demo
Additional information:
I've worked with fancybox plugin before and I've never encountered this problem. You might want to think of adding options to your fancybox.. for example add this line :
'type':'iframe',
I would have tried on jsfiddle, but unfortunately they don't allow it, it seems.
You can optimize your code and get rid of unnecessary click events and triggers (so you won't need unnecessary e.stopPropagation() methods either) like :
function openFancybox() {
setTimeout(function () {
$.fancybox('#newspopup', {
modal: true, // this prevents fancybox to close unless close unless ".visitwebsitebtn" is clicked
helpers: {
overlay: {
css: {
'background': 'rgba(58, 42, 45, 0.3)'
}
}
},
afterShow: function () {
// enables a way to close fancybox
$(".visitwebsitebtn").on("click", function () {
$.fancybox.close()
});
}
});
}, 1000);
};
$(document).ready(function () {
var visited = $.cookie('visited');
if (visited == 'yes') {
return false;
} else {
openFancybox();
}
$.cookie('visited', 'yes', {
expires: 7
});
});
See JSFIDDLE