Ich habe eine custom.js-Datei, in der ich mehrere Elemente habe, an die Clicks und andere Methoden gebunden sind. Die gesamte Datei ist in document.ready () gekapselt und alles funktioniert. Wenn ich jedoch einen AJAX -Posten mache, wird document.ready () nie wieder für die aktuelle Seite ausgelöst. Gibt es trotzdem eine Möglichkeit, dass document.ready () erneut ausgelöst wird, oder muss ich alles in benannten Funktionen von meiner create.js.erb aufrufen?
Sie können immer einfach alles in einer Funktion (mit dem Namen load function oder so) angeben und diese Funktion aufrufen, wenn das Dokument geladen wird und erneut, wenn der Ajax geladen wird. Obwohl es sich um eine zusammen gehackte Lösung handelt, sollte sie gut genug funktionieren.
Nehmen Sie dann alles zwischen $(document).onready(function () {
und seiner Endklammer }
und setzen Sie es in function OnloadFunction () {
und enden mit }
. Dann setzen Sie $document.onready(OnloadFunction);
Beispiel: Sie haben
$(document).ready(function () {alert("test");});
Es würde sich in
function OnloadFunction ()
{
alert("test");
}
$(document).ready(OnloadFunction);
Dann können Sie OnloadFunction
jederzeit aufrufen.
Es gibt ein Ereignis, das nach jedem Ajax-Anruf ausgelöst wird. Es heißt ajaxComplete .
$( document ).ajaxComplete(function() {
$( ".log" ).text( "Triggered ajaxComplete handler." );
});
Durch die Kombination der Antworten von Ben und Fotanus entstand folgendes Muster:
$(document).ready(function () {
AjaxInit()
});
$(document).ajaxComplete(function () {
AjaxInit()
});
function AjaxInit() {
alert("test");
}
Ich habe erfolgreich ein Muster wie das folgende verwendet:
Zuerst müssen wir ein .query () Plugin definieren.
// 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);
};
Wir schreiben dann unsere Init-Funktion und binden sie an das Ereignis "ready" sowie an unser benutzerdefiniertes Ereignis "domupdated". Innerhalb der init-Funktion verwenden wir .query()
, um Elemente aus dem gesamten Dokument oder nur aus dem aktualisierten Fragment zu finden.
// 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...
});
Wann immer wir Blöcke mit neuen Elementen in das DOM einfügen (z. B. wenn eine Ajax-Anforderung abgeschlossen ist), lösen wir das Ereignis domupdated
aus und übergeben das aktualisierte DOM-Fragment als Parameter.
...
var ajaxedDom = $(xhr.resultText).find('#message');
ajaxedDom.appendTo( '#modal' );
$(document).trigger('domupdated', [ajaxedDom]);
Für mich bedeutet dieses Setup, dass der Einstieg in das DOM nicht so einfach ist. Es erlaubt mir, einen einzigen Satz von Init-Routinen zu pflegen und mich auf die lustigen Dinge zu konzentrieren.
Ich habe einen Trick benutzt. ;) Der gesamte Code befindet sich im geladenen Teil der Datei (ajax) . Ich verwende keine 'success', 'done' oder andere erweiterte Funktion von jquery ajax load.
Zuerst müssen wir eine Funktion erstellen. Beispiel: _autostart ();
function _autostart() {
... all code here ....
}
Auf dem Körper werden wir den gesamten js-Code einfügen, den wir am Ende der Ajax-Last ausführen müssen.
Dann führen wir diese Funktion einfach durch den Zeitauslöser aus. ;)
setTimeout("_autostart();",0000);
Und das ist alles. Erledigt. :)
Natürlich können wir die js-Code-Funktion für jedes Ereignis in HTML-Code nach ajax verwenden. Zum Beispiel: 'onchange', 'onclick' usw. Es funktioniert auch. :)
Kleine Änderung an Ken Mc's Antwort. Aus irgendeinem Grund würde mein AjaxComplete nur ausgelöst, wenn er in einem Dokument verschachtelt ist. Es in mich zu schachteln und immer noch zu rufen funktionierte für mich.
$(document).ready(function () {
AjaxInit();
$(document).ajaxComplete(function () {
AjaxInit()
});
});
function AjaxInit() {
alert("test");
}