johny7: jQuery - Objekte aneinander hängen

Moin allerseits,

in jQuery gibt es Methoden, die ein Objekt-Set zurückgeben, so z.B. wenn ich $('div') aufrufe und in meinem HTML mehrere divs vorhanden sind.

Jetzt bin ich dabei, eine eigene Funktion zu schreiben, die auch ggf. so ein Objekt-Set zurück gibt.

z.B.

  
jQuery.fn.myfilter = function(str)  
   {  
   var retObj = {};  
   $(this).find(str).each(function()  
      {  
      if ($(this).hasClass('hallo'))  
         retObj = $(this);  
         // Hier wird jetzt retObj einfach überschrieben.  
         // Wie mache ich es aber, dass es angehängt wird, damit am Ende ein Objekt-Set herauskommt?  
      }  
   );  
   return retObj;  
   }  

Ich brauche das allerdings nicht, um eine Filter-Funktion zu programmieren, sondern um ab zu fragen, ob sich zwei Flächen berühren/kollidieren. Vielleicht gibt es dazu schon eine Funktion, dann wäre ich euch dankbar für einen Hinweis.

Grüße, JN

--
ie:{ fl:( br:^ va:| ls:[ fo:| rl:? n4:? ss:| de:] js:| ch:? sh:( mo:| zu:)
http://www.johny7.de
  1. in jQuery gibt es Methoden, die ein Objekt-Set zurückgeben, so z.B. wenn ich $('div') aufrufe und in meinem HTML mehrere divs vorhanden sind.

    Vorweg ich bin kein jquery experte, aber das ist soweit ich weiß nicht richtig. Die Methoden geben das jquery Objekt zurück, aber $() erstellt eine Objektliste, die dann im weiteren verlauf genutzt wird.

    Daher müßte eigentlich das ausreichen:

    jQuery.fn.myfilter = function(str)  
    {  
        return $(this).find(str).hasClass('hallo'));  
    }  
    
    

    Struppi.

    1. return $(this).find(str).hasClass('hallo'));

      hasClass ist keine Filterfunktion, sondern untersucht alle Elemente in der Liste und gibt einen Boolean zurück. Also true, wenn ein Element darin zur angegebenen Klasse gehört (»Determine whether any of the matched elements are assigned the given class«).

      Eine Filterfunktion wäre z.B. filter(".hallo").

      Mathias

  2. hi,

    jQuery.fn.myfilter = function(str)
       {
       var retObj = {};
       $(this).find(str).each(function()

    Es gibt bei jquery einen Artikel zum Plugin-Authoring, den solltest Du dringend lesen. Wichtig ist immer die dieser Aufbau:

    return this.each(function() {
                ...
            });

    damit die Verkettung der Methoden erhalten bleibt. Dein Versuchaufbau, der also alle Elemente der Klasse "hallo" unterhalb bestimmter Eltern rausfiltert sähe in Kurzform etwa so aus:

    <!DOCTYPE html>
    <html>
    <head>
    <script type="text/javascript" src="HIER DEIN JQUERY"></script>
    <script type="text/javascript">
    (function($){
        $.fn.myfilter = function(str) {
            return this.each(function() {
                $(this).find(str + ".hallo").each(function() {
                    $.myfilter.store.push( $(this).html() );
                });
            });
        };
        $.myfilter =  {
            store:[]
        };
    })( jQuery );

    $(document).ready(function(){
        $("div").myfilter("p");
        alert($.myfilter.store.toSource())
    });
    </script>
    </head>
    <body>
        <div>
            <p>2</p>
            <p class="hallo">3</p>
            <p>4</p>
            <p class="hallo">5</p>
        </div>
        <div>
            <p>x</p>
            <p class="hallo">y</p>
            <p class="hallo">z</p>
        </div>
    </body>
    </html>

    Gruesse, Joachim

    --
    Am Ende wird alles gut.
    1. $("div").myfilter("p");
          alert($.myfilter.store.toSource())

      Man würde erwarten, dass myfilter() die Resultate als jQuery-Wrapper zurückgibt, nicht dass man sie noch aus einem dritten Objekt holen muss.

      Dafür reicht doch folgendes aus:

      jQuery.fn.myfilter = function (str) {  
         return $(this).find(str + ' .hallo');  
      };
      

      Wenn ich jetzt myfilter aufrufe, bekomme ich ein jQuery-Objekt zurück und die »Chainability« bleibt erhalten.

      Verstehe ich gerade etwas falsch oder wieso der Umweg?

      Mathias

      1. return $(this).find(str + ' .hallo');

        Sorry, natürlich ohne Leerzeichen im Selektor: '.hallo'. Wie du auch geschrieben hast.

      2. Hi,

        Verstehe ich gerade etwas falsch oder wieso der Umweg?

        Naja, das Testproblem lässt sich ja sogar noch einfacher lösen:
        $("div p.hallo");

        ... findet alle in divs steckenden p-tags der Klasse "hallo". Aber mir gings ja eher darum, ihn auf die grundsätzlichen Strukturen beim Pluginbauen zu stossen...

        Gruesse, Joachim

        --
        Am Ende wird alles gut.
        1. Aber mir gings ja eher darum, ihn auf die grundsätzlichen Strukturen beim Pluginbauen zu stossen...

          Okay. Der Fehler von johny7 war ja, dass er bloß ein nacktes Objekt anstatt eines jQuery-Objekts zurückgegeben hat. Also wäre eine direkte Antwort:

          jQuery.fn.myfilter = function(str)  
             {  
             var retObj = jQuery(); // erzeuge leeres jQuery-Objekt, [link:http://api.jquery.com/jQuery/#returning-empty-set@title=ab jQuery 1.4]  
             $(this).find(str).each(function()  
                {  
                if ($(this).hasClass('hallo'))  
                   // Hier wird jetzt retObj einfach überschrieben.  
                   // Wie mache ich es aber, dass es angehängt wird, damit am Ende ein Objekt-Set herauskommt?  
                   retObj = retObj.[link:http://api.jquery.com/add/@title=add](this); // so geht es --molily  
                }  
             );  
             return retObj;  
             }
          

          Wie gesagt, das ist natürlich so ineffizient, es geht nur um das Prinzip des Zusammenbauens eines jQuery-Objekts.

          Was diesen Code angeht:

          (function($){  
              $.fn.myfilter = function(str) {  
                  return this.each(function() {  
                      $(this).find(str + ".hallo").each(function() {  
                          $.myfilter.store.push( $(this).html() );  
                      });  
                  });  
              };  
              $.myfilter =  {  
                  store:[]  
              };  
          })( jQuery );
          

          Anstelle von each will man beim Filtering ja mehr eine map-Operation:

          $.fn.myfilter = function (str) {  
             return this.[link:http://api.jquery.com/map/@title=map](function () {  
                return $(this).find(str + ".hallo");  
             });  
          };
          

          Auch das wieder nur zur Veranschaulichung. Da das jQuery-Objekt selbst eine Liste ist, ist jede Filteroperation als map() umgesetzt. Deshalb macht obiger Code dasselbe wie das besagte kurze return $(this).find(str + ".hallo").

          Mathias