Pregunta

Lo siento, si esto ya se ha publicado, he estado buscando en vano ...

Solo quiero saber cómo recorrer en bucle los 'elementos' de forma anidada (los elementos no son solo los elementos de forma estricta, como las etiquetas de entrada, sino también otros elementos html) en jQuery. Actualmente tengo este pedazo de código para hacerlo:

$('#'+arguments[i].formid).children().each(function(){ 
    var child = $(this);
    alert(child.attr('id'));
    if(child.is(":input")) { alert(child.attr('id'));
     if(child.attr('id')!='') eval("p."+child.attr('id')+"='"+child.attr('value')+"'"); 
    }

       if(child.is(":textarea")) {
     if(child.attr('id')!='')  eval("p."+child.attr('id')+"='"+child.attr('value')+"'"); 
    }
   });

no funciona cuando mi formulario contiene otros elementos como este:

<form>
    <div id='tabs'>
        <ul>...</ul>
        <div id='tab-1'>
               <input type='text' id='fname' />
               <textarea id='desc' ></textarea>
        </div>
    </div>
</form>

por favor ayuda ...

¿Fue útil?

Solución

Puedes hacerlo en una función recursiva.

function doStuff(child) {
  if(child.is(":input")) {
     ...
  }

  if(child.is(":textarea")) {
    ...
  }
}

function walk(children) {
  if (typeof children == "undefined" || children.size() === 0) {
    return;
  }
  children.each(function(){
    var child = $(this);
    if (child.children().size() > 0) {
      walk(child.children());
    }
    doStuff(child);
  }
}

walk($('#'+arguments[i].formid).children());

EDIT : me acabo de dar cuenta de lo que estás tratando de hacer y puedes dividirlo en esto

var p = {};
$('#'+arguments[i].formid + " input[id], #"+arguments[i].formid + " textarea[id]").each(function(){
  var child = $(this);
  p[child.attr("id")] = child.attr("value");
});

Probablemente debería leer más sobre jQuery selectores .

Otros consejos

Puede usar contents () (y filtrar los nodos de texto si es necesario) o find ('*') para obtener todos los elementos, aunque no me gusta el uso de comodines.

 $('form').contents()
          .filter( function() { return this.nodeType == 1; } )
          .each(...);

o

 $('form').find('*')
          .each(...);

Volví a corregirme :) jQuery Rocks! Así que después de un curso intensivo aquí es lo mismo en jQuery ...

/*
    menu.jq     : main menu jQuery for ekerner.com
    Author      : 'Eugene Kerner' <ekerner@ekerner.com>
    Date        : 16-12-2009
    Dependencies: jQuery javascript lib
                : menu.css
                : an unordered list structure as per the below Example.
                : a javascript call to menu.init(menuId, selectedMenuItemsArray) as per the below Example.
    Notes       : if your menu link has an onclick that returns false then it needs to call menu.init before returning (see Example).
    Example     : -
    <ul id="mainMenu" class="menuItems">
      <li>
        <a href="/">Menu Item</a>
        <ul>
          <li><a href="/webpage" onclick="window.open('/webpage'); menu.init('mainMenu', ['Menu Item', 'Sub Menu Item']); return false;">Sub Menu Item</a></li>
        </ul>
      </li>
    </ul>
    <script type="text/javascript">$(document).ready(function(){menu.init('mainMenu', ['Menu Item'])});</script>
*/

var menu = {
  selectedClass : 'selected',
  animateSpeed  : 'fast',
  selectedLinks : [],
  init : function(menuId, selectedLinks)
  {
    $('#' + menuId).children('li').each(function(){
      var menuItem       = $(this);
      var menuLink       = menuItem.children('a:first-child');
      var subMenu        = menuItem.children('ul:last-child');
      menu.selectedLinks = selectedLinks;
      menu.applySelectedClass(menuLink);
      if (subMenu.length == 1) {
        menuItem.hover(
          function(){menuLink.addClass(menu.selectedClass); subMenu.slideDown(menu.animateSpeed)}, 
          function(){subMenu.slideUp(menu.animateSpeed); menu.applySelectedClass(menuLink)}
        );
        subMenu.find('a').each(function(){menu.applySelectedClass($(this))});
      }
    });
  },
  applySelectedClass : function(menuLink)
  {
    ($.inArray(menuLink.html(), menu.selectedLinks) > -1) ? menuLink.addClass(menu.selectedClass) : menuLink.removeClass(menu.selectedClass);
  }
}

Y aquí está el css en caso de que alguien quiera usarlo ...

/*
    menu.css - main menu cascading style sheet for ekerner.com all media
    'Eugene Kerner' <ekerner@ekerner.com>
    14-12-2007
*/

.menuItems, .menuItems li, .menuItems li ul, .menuItems li ul li {
  padding: 0;
  margin: 0;
}
.menuItems, .menuItems li ul {
  list-style: none;
}
.menuItems {
  background: url(/shared/images/menu/menu_button_bg.png) repeat-x;
  height: 30px;
}
.menuItems:after { 
  content: ".";
  height: 0; 
  clear: both; 
  display: none;
}
.menuItems li {
  width: 80px;
  float: left;
}
.menuItems li a {
  color: #0d2a86;
  font-size: 14px;
  font-weight: bold;
  text-decoration: none;
  text-align: center;
  height: 24px;
  padding-top: 6px;
  border-right: 1px solid #f3f3f3;
  display: block;
}
.menuItems li a:hover, .menuItems li .selected {
  background: url(/shared/images/menu/menu_button_bg_selected.png) repeat-x;
  color: #518ed3;
}
.menuItems li ul {
  position: absolute;
    z-index: 100;
    border: 1px solid #e0e7ef;
    border-top: 0;
  display: none;
}
.menuItems li ul li {
  width: 77px;
  clear: both;
}
.menuItems li ul li a {
  background: #f3f3f3;
  font-size: 12px;
  font-weight: normal;
  height: 18px;
  padding: 0;
  padding-top: 2px;
  border: 0;
}
.menuItems li ul li a:hover, .menuItems li ul li .selected {
  background: #e0e7ef;
}
.visible {
  display: block;
}
.hidden {
  display: none;
}

No sé si necesita el jQuery, vea el ejemplo de domerador a continuación ...

/*
    menu.js     : main menu javascript class for ekerner.com
    Author      : 'Eugene Kerner' <ekerner@ekerner.com>
    Date        : 14-12-2007
    Dependencies: menu.css
                : an unordered list structure as per the below Example.
                : a javascript call to menu.init(menuId, selectedMenuItemsArray) as per the below Example.
    Notes       : if your menu link has an onclick that returns false then it needs to call menu.init before returning (see Example).
    Example     : -
    <ul id="mainMenu" class="menuItems">
      <li>
        <a href="/">Menu Item</a>
        <ul>
          <li><a href="/webpage" onclick="window.open('/webpage'); menu.init('mainMenu', ['Menu Item', 'Sub Menu Item']); return false;">Sub Menu Item</a></li>
        </ul>
      </li>
    </ul>
    <script type="text/javascript">menu.init('mainMenu', ['Menu Item']);</script>
*/

var menu = {

  selectedItems : [],

  init : function(menuId, selectedMenuItems)
  {
    this.selectedItems = selectedMenuItems;
    var menuItem = domIterator.getFirstChild(document.getElementById(menuId));
    while (menuItem) {
      var menuItemLink = domIterator.getFirstChild(menuItem);
      var subMenu      = domIterator.getNextSibling(menuItemLink);
      this.applySelectedClass(menuItemLink);
      if (subMenu) {
        menuItem.onmouseover = function(){menu.showSubMenu(this)};
        menuItem.onmouseout  = function(){menu.hideSubMenu(this)};
        var subMenuLinks = subMenu.getElementsByTagName('a');
        for (var i = 0; i < subMenuLinks.length; i++)
          this.applySelectedClass(subMenuLinks[i]);
      }
      menuItem = domIterator.getNextSibling(menuItem);
    }
  },

  applySelectedClass : function(menuLink)
  {
    for (var i = 0; i < this.selectedItems.length; i++) {
      if (menuLink.innerHTML == this.selectedItems[i]) {
        menuLink.className = 'selected';
        return;
      }
    }
    menuLink.className = '';
  },

  showSubMenu : function(menuItem)
  {
    domIterator.getFirstChild(menuItem).className     = 'selected';
    domIterator.getLastChild (menuItem).style.display = 'block';
  },

  hideSubMenu : function(menuItem)
  {
    domIterator.getLastChild (menuItem).style.display = 'none';
    this.applySelectedClass(domIterator.getFirstChild(menuItem));
  }

}; // end menu

var domIterator = {

  getFirstChild : function(elem)
  {
    if (elem) return domIterator.continueUntilType1(elem.firstChild, 'next');
  },

  getLastChild : function(elem)
  {
    if (elem) return domIterator.continueUntilType1(elem.lastChild, 'previous');
  },

  getNextSibling : function(elem)
  {
    if (elem) return domIterator.continueUntilType1(elem.nextSibling, 'next');
  },

  continueUntilType1 : function(elem, direction) 
  {
    while (elem && elem.nodeType != 1)
      elem = elem[direction + 'Sibling'];
    return elem;
  }

}; // end domIterator
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top