I have a custom.js file in which I have several elements that have 开发者_高级运维click and other methods bound to them. The entire file is encapsulated in document.ready() and everything works. However when I do an AJAX post obviously document.ready() is never fired again for the current page. Is there anyway I can get document.ready() to fire again or do I need to have everything in named functions call them form my create.js.erb?
You could always just put everything in one function (named loadfunction or something) and call that function when the document loads, and again when the ajax is loaded. Though it is a hacked together solution, it should work well enough.
So then take everything between $(document).onready(function () {
and its end bracket }
And put it in function OnloadFunction () {
ending with }
.
Then put $document.onready(OnloadFunction);
Example: You have
$(document).ready(function () {alert("test");});
It would turn into:
function OnloadFunction ()
{
alert("test");
}
$(document).ready(OnloadFunction);
Then you can call OnloadFunction
whenever you want to.
Combining Ben and fotanus' answers I created the following pattern:
$(document).ready(function () {
AjaxInit()
});
$(document).ajaxComplete(function () {
AjaxInit()
});
function AjaxInit() {
alert("test");
}
There is a event that triggers after every ajax call. It is called ajaxComplete.
$( document ).ajaxComplete(function() {
$( ".log" ).text( "Triggered ajaxComplete handler." );
});
I've successfully used a pattern like the following:
First off we must define a .query() plugin.
// jQuery.fn.query() emulates the behavior of .querySelectorAll()
// by allowing a full/complex selector to be matched against
//a small slice of the dom.
$.fn.query = function ( selector ) {
var scopeElms = this,
scopeIsDoc = scopeElms.length === 1 && scopeElms.is('html') ,
// check for obviously simple selectors.... (needs more elegance)
isComplexSelector = /\s/.test( selector.replace(/\s*([|~*$\^!]?=|,)\s*/g, '$1') ),
elms;
if ( scopeIsDoc || isComplexSelector )
{
elms = $(selector);
if ( scopeElms[0] )
{
elms = elms.filter(function(){
var i = scopeElms.length;
while (i--) {
if ( scopeElms[i] === this || $.contains(scopeElms[i], this) )
{
return true;
}
}
return false;
});
}
}
else
{
elms = scopeElms.filter( selector )
.add( scopeElms.find(selector) );
}
return $(elms);
};
We then write our init function and bind it to the "ready" event, and also to our custom "domupdated" event. Within the init function we use .query()
to find elements from either the whole document or just the updated fragment...
// Here we define our DOM initializations
$(document).bind('ready domupdated', function (e, updatedFragment) {
var root = $( updatedFragment || 'html' );
// Begin imaginary initialization routines
root.query('form').validate();
root.query('.sidebar .searchform input#search').autocomplete();
// etc...
});
Then whenever we inject blocks of new elements into the DOM (like when an Ajax request has finished) we then trigger the domupdated
event and pass the updated DOM fragment as a parameter - like so:
...
var ajaxedDom = $(xhr.resultText).find('#message');
ajaxedDom.appendTo( '#modal' );
$(document).trigger('domupdated', [ajaxedDom]);
For me, this set up takes all the pain out of initing the DOM. It allows me to maintain a single set of init routines, and focus on the fun things.
Minor twist on Ken Mc's answer. For whatever reason my ajaxComplete would not fire unless it was nested within a document.ready. Nesting it inside and still calling out worked for me.
$(document).ready(function () {
AjaxInit();
$(document).ajaxComplete(function () {
AjaxInit()
});
});
function AjaxInit() {
alert("test");
}
I've used some trick. ;) All code is inside loaded part of file (ajax). I don't use any 'success', 'done' or etc. extended functionall of jquery ajax load.
First we must build any function. For Example: _autostart();
function _autostart() {
... all code here ....
}
On the body we will paste all js code what we have to execute at the end of ajax load.
Then we just execute this function by the time trigger. ;)
setTimeout("_autostart();",0000);
And that's all. Done. :)
Of course we can use js code function on any event in html code after ajax. For example: 'onchange', 'onclick', etc. It's work too. :)
I tried Jess's, Ken Mc's, and byork2005's answers, and nothing worked. The only method that worked for me was to user jquery's .trigger
function. For that, the 'ready' handler must be called with .on
. That makes it possible to later trigger the event manually. See the docs for .trigger.
$(document).on('ready myFunction',function(){
(blah blah)
Rails.ajax({
(blah blah)
success: function(result) {
$(document).trigger('myFunction');
}
});
});
$(document).trigger('myFunction');
Now myFunction
is triggered both on document ready, and on successful ajax calls. Another way to trigger the function is to use
$(document).trigger('myFunction');
anywhere on the page, or even in the console. Be aware of this, and think about security.
精彩评论