2012-04-11 13 views
0

Für dieses Projekt habe ich eine Box (div), mit einigen statischen Inhalt (einschließlich Tabs) und Inhalt, die unter einer Vielzahl von Bedingungen ändern können (click, hover, und Timer). Jede dieser dynamischen Inhaltsansichten liegt in einem separaten div.JQuery: Einblenden nach dem Ausblenden mehrerer Objekte führt zu Flimmern

Ich versuche, eine Funktion zu schreiben, die alle diese Fälle behandeln kann, einschließlich der anfänglichen Belastung der Seite, da der gesamte dynamische Inhalt zunächst mit CSS ausgeblendet wird. Diese Funktion verwendet die übergeordnete Box, die geändert werden muss, um den Überblick zu behalten, und die Ansicht, zu der ich wechseln möchte.

Also verblasse ich zuerst alle Ansichten aus, um sicherzustellen, dass nichts da ist, und verblasse die neue Ansicht. Ich merkte ziemlich bald, dass der Callback nicht wie bestellt funktionierte, also lief ich über die Funktion promise() . Leider flackert dies in jedem Browser, den ich ausprobiert habe (IE, Chrome und Firefox). In Chrome war es nur gelegentlich, aber in den anderen ist es fast konstant.

$(container).children('.content_view').fadeOut(transition); 
$(container).children('.content_view').promise().done(function() { 
    $(next).fadeIn(transition); 
}); 

, die im Moment das Geschäft Ende meines Code. Gibt es einen besseren Weg, dies zu tun, oder eine Möglichkeit, das Flimmern zu beseitigen? Leider wird diese Seite hauptsächlich in den Browsern angezeigt, die sich schlecht benehmen.

Nach herumspielen mit Verzögerungen, vermute ich, dass das Problem ein Timing ist. Das vorzeitige Entfernen eines Elements oder das Erscheinen eines anderen Elements bewirkt, dass sich mein Layout vorübergehend ändert, bis das endgültige Layout erreicht ist. Ich vermute, dass die Funktion promise() eine solche Verzögerung implementiert.

EDIT:

ich eine Lösung gefunden, die gut für mich zu arbeiten scheint. Da mein anfängliches Ausblenden das Ereignis behandeln sollte, dass mehrere Ansichten irgendwie eingeblendet wurden (was aus anderen Gründen sehr häufig vorkam, benutze mouseenter und mouseleave statt mouseover und mouseout), entschied ich, dass es besser wäre, einfach sofort zu töten alles, was gerade von einem vorherigen Anruf verblasst, dann mache ich mein normales Fading:

$(container).children('.content_view').filter(function(){return ($(this).css('opacity') < 1)}).each(function() { 
    $(this).stop(); 
    $(this).css('opacity',0); 
    $(this).css('hidden','none'); 
}); 

if ($(container).children('.content_view').filter(function(){return ($(this).css('display') != 'none');}).length > 0) 
    $(container).children('.content_view').filter(function(){return ($this.css('display') != 'none';}).fadeOut(transition, function() { 
    $(content).fadeIn(transition); 
}); 
else 
    $(content).fadeIn(transition); 
$(container).children('.content_view').filter(function(){return ($(this).css('opacity') < 1)}).each(function() { 
    $(this).stop(); 
    $(this).css('opacity',0); 
    $(this).css('hidden','none'); 
}); 

if ($(container).children('.content_view').filter(function(){return ($(this).css('display') != 'none');}).length > 0) 
    $(container).children('.content_view').filter(function(){return ($this.css('display') != 'none';}).fadeOut(transition, function() { 
    $(content).fadeIn(transition); 
}); 
else 
    $(content).fadeIn(transition); 

Hoffnung, die Sinn macht. Ich kannte die Filterfunktion vorher nicht. Ziemlich handlich :)

Beachten Sie, dass dies in meinem Fall funktioniert, weil dies der einzige Weg ist, dass der Inhalt ausgetauscht wird, und es nur einen Elementbaum vollständig sichtbar (oder immer dort) am Ende von jedem verlassen wird Anruf. Wenn dies nicht durch die nächste enthüllt wird, wird es sofort getötet und ersetzt.

+0

Können Sie eine JSFiddle zusammenstellen, die das repliziert? – Jon

+0

Ich versuche es. Ach je. Scheint viel abzustürzen: P – user1215288

Antwort

0

sollte diese Arbeit:

$(container).children('.content_view').fadeOut(transition, function() { 
    $(next).fadeIn(transition); 
}); 

dann versuchen:

$(container).children('.content_view').each(function(){ 
    $(this).fadeOut(transition, function() { 
     $(next).fadeIn(transition); 
    }); 
}); 

jedoch wahrscheinlich die schönste Lösung CSS-Übergänge würden zu verwenden. Ist das eine Möglichkeit? Auf welchem ​​Browser muss das funktionieren?

+0

Das war mein erster Gedanke, aber da der Selektor mit mehreren Elementen übereinstimmt, wird die Callback-Funktion sofort ausgeführt. – user1215288

+0

ok Ich habe etwas anderes hinzugefügt. Welcher Selektor ist das Problem? .content_view oder $ (nächstes)? – Gavriel

+0

$ (nächste) ist nur das Objekt, das ich übergebe. Es stellt das Wurzelelement dar, das ich einfügen möchte. Dieses Element gehört zur Klasse content_view, wie auch alle anderen Ansichten, zwischen denen ich wählen kann. Die zweite Lösung führt zu einem ungeraden blinkenden Effekt, der sich mit einem anfänglichen Überblenden überschneidet. Die dritte macht das selbe, aber scheint inhaltliche Ansichten dort zu hinterlassen, nach denen ich nie gefragt habe. Ich nehme an, next() bewegt sich zum nächsten Geschwisterknoten? Das könnte dieses Verhalten verursachen – user1215288

Verwandte Themen