jQuery选择框问题

时间:2012-07-17 19:55:44

标签: jquery html list drop-down-menu

我正在添加一个下拉列表并使用.selectbox(“attach”)将其转换为选择框。超越第二种选择(除了电子产品,它让我选择电子产品)不允许我选择它们。这是attach命令生成的代码。

<div id="sbHolder_3628646" class="sbHolder"><a id="sbToggle_3628646" href="#" class="sbToggle"></a>
 <a id="sbSelector_3628646"
    href="#" class="sbSelector">Electronics</a>

    <ul id="sbOptions_3628646" class="sbOptions"
    style="top: 30px; max-height: 260px; display: none; ">
        <li><a href="# " rel=" "></a>
        </li>
        <li><a href="#1" rel="1">Electronics</a>
        </li>
        <li><a href="#2" rel="2">Tvs</a>
        </li>
        <li><a href="#3" rel="3">Plasma</a>
        </li>
        <li><a href="#4" rel="4">LED</a>
        </li>
    </ul>
</div>

这是从

生成它的代码
<select name="cat2" class="longinput" id="drop2" sb="3628646" style="display: none; ">
    <option value=" "></option>
    <option value="1">Electronics</option>
    <option value="2">Tvs</option>
    <option value="3">Plasma</option>
    <option value="4">LED</option>
</select>

来自selectbox的jQuery

(function (jQuery, undefined) {
var PROP_NAME = 'selectbox',
    FALSE = false,
    TRUE = true;
/**
 * Selectbox manager.
 * Use the singleton instance of this class, jQuery.selectbox, to interact with the select box.
 * Settings for (groups of) select boxes are maintained in an instance object,
 * allowing multiple different settings on the same page
 */
function Selectbox() {
    this._state = [];
    this._defaults = { // Global defaults for all the select box instances
        classHolder: "sbHolder",
        classHolderDisabled: "sbHolderDisabled",
        classSelector: "sbSelector",
        classOptions: "sbOptions",
        classGroup: "sbGroup",
        classSub: "sbSub",
        classDisabled: "sbDisabled",
        classToggleOpen: "sbToggleOpen",
        classToggle: "sbToggle",
        speed: 200,
        effect: "slide", // "slide" or "fade"
        onChange: null, //Define a callback function when the selectbox is changed
        onOpen: null, //Define a callback function when the selectbox is open
        onClose: null //Define a callback function when the selectbox is closed
    };
}

jQuery.extend(Selectbox.prototype, {
    /**
     * Is the first field in a jQuery collection open as a selectbox
     * 
     * @param {Object} target
     * @return {Boolean}
     */
    _isOpenSelectbox: function (target) {
        if (!target) {
            return FALSE;
        }
        var inst = this._getInst(target);
        return inst.isOpen;
    },
    /**
     * Is the first field in a jQuery collection disabled as a selectbox
     * 
     * @param {HTMLElement} target
     * @return {Boolean}
     */
    _isDisabledSelectbox: function (target) {
        if (!target) {
            return FALSE;
        }
        var inst = this._getInst(target);
        return inst.isDisabled;
    },
    /**
     * Attach the select box to a jQuery selection.
     * 
     * @param {HTMLElement} target
     * @param {Object} settings
     */
    _attachSelectbox: function (target, settings) {
        if (this._getInst(target)) {
            return FALSE;
        }
        var jQuerytarget = jQuery(target),
            self = this,
            inst = self._newInst(jQuerytarget),
            sbHolder, sbSelector, sbToggle, sbOptions,
            s = FALSE, optGroup = jQuerytarget.find("optgroup"), opts = jQuerytarget.find("option"), olen = opts.length;

        jQuerytarget.attr("sb", inst.uid);

        jQuery.extend(inst.settings, self._defaults, settings);
        self._state[inst.uid] = FALSE;
        jQuerytarget.hide();

        function closeOthers() {
            var key, uid = this.attr("id").split("_")[1];
            for (key in self._state) {
                if (key !== uid) {
                    if (self._state.hasOwnProperty(key)) {
                        if (jQuery(":input[sb='" + key + "']")[0]) {
                            self._closeSelectbox(jQuery(":input[sb='" + key + "']")[0]);
                        }
                    }
                }
            }
        }

        sbHolder = jQuery("<div>", {
            "id": "sbHolder_" + inst.uid,
            "class": inst.settings.classHolder
        });

        sbSelector = jQuery("<a>", {
            "id": "sbSelector_" + inst.uid,
            "href": "#",
            "class": inst.settings.classSelector,
            "click": function (e) {
                e.preventDefault();
                closeOthers.apply(jQuery(this), []);
                var uid = jQuery(this).attr("id").split("_")[1];
                if (self._state[uid]) {
                    self._closeSelectbox(target);
                } else {
                    self._openSelectbox(target);
                }
            }
        });

        sbToggle = jQuery("<a>", {
            "id": "sbToggle_" + inst.uid,
            "href": "#",
            "class": inst.settings.classToggle,
            "click": function (e) {
                e.preventDefault();
                closeOthers.apply(jQuery(this), []);
                var uid = jQuery(this).attr("id").split("_")[1];
                if (self._state[uid]) {
                    self._closeSelectbox(target);
                } else {
                    self._openSelectbox(target);
                }
            }
        });
        sbToggle.appendTo(sbHolder);

        sbOptions = jQuery("<ul>", {
            "id": "sbOptions_" + inst.uid,
            "class": inst.settings.classOptions,
            "css": {
                "display": "none"
            }
        });

        jQuerytarget.children().each(function(i) {
            var that = jQuery(this), li, config = {};
            if (that.is("option")) {
                getOptions(that);
            } else if (that.is("optgroup")) {
                li = jQuery("<li>");
                jQuery("<span>", {
                    "text": that.attr("label")
                }).addClass(inst.settings.classGroup).appendTo(li);
                li.appendTo(sbOptions);
                if (that.is(":disabled")) {
                    config.disabled = true;
                }
                config.sub = true;
                getOptions(that.find("option"), config);
            }
        });

        function getOptions () {
            var sub = arguments[1] && arguments[1].sub ? true : false,
                disabled = arguments[1] && arguments[1].disabled ? true : false;
            arguments[0].each(function (i) {
                var that = jQuery(this),
                    li = jQuery("<li>"),
                    child;
                if (that.is(":selected")) {
                    sbSelector.text(that.text());
                    s = TRUE;
                }
                if (i === olen - 1) {
                    li.addClass("last");
                }
                if (!that.is(":disabled") && !disabled) {
                    child = jQuery("<a>", {
                        "href": "#" + that.val(),
                        "rel": that.val(), 
                        "text": that.text(),
                        "click": function (e) {
                            e.preventDefault();
                            var t = sbToggle,
                                uid = t.attr("id").split("_")[1];
                            self._changeSelectbox(target, jQuery(this).attr("rel"), jQuery(this).text());
                            self._closeSelectbox(target);
                        }
                    });
                    if (sub) {
                        child.addClass(inst.settings.classSub);
                    }
                    child.appendTo(li);
                } else {
                    child = jQuery("<span>", {
                        "text": that.text()
                    }).addClass(inst.settings.classDisabled);
                    if (sub) {
                        child.addClass(inst.settings.classSub);
                    }
                    child.appendTo(li);
                }
                li.appendTo(sbOptions);
            });
        }

        if (!s) {
            sbSelector.text(opts.first().text());
        }

        jQuery.data(target, PROP_NAME, inst);

        sbSelector.appendTo(sbHolder);
        sbOptions.appendTo(sbHolder);           
        sbHolder.insertAfter(jQuerytarget);
    },
    /**
     * Remove the selectbox functionality completely. This will return the element back to its pre-init state.
     * 
     * @param {HTMLElement} target
     */
    _detachSelectbox: function (target) {
        var inst = this._getInst(target);
        if (!inst) {
            return FALSE;
        }
        jQuery("#sbHolder_" + inst.uid).remove();
        jQuery.data(target, PROP_NAME, null);
        jQuery(target).show();          
    },
    /**
     * Change selected attribute of the selectbox.
     * 
     * @param {HTMLElement} target
     * @param {String} value
     * @param {String} text
     */
    _changeSelectbox: function (target, value, text) {
        var inst = this._getInst(target),
            onChange = this._get(inst, 'onChange');
        jQuery("#sbSelector_" + inst.uid).text(text);
        jQuery(target).find("option[value='" + value + "']").attr("selected", TRUE);
        if (onChange) {
            onChange.apply((inst.input ? inst.input[0] : null), [value, inst]);
        } else if (inst.input) {
            inst.input.trigger('change');
        }
    },
    /**
     * Enable the selectbox.
     * 
     * @param {HTMLElement} target
     */
    _enableSelectbox: function (target) {
        var inst = this._getInst(target);
        if (!inst || !inst.isDisabled) {
            return FALSE;
        }
        jQuery("#sbHolder_" + inst.uid).removeClass(inst.settings.classHolderDisabled);
        inst.isDisabled = FALSE;
        jQuery.data(target, PROP_NAME, inst);
    },
    /**
     * Disable the selectbox.
     * 
     * @param {HTMLElement} target
     */
    _disableSelectbox: function (target) {
        var inst = this._getInst(target);
        if (!inst || inst.isDisabled) {
            return FALSE;
        }
        jQuery("#sbHolder_" + inst.uid).addClass(inst.settings.classHolderDisabled);
        inst.isDisabled = TRUE;
        jQuery.data(target, PROP_NAME, inst);
    },
    /**
     * Get or set any selectbox option. If no value is specified, will act as a getter.
     * 
     * @param {HTMLElement} target
     * @param {String} name
     * @param {Object} value
     */
    _optionSelectbox: function (target, name, value) {
        var inst = this._getInst(target);
        if (!inst) {
            return FALSE;
        }
        //TODO check name
        inst[name] = value;
        jQuery.data(target, PROP_NAME, inst);
    },
    /**
     * Call up attached selectbox
     * 
     * @param {HTMLElement} target
     */
    _openSelectbox: function (target) {
        var inst = this._getInst(target);
        //if (!inst || this._state[inst.uid] || inst.isDisabled) {
        if (!inst || inst.isOpen || inst.isDisabled) {
            return;
        }
        var el = jQuery("#sbOptions_" + inst.uid),
            viewportHeight = parseInt(jQuery(window).height(), 10),
            offset = jQuery("#sbHolder_" + inst.uid).offset(),
            scrollTop = jQuery(window).scrollTop(),
            height = el.prev().height(),
            diff = viewportHeight - (offset.top - scrollTop) - height / 2,
            onOpen = this._get(inst, 'onOpen');
        el.css({
            "top": height + "px",
            "maxHeight": (diff - height) + "px"
        });
        inst.settings.effect === "fade" ? el.fadeIn(inst.settings.speed) : el.slideDown(inst.settings.speed);
        jQuery("#sbToggle_" + inst.uid).addClass(inst.settings.classToggleOpen);
        this._state[inst.uid] = TRUE;
        inst.isOpen = TRUE;
        if (onOpen) {
            onOpen.apply((inst.input ? inst.input[0] : null), [inst]);
        }
        jQuery.data(target, PROP_NAME, inst);
    },
    /**
     * Close opened selectbox
     * 
     * @param {HTMLElement} target
     */
    _closeSelectbox: function (target) {
        var inst = this._getInst(target);
        //if (!inst || !this._state[inst.uid]) {
        if (!inst || !inst.isOpen) {
            return;
        }
        var onClose = this._get(inst, 'onClose');
        inst.settings.effect === "fade" ? jQuery("#sbOptions_" + inst.uid).fadeOut(inst.settings.speed) : jQuery("#sbOptions_" + inst.uid).slideUp(inst.settings.speed);
        jQuery("#sbToggle_" + inst.uid).removeClass(inst.settings.classToggleOpen);
        this._state[inst.uid] = FALSE;
        inst.isOpen = FALSE;
        if (onClose) {
            onClose.apply((inst.input ? inst.input[0] : null), [inst]);
        }
        jQuery.data(target, PROP_NAME, inst);
    },
    /**
     * Create a new instance object
     * 
     * @param {HTMLElement} target
     * @return {Object}
     */
    _newInst: function(target) {
        var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\jQuery1');
        return {
            id: id, 
            input: target, 
            uid: Math.floor(Math.random() * 99999999),
            isOpen: FALSE,
            isDisabled: FALSE,
            settings: {}
        }; 
    },
    /**
     * Retrieve the instance data for the target control.
     * 
     * @param {HTMLElement} target
     * @return {Object} - the associated instance data
     * @throws error if a jQuery problem getting data
     */
    _getInst: function(target) {
        try {
            return jQuery.data(target, PROP_NAME);
        }
        catch (err) {
            throw 'Missing instance data for this selectbox';
        }
    },
    /**
     * Get a setting value, defaulting if necessary
     * 
     * @param {Object} inst
     * @param {String} name
     * @return {Mixed}
     */
    _get: function(inst, name) {
        return inst.settings[name] !== undefined ? inst.settings[name] : this._defaults[name];
    }
});

/**
 * Invoke the selectbox functionality.
 * 
 * @param {Object|String} options
 * @return {Object}
 */
jQuery.fn.selectbox = function (options) {

    var otherArgs = Array.prototype.slice.call(arguments, 1);
    if (typeof options == 'string' && options == 'isDisabled') {
        return jQuery.selectbox['_' + options + 'Selectbox'].apply(jQuery.selectbox, [this[0]].concat(otherArgs));
    }

    if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') {
        return jQuery.selectbox['_' + options + 'Selectbox'].apply(jQuery.selectbox, [this[0]].concat(otherArgs));
    }

    return this.each(function() {
        typeof options == 'string' ?
            jQuery.selectbox['_' + options + 'Selectbox'].apply(jQuery.selectbox, [this].concat(otherArgs)) :
            jQuery.selectbox._attachSelectbox(this, options);
    });
};

jQuery.selectbox = new Selectbox(); // singleton instance
jQuery.selectbox.version = "0.1.3";
})(jQuery);

3 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,只是在_changeSelectbox()函数中添加了一行。

第345行附近应该有以下一行:

$(target).find("option[value='" + value + "']").attr("selected", TRUE);

直接之前,我添加了以下内容:

$(target).find("option").attr("selected", FALSE);

因此,当它触发_changeSelectbox()函数并设置所选属性时,它会首先删除所有现有的选定属性。

答案 1 :(得分:0)

答案 2 :(得分:0)

创建一个div或span同时分配id名称密钥创建任何弹出窗口给id名称key_con,  当你点击键弹出将显示。  再一次点击弹出键将隐藏。