I'm new to ajax and want to best understand how to write my jQuery code so that then a page is called via ajax, my jQuery functions (simple stuff like slideshows and overlays) will still work.
Below is what I'm currently doing to make my jquery work on a stand alone page without ajax.
$('.microContentWrap').click(function(){
//perform some functions
});
In order to make this same function work when this page has been loaded via ajax, I'm duplicating my code and binding it to a div called "ajax-wrapper" that loads normally on this page. Without this step, the above code was not executing on the ajax page.
$("ajax-wrapper").on("click", ".microContentWrap", function() {
//exact same functions as above
});
Both of these things work, but is this the most efficient way? Seems repetitive to do this two step process for every single function in my file.
$("ajax-wrapper").on("click", ".microContentWrap", function() {
//exact same functions as above
});
Is saying: "when I click within 'ajax-wrapper' check to see if the element I clicked is 'microContentWrap', if it is, then do this function". The benefit of this approach is that 'microContentWrap' doesn't need to exist when you bind the click even listener.
Another approach would be to add the event listener to 'microContentWrap' in your ajax callback function. So for example:
$.ajax({
url:"getvalue.php",
success:function(data) {
$('body').append('<div class="microContentWrap"></div>');
$('.microContentWrap').click(function(){});
}
});
The solution to this was actually very simple, I just didn't understand binding. The problem I was having was that the ajax-wrapper gets destroyed after the microContent comes in. On other non-ajax pages there was no ajax-wrapper which is why I thought there needed to be two functions. By binding to the body, I eliminated the issue.
$("ajax-wrapper").on("click", ".microContentWrap", function() {
//exact same functions as above
});
Related
For <div class="editdiv">Test</div>. Jquery click functionality is added in document.ready function . But editdiv loading in page dynamically with delay.
So when I click on the div. Function is not calling. By using timeout function is working fine.
I need a different approach to solve this functionality.
If your .editdiv is loaded dynamically after your js loading so your click event can't detect it and it will not work, instead you should use event delegation on() to deal with fresh DOM :
$('body').on('click', '.editdiv', function(){
//Your click event code
})
If you want to avoid setTimeout you could use delay with queue callback method :
$('div.scroll-area-blue')
.delay(5000)
.queue(function() {
$(this).enscroll({
showOnHover: false,
verticalScrolling: true,
verticalTrackClass: 'vertical-track-blue',
verticalHandleClass: 'vertical-handle-blue'
});
});
If you will use setTimeout better to use it like :
setTimeout( enscrollDiv, 5000);
function enscrollDiv(){
$('div.scroll-area-blue').enscroll({
showOnHover: false,
verticalScrolling: true,
verticalTrackClass: 'vertical-track-blue',
verticalHandleClass: 'vertical-handle-blue'
});
}
Hope this helps.
It is really difficult to understand whats going wrong from your question. What I guess is you are loading a specific div using Ajax or similar technologies - meaning the div is not available initially.
The way jQuery works is that, it only binds the event to the elements only available at the time the part is executed.
If a <div id='myDiv'></div> is not present when $('#myDiv').click(function(){}) is called, it won't work.
One workaround is to do it like this:
$('body').on('click','#myDiv',function(){});
This registers the click on body and then checks if the clicked element is having a id 'myDiv' or not. We can expect the <body></body> to be present always. So the problem we had with previous code won't happen here.
maybe you're loading the javascript codes before the html elements(tags) are loaded.
try adding the script which includes "document.ready()" before the end tag of the body when all html tags have already finished loading.
I'm hitting targets in the dark. Hope it works for you. It's difficult to generate any solution without analyzing the problematic code......
I want to write a global method for my site.
That when the page jumps to another, before the redirection acts, show a waiting mask on the page.
So I'm wondering if there is some way to get an event before the redirect?
The following code explains what I want to do, but doesn't work.
$(function() {
$(document).on('before_redirect', function() {
// show the waiting mask.
});
});
The answer can not be so neat, I just want the GLOBAL METHOD, once this piece of javascript included, no need to write anything other place.
Pray for good solution!
What you want is the beforeunload or unload event. JQuery also provides the unload shorthand method (deprecated after 1.8). Different browsers handle these events inconsistently, so you'll want to test each and make sure that your solution is acceptable in each. Generally, you'll lose control of the window once you've allowed the request to proceed so a mask may or may not work as intended.
the simplest way is place the same class name on redirecting elements like buttons ,anchor tag like so and write code based on class.
Html
<a class="navigation" href="/nextpage"></a>
or
<button class="navigation"></button> //for this you need to put url onClick function
js
$(function() {
$(document).on('click', '.navigation', function() {
// show the waiting mask.
});
});
I am using an infinite scroll plugin which uses ajax.
When the 'next page' is loaded via ajax, all other ajax related scripts that are on the next page do not work. I have been told that I have to use 'delegated events'(ie change $(id).click() to $(document).on) - problem is that means editing multiple plugins and changing dozens of function calls.
Is there any way I can avoid changing everything to $(document).on and do something cool with the infinite scroll?????
I'd much rather modify the infinite scroll plugin rather than modifying other ajax related plugins to make them fit.
Unfortunately you have very few options here, and switching to delegated events is by far the best of them.
The problem is that your old code was assigning behaviour to "particular elements" when what it should really have been doing is creating page-wide responses to "certain types of actions".
I see 3 possibilities, and only one of them is guaranteed to work.
Run any scripts that are needed on new pages each time a new page is loaded. The downside here being that unless you are careful about also "tearing down" between content loads you will have behaviours repeating or colliding with each other (eg: double popups, broken animations).
Encapsulate the dynamic areas in <iframe>s. Depending on your architecture this may or may not be possible, and certainly won't be easy to integrate with some kind of infinite scrolling plugin which already expects a certain page structure.
Bite the bullet and fix the crappy code.
Loading scripts inside your ajax loaded content is a bad way to start with anyway. What you need is event delegation to attach itself to any dynamically added elements.
$("body").on("click", ".yourclass", function() {
//This function will run for every element with `yourclass` class you load via ajax
});
If you must keep using .click() then you must have a function you can call on the new content to re-hook the events every time you add more content to the page.
e: though it is worth noting that a change from .click to .on can often be handled by a properly structured find/replace
Event delegation is the correct solution. The issue is that the HTML elements on the "next page" were not part of the DOM when the page loaded. Therefore, if you did something like:
$(function() {
$('#some-element-on-the-next-page').click(function() {
foo();
});
});
Your handler did not bind.
I wouldn't attach the events to $(document). I would attach them to the closest parent which is available when the DOM loads. For example, the body tag or the fixed width wrapper which is the first child of the body (assuming your layout uses this type of structure.)
Make sure that the element that you attach to is not emptied with .empty() or repopulated with .html() as that will break the binding. Attaching the delegated handlers lower down on the DOM tree will give you better performance since the events will not have to bubble all the way up to the document node to fire your methods.
You shouldn't need to rewrite all of your functions and plugins, just the bindings to the events that fire them.
I typically use the module pattern and de-couple my method definitions from the click handlers. All of my methods are defined in the outer closure. I'll have a "document ready" section where I bind user events like clicks.
For example:
var myModule = (function() {
var public = {};
public.foo = function() {
// do something cool here
};
// document ready
$(function () {
$('#site-container').on('click', '.js-foo', function() {
public.foo();
});
});
return public;
})();
If you need to change the bindings in the future you will only need to change the call inside the document ready section.
I'm using jQuery for a small project I have and it's one of my first times using it. Is it safe to put all my UI code in $(document).ready() ? I'm basically creating a form that pops up when a button is pressed, and the form is processed via AJAX. Basically, when I separate my AJAX function from the functions controlling the UI, the AJAX doesn't work. However, when I put both of them in $(document).ready(), everything works fine. Here's my code. Please ignore my comments, as they were for learning purposes.
$(document).ready(function(){ //ready for DOM manipulation
/*FORM UI*/
var container_form=$('#container_form'); //container form box
var addButton=$('.addButton'); //"+" add button
container_form.hide(); //initially hides form
$(addButton).click(function(){
$(container_form).toggle('fast');
/*SUBMISSION AJAX*/
$('form.ajax').on('submit',function() { //Make form with class "ajax" a JQuery object
var that = $(this), //"that"-current form, "url"-php file, "type"-post, "data"-empty object for now
url=that.attr('action'),
type=that.attr('method'),
data={};
that.find('[name]').each(function(index,value){ //search all elements in the form with the attribute "name"
var that=$(this), //legal attribute
name=that.attr('name'); //name of the legal attribute
value=that.val(); //value of text field in legal attribute
data[name]=value; //data object is filled with text inputs
});
$.ajax({
url: url, //url of form
type: type, //type of form
data: data, //data object generated in previous
success: function(response){ //reponse handler for php
if(!response){
console.log("Error");
}
console.log(response);
}
});
return false; //Stops submission from going to external php page.
});
});
});
Generally any selectors such as $('form.ajax')., $('#container_form'), $('.addButton') needs to be in doc.ready to ensure that the DOM is ready before you try to select an element from it, since it may not find the element if the DOM hasn't finished processing. So that pretty much applies to all of your code. If you had a function such as this:
//defines a function
function addThem(first,second)
{
return first + second;
}
You could declare it outside of doc ready, and call it from within doc ready.
$(document).ready(function(){
$('#someInput').val(
addThem( $('#anotherInput').val() , $('#thirdInput').val() )
);
});
The way I think about this, is doc ready is an event, so you should be doing things in response to the "document is now ready for your to query event", not declaring things. Declaring function just says what that function does, but doesn't actually do anything, so it can go outside of the document ready. It'd be pretty silly to declare this function inside of doc.ready since it can be defined at anytime (although it certainly is possible to put it inside doc ready, it just generally clutters things up). Even if it were selecting an element, that code isn't actually running until it is called:
function hideContainer()
{
//this code never runs until the function is called
//we're just defining a function that says what will happen when it is called
return $('#container').hide();
}
$(document).ready(function(){
//here we are calling the function after the doc.ready, so the selector should run fine
hideContainer();
});
Note that the act of wiring up to other events is an action in itself, such as when you subscribed to the click events and form submit events. You are saying, "find the form element with class .ajax, and subscribe to its submit event". You wouldn't want to try and wire up to events of DOM elements until the DOM is done processing. They might not "exist" yet as far as the browser is concerned if it is in the middle of processing the DOM, and thus your attempt to wire up to the click/form submit events may fail. I say may because depending on timing/processing lag it may sometimes work and sometimes not.
There's not only nothing wrong with putting all your code into one $(document).ready(), but there's nothing wrong with putting it into multiple $(document).ready() functions either so that you can separate repeated functionality into individual JS files.
For example, I use $(document).ready() in a script included on all my site's webpages to set up UI elements, prevent clickjacking, etc. At the same time, each page regularly has its own $(document).ready() which sets up page specific user interactions.
It is absolutely OK. If you find yourself needing to abstract your code into multiple function or multiple files, then by all means, but there's nothing wrong with throwing everything in $(document).ready().
I am loading data into the flexigrid. I am trying to use JQuery selectors to make the rows clickable, but I am unable to do so. I want to know if the element has been fully loaded, how do I do that?
I want to do something like if(element.load == true){//do this}. I am not sure of how to check that out. Could anybody help me with this.
Ok, so I already have this div, and am binding a flexigrid to that div. I want to know if the flexigrid has been bound.
$("#GridLoad").flexigrid();
I want to know if the flexigrid has been bound, after that, I need to run a piece of code.
Using a live() on div Gridload would always be true as it is already there. :(
I want to know if the element has been fully loaded?
There appears to be an onSuccess callback.
$("#GridLoad").flexigrid({
'onSuccess': function() {
// Do this.
}
});
Otherwise, if the things you are binding are being lost when the table updates, attach the events via on() or simply capture them at the persistent ancestor element and examine event.target.
You can use $(element).live('click', function () { // do something });
so that if it later loads it'll have the appropriate event binding.
you could use the callback function of jquery's load method.
like so :
$('#result').load('ajax/test.html', function() {
alert('Load was performed.');
});
Even if you are not using 'load' method, almost any method in jquery supports callbacks which happen after the functionality has been completed.
For example, ajax() has success and failure callbacks, animations has callbacks, etc.