Suchen
Inside Forum
Nützliche Links




 
phpforum.de bei Facebook
 
phpforum.de bei Twitter
 

Zurück   PHP Forum: phpforum.de > andere (Programmier-)Sprachen > JavaScript

JavaScript Alles rund um JavaScript, Ajax und die diversen JS-Frameworks.

Antwort
 
Themen-Optionen Ansicht
  #1  
Alt 01.08.2017, 17:47
tpk tpk ist offline
Engagierter Besucher
 
Registriert seit: 22.07.2006
Beiträge: 705
Standard Asynchroner Aufruf von Lightbox möglich?

Hi,

ich gebe eine Liste mit Adressen per Ajax aus. Wenn die Liste ausgegeben ist, werden per js noch Karten bei jeder Adresse ausgegeben:

HTML Quellcode:
$('.anbieter_map').each(function(){
 
    var json = $(this).attr('json_map');
    var json_obj = jQuery.parseJSON(json);
 
    var position_obj = {};
    position_obj.lat = parseFloat(json_obj.lat);
    position_obj.lng = parseFloat(json_obj.lng);
 
    var id_map = 'map_'+json_obj.id;
 
    map = new google.maps.Map(document.getElementById(id_map), {
      center: position_obj,
      zoom: 10
    });
 
    var search_position = new google.maps.LatLng(position_obj.lat,position_obj.lng);
    new_marker(map, search_position);
 
 
 
  });


Das braucht bei mir lokal bei 20 Adressen ne ganze Weile, aber da das erst gerechnet wird, wenn die Adressen schon alle sichtbar sind, ist das erst mal nicht so tragisch.

Unschön ist aber, dass darauf folgende JS-Aufrufe abwarten, bis die Karten alle fertig sind. Bei den Adressen kann man eine Lightbox mit mehr Infos aufrufen, deren Inhalt über Ajax kommt. Kann man das asynchron hinkriegen?
__________________
Leben ist das, was geschieht, während man selbst ganz andere Pläne macht.
Mit Zitat antworten
  #2  
Alt 01.08.2017, 18:28
Don T. Worry Don T. Worry ist offline
Engagierter Besucher
 
Registriert seit: 29.03.2012
Beiträge: 467
Standard AW: Asynchroner Aufruf von Lightbox möglich?

Zitat:
Unschön ist aber, dass darauf folgende JS-Aufrufe abwarten, bis die Karten alle fertig sind.
Was sagt denn die Google Doku dazu?
__________________
“Just think of how stupid the average person is, and then realize half of them are even stupider!” [George Carlin]

“There is only one god, and His name is Death. And there is only one thing we say to Death: "not today".” [Syrio Forel]
Mit Zitat antworten
  #3  
Alt 02.08.2017, 16:30
tpk tpk ist offline
Engagierter Besucher
 
Registriert seit: 22.07.2006
Beiträge: 705
Standard AW: Asynchroner Aufruf von Lightbox möglich?

each() wird synchron ausgeführt ...
Ich hab das jetzt mit dem

http://mess.genezys.net/jquery/jquery.async.php

gelöst.
__________________
Leben ist das, was geschieht, während man selbst ganz andere Pläne macht.
Mit Zitat antworten
  #4  
Alt 03.08.2017, 13:46
Kasalop Kasalop ist offline
Forum-Mitarbeiter
 
Registriert seit: 29.12.2006
Ort: München
Beiträge: 5.648
Standard AW: Asynchroner Aufruf von Lightbox möglich?

Zitat:
Zitat von tpk Beitrag anzeigen
each() wird synchron ausgeführt ...
Ich hab das jetzt mit dem

http://mess.genezys.net/jquery/jquery.async.php

gelöst.
Ist ja eine nette Idee, aber wieso unterstützt das each beispielsweise keine Objekte. Es soll hier ja eine jQuery Methode nachgebildet werden, nur in Asynchron. Hätte man einfach bei jQuery geklaut hätte man die funktionalität auch gehabt, es wäre aber dann auch vollständig. so funktioniert es nur für Arrays und bricht ab, da auch eine Überprüfung des Arguments fehlt (isArrayLike von jQuery könnte helfen ).
Weiterhin kann das Script nicht im strict-mode laufen, da es arguments.callee verwendet, was man hier sehr leicht vermeiden könnte.

Würde man diese sachen noch anpassen, dann sieht das ganz nett aus. So richtig asynchron wäre es zwar mMn nur mit Workern, aber setTimeout tuts in den meisten Fällen auch und ist einfacher zu handeln, auch die Unterstützung ist besser.

Lg Kasalop

PS: Ohne "zusatz-lib" hättest du es in deinem Fall einfach lösen können, indem du alles was im funktionsblock des Arguments für das each steht mit einem setTimeout eingefasst hättest.
__________________
Es gibt 10 Arten von Menschen auf der Welt. Die die die binäre Mathematik verstehen und die die sie nicht verstehen!

Zu welcher der Gruppen gehörst du?

Geändert von Kasalop (03.08.2017 um 13:48 Uhr)
Mit Zitat antworten
  #5  
Alt 03.08.2017, 16:48
tpk tpk ist offline
Engagierter Besucher
 
Registriert seit: 22.07.2006
Beiträge: 705
Standard AW: Asynchroner Aufruf von Lightbox möglich?

Ohne Zusatz Lib ist ja immer besser. Hast Du es so gemeint?

Innerhalb von each geht es nun auf eine für mich seltsame Weise asynchron zu.

Das Loggen bei //1 und //2 führt schematisch dargestellt zu diesem Ergebnis (bei 3 Anbietern):

#1 -> //1
#2 -> //1
#3 -> //1
#3 -> //2
#3 -> //2
#3 -> //2

Ich fände diese Ausgabe ja verständlich:

#1 -> //1
#2 -> //1
#3 -> //1
#3 -> //2

Aber wieso dann auch innerhalb von setTimeout 3x durchaufen wird, nachdem die Ausgaben bei //1 schon draußen sind, scheint mir obskur.

Jedenfalls weiß ich nicht, wie ich mit meinen mediokren JS-Kenntnissen das $(this) in das timeout reingewuchtet kriege.


HTML Quellcode:
$('.anbieter_map').each(function () {
    THIS = $(this);
 
    console.log(THIS); // 1
 
    setTimeout(function () {
 
      console.log(THIS); // 2
 
      var json = THIS.attr('json_map');
      var json_obj = jQuery.parseJSON(json);
 
      var position_obj = {};
      position_obj.lat = parseFloat(json_obj.lat);
      position_obj.lng = parseFloat(json_obj.lng);
 
      var id_map = 'map_' + json_obj.id;
 
      map = new google.maps.Map(document.getElementById(id_map), {
        center: position_obj,
        zoom: 10
      });
 
      var search_position = new google.maps.LatLng(position_obj.lat, position_obj.lng);
      new_marker(map, search_position);
    }, 10);
 
  });
 
  });
__________________
Leben ist das, was geschieht, während man selbst ganz andere Pläne macht.
Mit Zitat antworten
  #6  
Alt 03.08.2017, 18:01
Kasalop Kasalop ist offline
Forum-Mitarbeiter
 
Registriert seit: 29.12.2006
Ort: München
Beiträge: 5.648
Standard AW: Asynchroner Aufruf von Lightbox möglich?

Das Verhalten kommt von der Art und Weise wie Scopes in js behandelt werden.
Code:
var i=0;
function foo() {
  i++;
}
alert(i); // 0
foo();
alert(i); // 1

Warum geht das? Weil die Variable i im globalen Scope liegt (könnte auch in einem anderen Scope liegen) und die funktion foo ein unterscope, davon ist. Somit ist i auch in foo gültig (Das wäre nur der Fall, wenn i in foo neudefiniert werden würde. Stichwort: Verschattung).
Dabei ist die Variable i nicht kopiert, sondern es wird auf die Variable im äußeren Scope zu gegriffen.

Was bedeutet das für dein Problem:
Code (Javascript):
for(var i=0;i<5;i++) {
  setTimeout(function() { alert(i); }, 1000); // gibt nach einer Sekunde 5x den Wert 5 aus
}

Die Funktion die an setTimeout übergeben wird, wird im gleichen Scope ausgeführt, wie du sie geschrieben hast. Da i also die gleiche Variable ist, wie des umgebenden Scopes, passiert folgendes: Die for-schleife zählt von 0 bis 5 (bzw. 4, erhöht sich um eins und bricht dann ab, weil die Laufzeitbedingung nicht mehr erfüllt ist). Bei jedem Schleifen durchgang wird per setTimeout festgelegt, dass die funktion in einer Sekunde ausgeführt werden soll. Da die forschleife aber schneller ist und nicht eine Sekunde braucht... Welchen Wert hat dann i zum Zeitpunkt, wenn die funktionen ausgeführt werden?

Wie kann man das lösen. Dafür gibt es 3 grundsätzliche Ansätze, die mir sofort einfallen:
1) Kreiere einen neuen Scope für jeden Funktionsaufruf. Das kann zum Beispiel so aussehen:
Code (Javascript):
for(var i=0;i<5;i++) {
  setTimeout((function() { var j=i; return function() { alert(j); }; })(), 1000);
}

oder:
Code (Javascript):
for(var i=0;i<5;i++) {
  (function() {
    var j = i;
    setTimeout(function() { alert(j); }, 1000);
  })();
}


Zu 1. Hierbei wird durch ein Closure ein neuer Scope erschaffen und innerhalb von diesem wird j mit i belegt, was beim verlassen des Kontext zum kopieren führt. j behält den Wert von i, den es zum Zeitpunkt der Zuweisung hatte.
Zu 2. Kopiert man in js Variablen wird die Variable referenziert, statt kopiert. Erschafft man durch ein Closure allerdings einen neuen Scope, ist das Kopieren möglich.

Beides im Prinzip gleich, nur der neue Kontext (Scope) wird an einer anderen Stelle erschaffen.

2) .bind(), .call() und .apply() kopieren die Argumente. Das heißt, wenn du mit bind i als Kontext für eine Funktion festlegst, dann kannst du per this innerhalb der funktion auf den wert von i zugreifen zum Zeitpunkt des bindings:
Code (Javascript):
for(var i=0;i<5;i++) {
    setTimeout(function() { alert(this); }.bind(i), 1000);
}


3) Welcome to new millenuim. Es gibt seit längerem das Schlüsselwort let in javascript. Das funktioniert sehr ähnlich, wie var, allerdings verhält es sich etwas anders, was den Scope angeht.
Code (Javascript):
for(let i=0;i<5;i++) {
    setTimeout(function() { alert(i); }, 1000);
}

Und arbeitet wie erwartet.
Warum das so ist, kannst du am besten in der Doku nachlesen: https://developer.mozilla.org/en-US/...Statements/let

Ich hoffe damit wird es etwas klarer und du kannst dein Problem auch so lösen. Falls doch noch Fragen offen sind: Immer raus damit.

Lg Kasalop
__________________
Es gibt 10 Arten von Menschen auf der Welt. Die die die binäre Mathematik verstehen und die die sie nicht verstehen!

Zu welcher der Gruppen gehörst du?

Geändert von Kasalop (03.08.2017 um 18:05 Uhr)
Mit Zitat antworten
  #7  
Alt 04.08.2017, 18:41
tpk tpk ist offline
Engagierter Besucher
 
Registriert seit: 22.07.2006
Beiträge: 705
Standard AW: Asynchroner Aufruf von Lightbox möglich?

Zitat:
Falls doch noch Fragen offen sind: Immer raus damit.
Wow, die Closures sind aber wirklich abstrakter Scheibenhonig :-)
Hab mal ein bisschen quergelesen. Zum Anwenden reicht es evtl. schon, aber noch nicht zum ganz Verstehen.

Aber erst mal zum Problem. Die Karten werden jetzt ausgegeben, aber immer noch synchron, d.h., auf Klicks wird erst reagiert, wenn alle Karten geladen sind. Das war mit http://mess.genezys.net/jquery/jquery.async.php anders.


HTML Quellcode:
$('.anbieter_map').each(function () {
    THIS = $(this);
 
    (function () {
      var ANBIETER = THIS;
      setTimeout(function () {
        var json = ANBIETER.attr('json_map');
        var json_obj = jQuery.parseJSON(json);
 
        var position_obj = {};
        position_obj.lat = parseFloat(json_obj.lat);
        position_obj.lng = parseFloat(json_obj.lng);
 
        var id_map = 'map_' + json_obj.id;
 
        map = new google.maps.Map(document.getElementById(id_map), {
          center: position_obj,
          zoom: 10
        });
 
        var search_position = new google.maps.LatLng(position_obj.lat, position_obj.lng);
        new_marker(map, search_position);
      }, 100);
    })();
__________________
Leben ist das, was geschieht, während man selbst ganz andere Pläne macht.
Mit Zitat antworten
  #8  
Alt 04.08.2017, 20:16
Kasalop Kasalop ist offline
Forum-Mitarbeiter
 
Registriert seit: 29.12.2006
Ort: München
Beiträge: 5.648
Standard AW: Asynchroner Aufruf von Lightbox möglich?

Zitat:
Zitat von tpk Beitrag anzeigen
Die Karten werden jetzt ausgegeben, aber immer noch synchron, d.h., auf Klicks wird erst reagiert, wenn alle Karten geladen sind.
Deinem Code fehlt das schließende }); des each-konstrukts. Das ist bei dir schon da, oder?
Pack mal nach dem .each ein alert und schau ob die verzögert ausgegeben wird. Eigentlich sollte es direkt ausgegeben werden, da ja das Laden der Karten durch das setTimeout verschoben wird.
Falls möglich: mach doch bitte eine jsfiddle auf, sodass ich dein Problem an einem Beispiel nachvollziehen kann. Eigentlich kann das nicht sein, was du beschreibst, außer der Fehler liegt in einem anderen Codefragment.

Lg Kasalop
__________________
Es gibt 10 Arten von Menschen auf der Welt. Die die die binäre Mathematik verstehen und die die sie nicht verstehen!

Zu welcher der Gruppen gehörst du?
Mit Zitat antworten


Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.

Gehe zu
Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Asynchroner Zugriff auf Variablen MasseElch JavaScript 4 20.10.2014 11:08
lightbox art John Smith JavaScript 3 09.01.2010 23:23
Lightbox mit php globifrosch PHP 8 14.02.2009 12:07
Lightbox kamp JavaScript 16 19.10.2008 19:53
anhang in mail() moglich? tab in text möglich? robiotor PHP 1 14.04.2003 23:25


Alle Zeitangaben in WEZ +2. Es ist jetzt 15:33 Uhr.


Powered by vBulletin® Version 3.8.8 (Deutsch)
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Powered by NuWiki v1.3 RC1 Copyright ©2006-2007, NuHit, LLC