动态级联下拉框

今天需要遇到添加商品的某一类型的时候,原来的类型只有一个下拉框,虽然下拉框有层次缩进,但太长了,很不好使用,于是,想有这么一个处理:

1)首先生成根类的下拉框
2)选择某一个父类的时候,随后生成一个其子类的下拉框,如果有子类的子类(即孙子),不列出它们。
3)以此类推

完成以上功能的话,非JavaScript莫属了。

这里有一个难点,如果处理好只能生成当前父类的子类(如果存在的话),而且不能重复生成子类的下拉框(select)。变化到同级中的另一个父类的时候,之前父类的子类(还有由点击子类生成的其子类(即孙子类)的下拉框,再类推以下几级),都要消失,而是生成当前指向的父类的子类。

说得乱七八糟的吧。其实,也简单,我们要处理的是,当前某层类位置以后东东,我们需要一个东西记录这些东东,以便选择同层中另一个类时候的删除它们,插进该类的子类。

以上也只是自己想得处理这问题的一个方法,当前能力还非常有待提高,所以很期待高人指点。下边贴出代码,JavaScript好些东西是用于致学(即是用的时候,查看了下参考手册,很多东西没了解,用的比较生硬),还有,以下只支持IE,非常郁闷!其它浏览器不支持Event对象的srcElement属性哦!

类别的XML文档category.xml

HTML DOM:

处理xml并生成category的select菜单的JavaScript:xml_category.js

/**
 * @param   xml_name     xml文档的路径
 * @param   target_id      html的DOM的ID
 */
function xml_category(xml_name, target_id)
{
  var self = this;             // 私有变量,指向对象本身,在JS“类”的封装和访问机制,理解还有待加强。
  
   this.xmlDoc       = loadXMLDoc(xml_name)        // loadXMLDoc函数见/?p=302
   this.targetID     = document.getElementByID(target_id);
   this.catTree      = new Array();                       // 记录select的情况

   /**
    *  产生select下拉框
    */
   this.createSelect = function(parent_id)
   {
      var xmlDoc = self.xmlDoc;
      var cat, cat_num;

      // 以下为了都兼容各浏览器,不使用用与IE的XML DOM的selectNodes() 方法用一个 XPath(//cat[pid=*])[*表传来对应的parent_id] 查询选择节点.其它浏览器可参考Document.evaluate()。
      cat = xmlDoc.getElementByTagName("cat");
      cat_num = parseInt(cat.length);
     
      if (cat_num > 0) // 类别存在
      {
         var slt;
         var is_set = false;                                            // 为标志该层是否有类别,即有option选项
         slt = document.createElement("SELECT")              // 创建一个select元素节点
         slt.onchange = self.createChildSelect;                 // onchange事件

         // 每次都是整树遍历啊! !--
         for (var i=0, j=0; i < cat_num; i++)
         {
            // 同层的类别
            if (parseInt(cat[i].getAttribute("pid")) === parseInt(parent_id))
            {
               // option选项
               slt.optons[j] = new Option(cat[i].childNodes[0].nodeValue, cat[i].getAttribute("id"));
               is_set = true;
               j++; 
            }
         }

         // 有选项值
         if (is_set)
         {
             self.catTree.push(slt);          // 记录这个select下拉框
             self.targetID.appendChild(slt);
         }
         else
         {
            slt = null;
         }

      }
   }

   /** 
    * 生成子类
    */
  this.createChildSelect = function()
  {
       var slt_len = self.catTree.length;
       
       if (slt_len > 0)
       {
            var s = 0;                     // 标记当前触发option在catTree的位置(如果存在的情况)

            // 很不顺眼的遍历
            for (var i=0; i < slt_len; i++)
            { 
                // srcElement是IE的属性。 !--
                if (self.catTree[i] == event.srcElement)
                {
                    s = i ; break;
                }
            }

            // 删除该层位置以后所有的东东
            for (var i= slt_len - 1; i > s; i--)
            {
                 self.targetID.removeChild(self.catTree[i]);
                 seft.catTree.pop();
             }

            self.createSelect(event.srcElement.value);
       }

  }

}

下来在之前HTML文档位于id=”cat”写下如下JS,便可实现了:

var xml = xml_category("xml_category.xml", "cat")
xml.createSelect(0);

以上处理,还非常欠缺灵活性,就是初始化这个select下拉框的时候,如果输入的parent_id不是根类的ID,而是子类,或以下几层的子类的ID的时候,不能生成相应的select下拉框。

到此,写下这点记录,希望高人指点,也继续更进~

发表回复

您的电子邮箱地址不会被公开。