I'm writing a search function in JavaScript and am having some troubles with it. Currently, I'm using the help of jQuery for ease-of-use on my momentarily retarded brain.

The function I'll be using as a starting point will, indeed, be using the jQuery library. However, I would much rather know how to do this in JavaScript, so code responses in either vanilla or jQuery will most certainly suffice. This code, after all, is going into a large jQuery plugin I'm writing.

So, the function is supposed to search the current page for a DOM element containing a specified class and return it only after it has passed up a specified element.

Do explain this further:

Code:
<html>
     <body>
          <article>
               <header>
                    <h1 class="myclass" id="a">An Article's Title!</h1>
                    <span>Posted at 00.00 on January 0th, 3034</span>
               </header>
               <p class="myclass" id="b">BLARGH BLARGH BLARGH</p>
               <p class="myclass">Lorem Ipsum</p>
               <blockquote><p class="myclass" id="c">Dolor sit amit</p></blockquote>
               <p class="myclass">Lipsum</p>
          </article>
     </body>
</html>


I want to scan <article> to find the next element with the class `myclass` starting from the element with either id `a`, `b`, or `c` (which ever one I pass through the function).

Static variables:
  • Class name,
  • <article> (element to begin search in)
Dynamic variables:
  • Start element (either ID: `a`, `b`, or `c`),
  • The element found

Code:
function nextMyClass(obj) {
   if(obj==false) temp = $('article').children()[0];
   else temp = obj;
   while((typeof temp).toUpperCase()=="OBJECT") {
      if(temp===startElement) {
         $flag = true;
      } else if($flag===true) {
         if($(temp).hasClass('myclass')) {
            return temp;
         } else if((typeof temp.children()[0]).toUpperCase()=="OBJECT") {
            temp2 = nextMyClass(temp.children()[0]);
            if(temp2!==false) return temp2;
         }
      }
      temp = temp.next();
   }
   return false;
}
The above function will do the trick... only if the start element is one of the immediate children of the <article> element.


[edit] My Ramblings...
Quote:
I think the problem right now is: "How do I pass the flag?!"... Because if I can pass the flag then the current function will work... But I don't want to clutter the code with more function params containing the current flag... Or would that be the logical way? Just add another argument that carries the flag? But the other problem is retrieving the flag without ruining the default output of OBJECT or BOOL... Unless of course I assign the flag to an element in the object returned (whether false or the object.flag = true|false)

I just don't think it has to be that complicated... am I wrong? :/
The standard method would indeed be just adding a second parameter to your function. Multiple parameters is an important part of functional languages, and is still used extensively with object-oriented languages (instead of constructing a single argument object of some sort, which seems to be something you're considering).
For those of you who would like to know how to do this, I finished the code here:


Code:
// Set the starting position for the search
var myStartObj = $('#a');

function nextMyClass(obj,flag) {
   // Check to see if this was called within itself
   if(obj==false) // If not, set the temp object with the parent tag
      var temp = $('article').children();
   else // If so, continue searching within the children of the supplied object
      var temp = $(obj).children();

   // Count all the children
   var count = ($(temp).size());

   for(var i=0;i<count;i=i+1) {
      var o = temp[i];

      // Make sure there's something in there!
      if($(o).length > 0) {

         // Check to see if we have found our starting point
         if($(o)[0] == $(myStartObj)[0]) {
            flag = true; // If so, let everyone know the hunt has begun!
         } else

         if(flag===true) {
            // If the hunt has started,
            // check to see if the next
            // element contains the class!
            if($(o).hasClass('myclass'))
               return $(o); // Return the found class, if so!
         }

         // Check to see if the current element has children
         var c = $(o).children();
         if($(c).size() > 0) {
            // If so, check inside those too!
            var r = nextMyClass($(o),flag);
            if((typeof r).toUpperCase() == "BOOLEAN")
               // If it returned a boolean, then it's just passing the flag
               // Meaning the element has not yet been found!
               flag = r;

            else if($(r).size() > 0)
               // We found the next instance! Let's return it.
               return $(r);
         }
      }
   }

   // Check again to see if this function has been called inside itself
   if(obj==false)
      return false; // If not, return false. No luck finding it :(
   else
      return flag; // If it has been, then pass the flag!
}


Anyone up for some optimizations/suggestions? Smile
Assuming that Javascript has ternaries, which I believe it does, the last four lines could be
Code:
return obj?flag:false;
You also use the triple-equal (===) binary comparison operator in one place, but only there; why the inconsistency? Smile
Kerm, Ironically I made all those changes after I posted that. I posted up the source and went through the list of optimizations. The first one I did was change the return to a ternary actually ^^,

And the inconsistency is only because `obj` is not a definite boolean. It's either a boolean or an object. Object==false can still return true even if the Object is not a boolean. Smile
The `flag`, however, is a definite boolean and it remains that way.

Am I right? Or would it still make sense to use the triple-equal comparison operator in both places?
Nope, you're absolutely right about that, glad you used it with proper knowledge of what it's for. Smile Good job!
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement