驯服Select - Don替换禁用的OPTION

时间:2017-06-10 15:28:16

标签: javascript html css

我找到了一个很棒的Javascript叫做Taming Select。我知道它已经很老了,但是通过渲染<选择>输入到UL下拉列表中。

我的问题是我的<选择> DOM元素已动态禁用<选项>孩子们,但这段代码并不能辨别它是否被禁用。

我想知道几件事:

  1. 如何让Javascript识别已禁用<选项>?
  2. 我应该完全删除DOM元素还是将CSS类注入新创建的列表项中以使用user-select和pointer-events禁用它们?
  3. 我已经进行了将近8个小时的搜索,而且我似乎无法弄清楚如何在我的名单上做到第1位。

    我尝试了getElementsByTagName('选项')。禁用和getElementsByTagName的其他变体,没有任何反应;即使我修改了W3Schools中的一些例子。

    以下是TamingSelect的代码:

        function tamingselect()
    {
        if(!document.getElementById && !document.createTextNode){return;}
    
    // Classes for the link and the visible dropdown
        var ts_selectclass='turnintodropdown';  // class to identify selects
        var ts_listclass='turnintoselect';      // class to identify ULs
        var ts_boxclass='dropcontainer';        // parent element
        var ts_triggeron='activetrigger';       // class for the active trigger link
        var ts_triggeroff='trigger';            // class for the inactive trigger link
        var ts_dropdownclosed='dropdownhidden'; // closed dropdown
        var ts_dropdownopen='dropdownvisible';  // open dropdown
    /*
        Turn all selects into DOM dropdowns
    */
        var count=0;
        var toreplace=new Array();
        var sels=document.getElementsByTagName('select');
        for(var i=0;i<sels.length;i++){
            if (ts_check(sels[i],ts_selectclass))
            {
                var hiddenfield=document.createElement('input');
                hiddenfield.name=sels[i].name;
                hiddenfield.type='hidden';
                hiddenfield.id=sels[i].id;
                hiddenfield.value=sels[i].options[0].value;
                sels[i].parentNode.insertBefore(hiddenfield,sels[i])
                var trigger=document.createElement('a');
                ts_addclass(trigger,ts_triggeroff);
                trigger.href='#';
                trigger.onclick=function(){
                    ts_swapclass(this,ts_triggeroff,ts_triggeron)
                    ts_swapclass(this.parentNode.getElementsByTagName('ul')[0],ts_dropdownclosed,ts_dropdownopen);
                    return false;
                }
                trigger.appendChild(document.createTextNode(sels[i].options[0].text));
                sels[i].parentNode.insertBefore(trigger,sels[i]);
                var replaceUL=document.createElement('ul');
                for(var j=0;j<sels[i].getElementsByTagName('option').length;j++)
                {
                    var newli=document.createElement('li');
                    var newa=document.createElement('a');
                    newli.v=sels[i].getElementsByTagName('option')[j].value;
                    newli.elm=hiddenfield;
                    newli.istrigger=trigger;
                    newa.href='#';
                    newa.appendChild(document.createTextNode(
                    sels[i].getElementsByTagName('option')[j].text));
                    newli.onclick=function(){ 
                        this.elm.value=this.v;
                        ts_swapclass(this.istrigger,ts_triggeron,ts_triggeroff);
                        ts_swapclass(this.parentNode,ts_dropdownopen,ts_dropdownclosed)
                        this.istrigger.firstChild.nodeValue=this.firstChild.firstChild.nodeValue;
                        return false;
                    }
                    newli.appendChild(newa);
                    replaceUL.appendChild(newli);
                }
                ts_addclass(replaceUL,ts_dropdownclosed);
                var div=document.createElement('div');
                div.appendChild(replaceUL);
                ts_addclass(div,ts_boxclass);
                sels[i].parentNode.insertBefore(div,sels[i])
                toreplace[count]=sels[i];
                count++;
            }
        }
    
    /*
        Turn all ULs with the class defined above into dropdown navigations
    */  
    
        var uls=document.getElementsByTagName('ul');
        for(var i=0;i<uls.length;i++)
        {
            if(ts_check(uls[i],ts_listclass))
            {
                var newform=document.createElement('form');
                var newselect=document.createElement('select');
                for(j=0;j<uls[i].getElementsByTagName('a').length;j++)
                {
                    var newopt=document.createElement('option');
                    newopt.value=uls[i].getElementsByTagName('a')[j].href;  
                    newopt.appendChild(document.createTextNode(uls[i].getElementsByTagName('a')[j].innerHTML)); 
                    newselect.appendChild(newopt);
                }
                newselect.onchange=function()
                {
                    window.location=this.options[this.selectedIndex].value;
                }
                newform.appendChild(newselect);
                uls[i].parentNode.insertBefore(newform,uls[i]);
                toreplace[count]=uls[i];
                count++;
            }
        }
        for(i=0;i<count;i++){
            toreplace[i].parentNode.removeChild(toreplace[i]);
        }
        function ts_check(o,c)
        {
            return new RegExp('\\b'+c+'\\b').test(o.className);
        }
        function ts_swapclass(o,c1,c2)
        {
            var cn=o.className
            o.className=!ts_check(o,c1)?cn.replace(c2,c1):cn.replace(c1,c2);
        }
        function ts_addclass(o,c)
        {
            if(!ts_check(o,c)){o.className+=o.className==''?c:' '+c;}
        }
    }
    
    window.onload=function()
    {
        tamingselect();
        // add more functions if necessary
    }
    

    非常感谢任何帮助。我的Javascript经验非常少(说实话,我最接近研究的是10年前的ActionScript)。

    提前致谢。 迈克尔

1 个答案:

答案 0 :(得分:0)

  1. 您正在寻找返回bool的.hasAttribute()函数。 即。 el.hasAttribute( '禁用')。

    https://developer.mozilla.org/en-US/docs/Web/API/Element/hasAttribute

  2. 如评论中所述,要实际迭代检查属性的选项,您应该执行以下操作:

    // returns an array like HTMLCollection of the elements that match the 
    // tag
    let options = document.getElementsByTagName('option')
    
    // uses the array method forEach on the HTMLCollection.
    // note that HTMLCollections do not natively have the forEach method 
    // but still act behave normal arrays when using iteration.
    
    Array.prototype.forEach.call( options, el => { 
        el.hasAttribute('disabled')
    })