jQuery einbinden

Hallo,

 

ich glaube ich bin unfähig, ein eigenes jQuery-Script einzubinden… wo gehört das hin?

Habs schon inline versucht… habs im Header versucht und auch im Block “frontend_index_header_javascript_jquery_lib” in der index.tpl.

Jedes mal ist “jQuery” nicht bekannt an der Stelle wo mein Script ist…

wie macht mans denn richtig?

Hi FloC3,

du willst jQuery Code direkt im Template einbinden? Das machst du am besten über die Theme.php und fügst dort ein eigene File hinzu (Anleitung HIER). Wenn du es unbedingt im Code machen möchtest, musst du darauf achten das vor deinem Code Aufruf die /web/cache/*.js File geladen wurde - sonst wurde noch kein jQuery eingebunden.

Falls dies der Fall ist, einfach:

(function ($) {
   Do stuff
})(jQuery);

 

 

 

Zuerst einmal kommt es darauf an, wo du die Funktion aufrufen möchtest.
Du suchst dir die entsprechende tpl-Datei der Seite heraus, die du erweitern möchtest und musst dann sicher stellen, dass die Seite geladen und JQuery bereits bereit sind.

Die Erweiterung fügst du dann natürlich in der tpl deines eigenen Themes durch.

 

{extends file="parent:frontend/[FOLDER]/[TPLNAME].tpl"}

{block name="frontend_index_header_javascript_jquery" append}


   function YourFunction() {
      ~Your Function Code~
   }; 


   window.addEventListener('load', onloadEvent, false);
   function onloadEvent(){
	$( document ).ready(function() {

	    // Führt deine Funktion einmalig nach Seitenaufruf aus
	    YourFunction();
	    
	    // Registriert sich auf bestimmte Events und führt dann deine Funktion aus 
	    $.subscribe('plugin/swAjaxVariant/[EVENT]', function() {
		YourFunction();
	    });

	});
   }

	

{/block}

Das ist dann auch schon alles~

@PStadtfeld‍

ich habs jetzt genau so gemacht wie du sagst. Ich hab in der index.tpl den Block " frontend_index_header_javascript_jquery" appended.

 

 {block name="frontend\_index\_header\_javascript\_jquery" append} <script type="text/javascript">
        $(document).ready(function() {ldelim}
            ...
        {rdelim});
    </script> {/block}

 

Ergebnis: ReferenceError: $ is not defined (wie bisher auch schon) …

Hallo @FloC3‍,

schau doch mal in deinen Theme-Einstellungen, ob du das „Asynchrone Laden von Javascript Dateien“ aktiviert hast.
Dies sorgt dafür, dass unsere Javascript-Dateien, inklusive der jQuery Library,  asynchron  nachgeladen werden.
Dein Javascript Code in einer Template-Datei wird jedoch  sofort  geladen, sobald das Document ready ist.

Solltest du das asynchrone Laden aktiviert haben, musst du deinen Code quasi so aufrufen:

document.asyncReady(function () {
   [dein Code hier]
});

Dazu hier die Implementierung der o.g.  asyncReady  Funktion.
Übrigens:Wenn du deinen Code durch das Theme einbindest, so wie von @Misengo‍ vorgeschlagen, dürfte es auch ohne  asyncReady  funktionieren.

Gruß,
Patrick  Shopware

d.h. via das Theme kann ich beliebig jQuery einbinden?

@FloC3‍ wenn du viel Code hast, macht es auf jeden Fall Sinn es über die Theme.php zu managen. Wir haben dafür eine overload.js, welche all unsere Änderungen enthält, die in den meisten Fällen überall benötigt werden.

 

[@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl “Patrick Stahl”)‍ funktioniert asyncReady auch schon in Versionen unter 5.3? Eventuell hat FloC3 die Version noch nicht.

@Misengo‍
Nein, gibt es erst ab 5.3.

Der Fehler, den Flo bekommt, deutet jedoch sehr stark darauf hin.
Ansonsten müsste sein Beispiel, bzw. sein genutzter Block, bereits einwandfrei funktionieren. :slight_smile:
Zumindest, sofern ich nichts übersehen habe.  Sticking-out-tongue

@all​

mit dem asyncReady funktioniert es nun einwandfrei, vielen Dank für den Tipp!

 

es handelt sich nur um ein paar Tests die ich schnell machen wollte, da war mir das mit dem Theme.php zu viel Aufwand :smiley:

Freut euch nicht zu früh!!!

asyncReady = Problem gelöst? Nicht so ganz.

Früher gab es ein Smarty-Block für javaScript. Da hat auch JQuery funktioniert. Dann kam ein Update und JQuery hat im dem Block nicht mehr funktioniert. Warum? Ach ja, es gab dann ein Smarty-Block extra für Jquery. Toll, alle Shopware-Projekte anpassen, danke! Dann kamm wieder ein Update, sodass auch in dem neuen JQuery-Block dein Code nicht mehr funktioniert hat. Wie mache ich den jetzt mein JQuery??? Na klar. Über  asyncReady. Danke, nochmal alle Shopware Projekte anpassen. 

Und warum ist das Problem nun nicht gelösst? Weil der asyncReady-Dreck nicht im FireFox funktionert! IE? geht. Chrome? Na klar, auch. FF? Wirft keinen Fehler. Nicht in der Konsole, nirgens! Nicht ein mal ein Warning!

Und mir ist schon klar das hier wahrscheinlich FF Mist gebaut hat. Oder vielleicht habe ich auf allen meinen drei Umgebungen eine unglückliche Pluginkonstellation… Das hilft mir aber nicht!!! Wie viel wollt Ihr JQuery denn noch verstecken und einschränken??? Ich muss mit JQuery Listener definieren, oder den verdamten Shop komplett umschreiben, weil ich in der Vergangenheit davon ausging, dass ich im Frontend Jquery nutzen kann.

Vorschlag für Shopware 6.0: Jquery nur zwischen 22:00 und 23:00 ausfühbar machen. Alles andere wäre für uns doch viel zu leicht!

 

@ruppert‍ Geht es auch etwas konstruktiver ohne solch ein gekeife? Das hier ist ein Forum, wo Menschen in Ihrer Freizeit versuchen anderen zu helfen. Solche Beiträge bringen hier überhaupt nichts. Und ein Update musst du auch nicht zwingen vornehmen. Aber es gibt nun einmal Änderungen und Neuerungen, wo man ggf. Anpassungen vornehmen muss. Ich weiß gar nicht wie du dir das vorstellst. Alles beim alten lassen, damit man bloß keine Änderungen vornehmen muss oder wie? Das gehört nun einmal dazu.

Zu deinem Problem:

Ich vermute mal eher, dass du dein Script falsch eingebunden hast. Davon abgesehen ist ein Shopware jQuery Plugin natürlich immer die erste Wahl.

asyncReady funktioniert auch ohne Probleme im Firefox.

frontend/index/index.tpl

{block name="frontend_index_javascript_async_ready"}
    {$smarty.block.parent}
    
        document.asyncReady(function() {
            if ('undefined' == typeof window.jQuery) {
                alert('nope');
            } else {
                alert('yep');
            }
        });
    
{/block}

 

@christiantrade ich gebe dir teileweise recht. Ich habe mich gestern hier ausgekotzt und möchte nun auch produktiv etwas beitragen. Im übrigen bin ich jedem dankbar der hier Beiträge schreibt. Davon habe ich selbst schon hundert mal profitiert. Meine Wut richtete sich keines wegs an die freiwilligen Helfer hier, sondern an die Art und Weise, wie der Zugriff auf JQuery immer weiter eingeschränkt wird. Und doch, ich stehe immer noch zu meiner Aussage - das Konzept (asyncReady) funktioneriert nicht in FF. Bzw. es ist sogar schlimmer - es funktionert in etwa 40% der Ausführungen, sodass man das Problem, unter Umständen nicht einmal erkennt. Zum Problem:

Jquery wird asynchron geladen:

irgendwann später versucht man darauf zu reagieren wenn der Script geladen wurde:

document.getElementById('main-script').addEventListener('load', function() {...

So. Was kann jetzt schief gehen? Zumindest im FF kommt es in mehr als der Hälfte der Fälle vor, dass bevor der “load”-Listener erstellt wird, der asynchrone Script bereits geladen ist. Und dann macht der Listener entsprechend nichts!

Es war verdammt schwehr es herauszufinden (daher die Emotionen oben ). Wir haben uns nämlich, wie du, “Hello World”-Beispiele gebaut und die haben alle samt funktioniert! Jedes mal! In einem richtigen Shop hat man aber viele Plugins die an diesen Stellen eingreifen, so dass der “Abstand” zwischen der beiden Codezeilen oben groß wird. Für FF ist der “Abstand” scheinbar groß genug den Script “zu schnell” zu laden, noch bevor der Listener überhaupt aktiv ist. Wir haben viel ausprobiert und sind auf eine Lösung gekommen, mit de wir leben können. Unsere Lösung ist mit “setTimeout” auf Jquery zu warten:

      var tmrJQIterations = 0;
      function waitForJQ() {
      	tmrJQIterations++;
      	if (window["$"]) {
      		console.log("jQuery available :-)");
      		console.log("main-script: " + $("#main-script").attr("src"));
      	} else {
      		console.log("waiting for jQuery :-|");
            if (tmrJQIterations < 100) {
                setTimeout(waitForJQ, 100);
            } else {
            	console.log("no jQuery found :-(")
            }
      	}
      }
      setTimeout(waitForJQ, 1);

Ich hoffe das hilft auch Anderen.

@ruppert‍ Was willst du denn genau überhaupt machen?

Und wo vor allem wo, in einer Einkaufswelt oder dergleichen?

Davon ab: Du verwendest oben doch gar kein jQuery, das ist reines Javascript. 

Nehm hier mal window.addEventListener statt document.

Und wie gesagt: asyncReady funktioniert ohne Probleme. Wie lautet denn dein kompletter Code inkl. Einbindung.

Was willst du denn genau berhaupt machen?

Ich möchte per Jquery Eventlistener auf meine, selbstgeschriebene UI-Elemente definieren.

Und wo vor allem wo, in einer Einkaufswelt oder dergleichen?

In meinem konkretem Fall geht es ums Checkout. Im letzten Bestellschritt holen wir von Kunden Zusatzinfos ein.

Davon ab: Du verwendest oben doch gar kein jQuery, das ist reines Javascript. 

Schau dir bitte diese Codezeile an:

console.log("main-script: " + $("#main-script").attr("src"));

An dieser Stelle ist Jquery “nutzbar”. Das oben ist na klar nur ein Beispiel. In meinem Projekt definiere ich hier meine Listener.

Nehm hier mal window.addEventListener statt document.

Wo soll ich das verwenden? Meinst du anstelle von “document.getElementById(‘main-script’).addEventListener(‘load’, function() {…” ? Meinst du, ich soll die “asyncReady”-Implementierung von Shopware überschreiben? Ich glaube nicht, dass es von den Shopware-Entwicklern so gedacht war, dass man diese Stelle anpasst.

Und wie gesagt: asyncReady funktioniert ohne Probleme.

Wir haben einen Mordsaufwand gehabt das Problem zu analysieren. Ich habe das Problem oben genau beschrieben. Du darfst gerne bei deiner Meinung bleiben.

@christiantrade schrieb:

Ich vermute mal eher, dass du dein Script falsch eingebunden hast. Davon abgesehen ist ein Shopware jQuery Plugin natürlich immer die erste Wahl.

asyncReady funktioniert auch ohne Probleme im Firefox.

frontend/index/index.tpl

{block name=“frontend_index_javascript_async_ready”}
{$smarty.block.parent}

document.asyncReady(function() {
if (‘undefined’ == typeof window.jQuery) {
alert(‘nope’);
} else {
alert(‘yep’);
}
});

{/block}

Ich habe meine Scripts genau so eingebunden und muss ruppert Recht geben, dass das im FF leider nicht immer funktioniert (in ca. 10% der Fälle wird der Code im Block vor dem Laden des main-scripts ausgeführt).