Onload fires no matter where I place it - javascript

Right, I'm getting quite aggitated with this. I'm probably doing something wrong, but here's what I'm doing:
$(document).ready(function () {
$('#somebutton').click(function () {
openPage1();
});
$('#someotherbutton').click(function () {
openPage2();
});
});
var openPage1 = function () {
$('#iframe').attr('src', 'someurl');
$('#iframe').load(function () {
$('#button').click();
});
};
var openPage2 = function () {
$('#iframe').attr('src', 'anotherurl');
$('#iframe').load(function () {
$('#anotherbutton').click();
});
}
Whenever I click somebutton everything goes as expected. However when I click someotherbutton. The .load() from openPage1() is called first and I can't find a way to stop that. The .load() from openPage1() has a button with the same name, however on openPage2() I need to modify the contents before clicking the buttons.
I need to use .load() because I can't click the buttons before the document is ready.
Basically what I need is two seperate .load() instances on the same iframe, that don't fire off on each other.
Besides that, maybe my understanding of jQuery/JS is wrong, but shouldn't the .load() events only be listening after clicking the corresponding button?
Can someone help me out, this has been keeping me busy all afternoon.

Try using on, and once loaded, unbind
$("#iframe").on("load", function(){
$(this).off("load");
$('#button').click();
});
That way you remove the handler you put up before the second button is clicked?

By writing : $('#iframe').load(function (){ $('#button').click(); });, you are adding a listener on the load event, which will stay and be re-executed on each subsequent reload of the iframe.
Here is a jsfiddle to demonstrate this : click on the "reload" button, and see how many times the "loaded" message appears in your console.
in your case, if you click on #somebutton, then on #someotherbutton, after the second click, you will have two handlers bound on the load event, and both will be triggered.
If you click 5 times on #somebutton, you should end up calling 5 times $('#button').click().
If you want to execute it once, you can follow Fred's suggestion, or use jQuery .one() binder :
$('#iframe').one('load', function(){ $('#button').click() });
Here is the updated jsfiddle : 'loaded' should be displayed only once per click.

Maybe try and replace the lines in both functions like this:
$('#iframe').load(function() {
$('#anotherbutton').click();
};
$('#iframe').attr('src', 'anotherurl');
Otherwise it might be firing the event before the new event-handler has been set.

This isn't really an answer to your problem Now it is an answer, but I think utilizing functions as they were intended could be beneficial here, i.e.:
//Utilize a single function that takes arguments
var openPage = function (frame, src, eventEl) {
frame.attr('src', src); // If you pass frame as a jQuery object, you don't
frame.on("load", function(){ // need to do it again
$(this).off("load");
evEl.click(); //Same for your buttons
});
}
//Simplify other code
$(document).ready(function () {
$('#somebutton').click(function () {
openPage($("#iframe"),somehref,$("#buttonelement"));
});
$('#someotherbutton').click(function () {
openPage($("#iframe"),anotherhref,$("#someotherbuttonelement"));
});
});

Related

Does JQuery (div).load recall the (div).load function?

I have a function which when the div is loaded it executes code:
$("#row").ready(function () {
When the page has first loaded, it fires fine, my data loads up without any problems.
How ever I would like to reload the div every time the value of a textbox is changed.
$("#startDatePicker").change(function () {
$("#row").load(document.URL);
});
Which is why I have that code there.
However when I change it, the .change event is fired, however it doesn't reload my div? Now I'm not sure if the div has been reloaded and it just doesn't fire the event or the event is not being loaded again at all.
EDIT
Thanks to the comment using an alert to check if the div is being called, I found out that is it not being called after I load it, so the next question is, how do I recall the (div).ready function again?
I think the issue is with jquery-cache.
Try it:
$("#startDatePicker").change(function () {
$("#row").load(document.URL+'?dt='+new Date().getTime(), function() {
alert( "Load was performed." ); // perform the operations here that
// that you wish to perform on .ready
});
});
See if it helps.

How to trigger a jQuery function to load again after another jQuery is executed?

I'm not that great with jQuery but basically, I have a jQuery that displays when scrolling down, new content.
But that new content has div that are under effect of another jQuery function that is called by ready.
So not it only the content that is loaded first when the page loads is working but when the new content is showing is not working on it to.
So I'm thinking maybe I can link the two jQuerys like a trigger when the second jQuery loads to execute the first one, is it possible? How?
Thanks!
UPDATE:
$(document).ready(function($){
$('.wrapper-hover').hover(
function () {
$(this).animate({opacity:'1'});
},
function () {
$(this).animate({opacity:'0'});
}
);
};
Try using Jquery .trigger() to trigger an event and then have something listen for that event
$(document).ready(function($){
//your event handler
$('body').on('event', function() {
$('.wrapper-hover').hover(
function () {
$(this).animate({opacity:'1'});
},
function () {
$(this).animate({opacity:'0'});
}
);
});
};
//when your inifinite scroll finishes trigger the event
$('body').trigger('event');
If all you're doing is attaching a hover event to that class you might also want to think about event delegation, still not sure what your intention is based on your question.
What I understood from your question is that you want a hover event on a div which works well when the page is loaded but it doesn't work when a new div renders. If this is so then try the following code.
$(document).ready(function($){
$('.wrapper-hover').on("mouseenter", function() {
$(this).animate({opacity: '0'}, 1000,
function() {
$(this).animate({opacity: '1'});
});
});
});
I resolved the issue with callback of the infinite scroll jquery. Thanks all!

How to set the focus for a particular field in a Bootstrap modal, once it appears

I've seen a couple of questions in regards to bootstrap modals, but none exactly like this, so I'll go ahead.
I have a modal that I call onclick like so...
$(".modal-link").click(function(event){
$("#modal-content").modal('show');
});
This works fine, but when I show the modal I want to focus on the first input element... In may case the first input element has an id of #photo_name.
So I tried
$(".modal-link").click(function(event){
$("#modal-content").modal('show');
$("input#photo_name").focus();
});
But this was to no avail. Lastly, I tried binding to the 'show' event but even so, the input won't focus. Lastly just for testing, as I had a suspiscion this is about the js loading order, I put in a setTimeout just to see if I delay a second, will the focus work, and yes, it works! But this method is obviously crap. Is there some way to have the same effect as below without using a setTimeout?
$("#modal-content").on('show', function(event){
window.setTimeout(function(){
$(event.currentTarget).find('input#photo_name').first().focus()
}, 0500);
});
Try this
Here is the old DEMO:
EDIT:
(Here is a working DEMO with Bootstrap 3 and jQuery 1.8.3)
$(document).ready(function() {
$('#modal-content').modal('show');
$('#modal-content').on('shown', function() {
$("#txtname").focus();
})
});
Starting bootstrap 3 need to use shown.bs.modal event:
$('#modal-content').on('shown.bs.modal', function() {
$("#txtname").focus();
})
Just wanted to say that Bootstrap 3 handles this a bit differently. The event name is "shown.bs.modal".
$('#themodal').on('shown.bs.modal', function () {
$("#txtname").focus();
});
or put the focus on the first visible input like this:
.modal('show').on('shown.bs.modal', function ()
{
$('input:visible:first').focus();
})
http://getbootstrap.com/javascript/#modals
I am using this in my layout to capture all modals and focus on the first input
$('.modal').on('shown', function() {
$(this).find('input').focus();
});
I had the same problem with bootstrap 3, focus when i click the link, but not when trigger the event with javascript.
The solution:
$('#myModal').on('shown.bs.modal', function () {
setTimeout(function(){
$('#inputId').focus();
}, 100);
});
Probably it´s something about the animation!
I had problem to catch "shown.bs.modal" event.. And this is my solution which works perfect..
Instead simple on():
$('#modal').on 'shown.bs.modal', ->
Use on() with delegated element:
$('body').on 'shown.bs.modal', '#modal', ->
Seems it is because modal animation is enabled (fade in class of the dialog), after calling .modal('show'), the dialog is not immediately visible, so it can't get focus at this time.
I can think of two ways to solve this problem:
Remove fade from class, so the dialog is immediately visible after calling .modal('show'). You can see http://codebins.com/bin/4ldqp7x/4 for demo. (Sorry #keyur, I mistakenly edited and saved as new version of your example)
Call focus() in shown event like what #keyur wrote.
I've created a dynamic way to call each event automatically. It perfect to focus a field, because it call the event just once, removing it after use.
function modalEvents() {
var modal = $('#modal');
var events = ['show', 'shown', 'hide', 'hidden'];
$(events).each(function (index, event) {
modal.on(event + '.bs.modal', function (e) {
var callback = modal.data(event + '-callback');
if (typeof callback != 'undefined') {
callback.call();
modal.removeData(event + '-callback');
}
});
});
}
You just need to call modalEvents() on document ready.
Use:
$('#modal').data('show-callback', function() {
$("input#photo_name").focus();
});
So, you can use the same modal to load what you want without worry about remove events every time.
I had the same problem with the bootstrap 3 and solved like this:
$('#myModal').on('shown.bs.modal', function (e) {
$(this).find('input[type=text]:visible:first').focus();
})
$('#myModal').modal('show').trigger('shown');
Bootstrap has added a loaded event.
https://getbootstrap.com/docs/3.3/javascript/#modals
capture the 'loaded.bs.modal' event on the modal
$('#mymodal').on('loaded.bs.modal', function(e) {
// do cool stuff here all day… no need to change bootstrap
})
Bootstrap modal show event
$('#modal-content').on('show.bs.modal', function() {
$("#txtname").focus();
})
A little cleaner and more modular solution might be:
$(document).ready(function(){
$('.modal').success(function() {
$('input:text:visible:first').focus();
});
});
Or using your ID as an example instead:
$(document).ready(function(){
$('#modal-content').modal('show').success(function() {
$('input:text:visible:first').focus();
});
});
Hope that helps..

Check if the jQuery page load events fired already

Is there a way to check if jQuery fired the page load events yet, or do you have to roll your own? I need to alter the behavior of links, but I don't want to wait until the page finishes loading because the user could conceivably click on a link on, say, the top half of the page before the page finishes loading. Right now I'm doing it like this:
var pageLoaded = false;
$(function() {
pageLoaded = true;
});
function changeLinks() {
$("a[data-set-already!='true']").each(function() {
$(this).attr("data-set-already", "true").click(...);
});
// Is there something along the lines of jQuery.pageWasLoaded that I can
// use instead?
if (!pageLoaded) {
window.setTimeout(changeLinks, 100);
}
}
changeLinks(); // Added per #jondavidjohn's question
Since you are using the document ready shorthand, I'm guessing you mean when the dom is loaded. For this:
$.isReady
You could use setInterval and clear the interval on domready:
var changeLinksInterval = setInterval(function () {
$("a[data-set-already!='true']").each(function() {
$(this).attr("data-set-already", "true").click(...);
});
}, 100);
$(function () {
clearInterval(changeLinksInterval);
});
By the way, in your code example, you shouldn't need .each() - you should be able to call .attr() and .click() directly and let jQuery do the looping. Unless there is more to your .each() code that you didn't post.
$("a[data-set-already!='true']").attr("data-set-already", "true").click(...);
you could use .live() to initiate a click event that needs additional work when binding.
$("a[data-set-already!='true']").live(function(){
// since this event will only fire once per anchor tag, you
// can safely bind click events within it without worrying
// about getting duplicate bound click events.
var $this = $(this);
$this
.data("dataSetAlready",true)
.click(myClickHandler);
});
this is also a useful technique for late-initializing plugins on elements that may not exist at domReady.

jquery function not getting called inside of an ajax function

So im trying do disable links on some <li> ellements that have been loaded in from another page using an .load() function, but for some reason i'm not able to effect those list items.
var from_post = false;
$(document).ready(function() {
//so this is the function that loads in data from another page
$("#gallery").load('http://localhost/index.php/site/gallerys_avalible/ #gallerys_avalible'), function() {
console.log('hello');
// sense there are no other li elliments on the page i thought this
// would be okay. but this function never gets called, i've moved it
// all over i just recently attached it to the load function thinking
// that maybe if the load was not complete it would not run, but i
// have had no luck.
$('li').click(function (e) {
e.preventDefault();
console.log("I have been clicked!");
return false;
});
};
$('#addNew').click(function () {
console.log('i got called');
$('#new_form').fadeIn(1000);
});
$('form').submit(function() {
if(from_post) {
//submit form
return true;
} else {
//dont submit form.
return false;
}
});
any help would be greatly appreciated, oh and the other thing is that i can run this function through firebug, and it works 100% fine. so im stumped.
You are closing your call to .load() too early. You have:
$("#gallery").load('http://...'), function() {
That just calls load and then declares a function. But, that function is not bound to the success handler and it will never be executed. You need the ) to be on the other side of the function declaration so that the function is included as a parameter to your call to load:
$("#gallery").load('http://...', function() {
...
});
Fix that and your code works: http://jsfiddle.net/gilly3/WdqDY/
Try a future-proof event observer like live or delegate:
$('li').live('click', function(){})
or, this method is preferred if you know the parent:
$('#gallery').delegate('li','click',function(){})
The reason for needing this is your click events are being bound to elements that are on the page at the time of the binding. Any li's added later will not see that binding which is how live or delegate works. They bind to the parent and traverse the child nodes every (click in this case) event to see if the event applies to an existing child.
Use .live('click', ...) or .delegate() instead of .click(...).

Categories

Resources