jQuery Plugin公共函数返回对象而不是简单数组

时间:2017-03-05 21:22:38

标签: jquery jquery-plugins

以下是我正在使用的插件的一部分。这是我的第一个插件。我可以访问并向函数发送值。但是现在当我尝试从函数中获取数组时,它会向我发送一个对象!谁能告诉我getValue功能有什么问题?它的返回对象而不是数组$selected_items

(function($){
    function WMPlugin(item, options) {
        this.options = $.extend({
            selectableList_header: null,
            selectedList_header: null,
        }, options);


        this.$element = $(item);
        this.$container = $('<div/>', { 'class': "wmdl-container" });
        this.$selectable_list = $('<ul/>', { 'class': 'wmdl-selectable-list' });
        this.$selected_list = $('<ul/>', { 'class': 'wmdl-selected-list' });

        this.config = $.extend(true, {
            selectableList_header: null,
            selectedList_header: null,
        }, options || {});

        this.init();
    }
    WMPlugin.prototype = {
        init: function (options) {
            $.extend(this.options, options);
            var $select = this.$element;         
            var $wmdl = this.generateWMDL();
            $select.after($wmdl);
            $select.hide();
            return $wmdl;
        },

        generateWMDL: function (options) {
            var $container = this.$container;
            var $selectable_list = this.selectableList();
            var $selected_list = this.selectedList();
            $container.append($selectable_list).append($selected_list);
            return $container;
        },

        selectableList: function (options) {
            $.extend(this.options, options);
            var $this = this;
            var $selectable_list = this.$selectable_list;
            var $select = this.$element;

            var $optgroups = $select.children('optgroup');
            var $i = 1;
            if( $optgroups.length > 0 ) {
                $optgroups.each(function(i, group){
                    var $group = $(group);
                    var $group_label = $group.attr('label');

                    if ($group_label == "") {
                        $group_label = '<small>No name found</small>';
                    }

                    var $group_parent = $('<li>')
                                        .addClass('wmdl-has-group')
                                        .html('<span>' + $group_label + '</span>');



                    var  $group_ul = $('<ul>')
                                    .addClass('wmdl-group')
                                    .attr('data-wmdl-group', 'wmdl-group-'+i);
                    $group.attr('id', 'wmdl-group-'+i);

                    $group_parent.append($group_ul);

                    $selectable_list.append($group_parent);
                });
            }


            $select.find('option').each(function(i, item) {
                var $item = $(item);
                var $item_value = $(item).attr('value');
                var $item_text = $(item).text();
                var $item_optgroup = $item.parent('optgroup');

                if ($item.is(':selected')) {
                    var $li =  $('<li>')
                                    .css('display', 'none')
                                    .attr('data-wmdl-value', $item_value)
                                    .text($item_text);
                } else {
                    var $li =  $('<li>')
                                    .attr('data-wmdl-value', $item_value)
                                    .text($item_text);
                }

                if ($item_optgroup.length > 0) {
                    var $item_optgroup_id = $item_optgroup.attr('id');
                    $selectable_list.find('[data-wmdl-group="'+ $item_optgroup_id +'"]').append($li);
                } else {
                    $selectable_list.append($li);
                }

                $this.addItem($li);
            });

            return $selectable_list;
        },

        selectedList: function (options) {
            $.extend(this.options, options);
            var $this = this;
            var $select = this.$element;
            var $selected_list = this.$selected_list;

            $select.find('option:selected').each(function(i, item) {
                var $item = $(item);
                var $item_value = $(item).attr('value');
                var $item_text = $(item).text();
                var $item_optgroup = $item.parent('optgroup');
                if ($item_optgroup_label == "") {
                    $item_optgroup_label = '<small>No name found</small>';
                }

                var $li =  $('<li>')
                                .attr('data-wmdl-value', $item_value)
                                .text($item_text);

                if ($item_optgroup.length > 0) {
                    var $item_optgroup_id = $item_optgroup.attr('id');
                    var $item_optgroup_selectedList = $selected_list.find('[data-wmdl-group="'+ $item_optgroup_id +'"]');
                    if ($item_optgroup_selectedList.length > 0) {
                        $item_optgroup_selectedList.append($li);
                    } else {
                        var $item_optgroup_label = $item_optgroup.attr('label');
                        var $group_parent = $('<li>')
                                                .addClass('wmdl-has-group')
                                                .html('<span>' + $item_optgroup_label + '</span>');
                        var  $group_ul = $('<ul>')
                                        .addClass('wmdl-group')
                                        .attr('data-wmdl-group', $item_optgroup_id);

                        $group_parent.append($group_ul);
                        $group_ul.append($li);
                        $selected_list.append($group_parent);
                    }
                } else {
                    $selected_list.append($li);
                }

                $this.removeItem($li);
            });

            return $selected_list;
        },

        getValue: function () {
            var $this = this;
            var $selected_list = this.$selected_list;
            var $selectable_list = this.$selectable_list;
            var $selected_items = [];
            $selected_list.find('li').each(function(){
                var $value = $(this).attr('data-wmdl-value');
                $selected_items.push($value);
            })

            return $selected_items;
        },
    }

    // jQuery plugin interface
    $.fn.WMDuelList = function(opt) {
        var args = Array.prototype.slice.call(arguments, 1);
        return this.each(function() {
            var item = $(this), instance = item.data('WMPlugin');
            if(!instance) {
                // create plugin instance if not created
                item.data('WMPlugin', new WMPlugin(this, opt));
            } else {
                // otherwise check arguments for method call
                if(typeof opt === 'string') {
                    instance[opt].apply(instance, args);
                }
            }
        });
    }

}(jQuery));

使用JSFiddle - https://jsfiddle.net/uh7w0dwb/

2 个答案:

答案 0 :(得分:1)

您可以尝试更改插件界面的返回上下文。这是基于只返回一个列表项的实例。即提供getValue是在ID上调用的,而不是具有多次出现的类。

更新:将结果推送到多个实例的数组中:

    // jQuery plugin interface
    $.fn.WMDuelList = function(opt) {
        var args = Array.prototype.slice.call(arguments, 1), inst=[];
        this.each(function() {
            var item = $(this), instance = item.data('WMPlugin');
            if(!instance) {
                // create plugin instance if not created
                item.data('WMPlugin', new WMPlugin(this, opt));
            } else {
                // otherwise check arguments for method call
                if(typeof opt === 'string') {
                    inst.push(instance[opt].apply(instance, args));
                }
            }
        });
        return inst;
    } 

你需要记住在有一个实例的地方使用console.log(value[0]);。然而,可能存在这种模式不理想的情况。

(function($) {
  function WMPlugin(item, options) {
    this.options = $.extend({
      selectableList_header: null,
      selectedList_header: null,
    }, options);


    this.$element = $(item);
    this.$container = $('<div/>', {
      'class': "wmdl-container"
    });
    this.$selectable_list = $('<ul/>', {
      'class': 'wmdl-selectable-list'
    });
    this.$selected_list = $('<ul/>', {
      'class': 'wmdl-selected-list'
    });

    this.config = $.extend(true, {
      selectableList_header: null,
      selectedList_header: null,
    }, options || {});

    this.init();
  }
  WMPlugin.prototype = {
    init: function(options) {
      $.extend(this.options, options);
      var $select = this.$element;
      var $wmdl = this.generateWMDL();
      $select.after($wmdl);
      $select.hide();
      return $wmdl;
    },

    generateWMDL: function(options) {
      var $container = this.$container;
      var $selectable_list = this.selectableList();
      var $selected_list = this.selectedList();
      $container.append($selectable_list).append($selected_list);
      return $container;
    },

    selectableList: function(options) {
      $.extend(this.options, options);
      var $this = this;
      var $selectable_list = this.$selectable_list;
      var $select = this.$element;

      var $optgroups = $select.children('optgroup');
      var $i = 1;
      if ($optgroups.length > 0) {
        $optgroups.each(function(i, group) {
          var $group = $(group);
          var $group_label = $group.attr('label');

          if ($group_label == "") {
            $group_label = '<small>No name found</small>';
          }

          var $group_parent = $('<li>')
            .addClass('wmdl-has-group')
            .html('<span>' + $group_label + '</span>');



          var $group_ul = $('<ul>')
            .addClass('wmdl-group')
            .attr('data-wmdl-group', 'wmdl-group-' + i);
          $group.attr('id', 'wmdl-group-' + i);

          $group_parent.append($group_ul);

          $selectable_list.append($group_parent);
        });
      }


      $select.find('option').each(function(i, item) {
        var $item = $(item);
        var $item_value = $(item).attr('value');
        var $item_text = $(item).text();
        var $item_optgroup = $item.parent('optgroup');

        if ($item.is(':selected')) {
          var $li = $('<li>')
            .css('display', 'none')
            .attr('data-wmdl-value', $item_value)
            .text($item_text);
        } else {
          var $li = $('<li>')
            .attr('data-wmdl-value', $item_value)
            .text($item_text);
        }

        if ($item_optgroup.length > 0) {
          var $item_optgroup_id = $item_optgroup.attr('id');
          $selectable_list.find('[data-wmdl-group="' + $item_optgroup_id + '"]').append($li);
        } else {
          $selectable_list.append($li);
        }

      });

      return $selectable_list;
    },

    selectedList: function(options) {
      $.extend(this.options, options);
      var $this = this;
      var $select = this.$element;
      var $selected_list = this.$selected_list;

      $select.find('option:selected').each(function(i, item) {
        var $item = $(item);
        var $item_value = $(item).attr('value');
        var $item_text = $(item).text();
        var $item_optgroup = $item.parent('optgroup');
        if ($item_optgroup_label == "") {
          $item_optgroup_label = '<small>No name found</small>';
        }

        var $li = $('<li>')
          .attr('data-wmdl-value', $item_value)
          .text($item_text);

        if ($item_optgroup.length > 0) {
          var $item_optgroup_id = $item_optgroup.attr('id');
          var $item_optgroup_selectedList = $selected_list.find('[data-wmdl-group="' + $item_optgroup_id + '"]');
          if ($item_optgroup_selectedList.length > 0) {
            $item_optgroup_selectedList.append($li);
          } else {
            var $item_optgroup_label = $item_optgroup.attr('label');
            var $group_parent = $('<li>')
              .addClass('wmdl-has-group')
              .html('<span>' + $item_optgroup_label + '</span>');
            var $group_ul = $('<ul>')
              .addClass('wmdl-group')
              .attr('data-wmdl-group', $item_optgroup_id);

            $group_parent.append($group_ul);
            $group_ul.append($li);
            $selected_list.append($group_parent);
          }
        } else {
          $selected_list.append($li);
        }

      });

      return $selected_list;
    },

    getValue: function() {
      var $this = this;
      var $selected_list = this.$selected_list;
      var $selectable_list = this.$selectable_list;
      var $selected_items = [];
      $selected_list.find('li').each(function() {
        var $value = $(this).attr('data-wmdl-value');
        $selected_items.push($value);
      });

      return $selected_items;
    }
  }

  // jQuery plugin interface
  $.fn.WMDuelList = function(opt) {
    var args = Array.prototype.slice.call(arguments, 1),
      inst = [];
    this.each(function() {
      var item = $(this),
        instance = item.data('WMPlugin');
      if (!instance) {
        // create plugin instance if not created
        item.data('WMPlugin', new WMPlugin(this, opt));
      } else {
        // otherwise check arguments for method call
        if (typeof opt === 'string') {
          inst.push( instance[opt].apply(instance, args));
        }
      }
    });
    return inst;
  }

}(jQuery));

$(document).ready(function() {
  $('#wm-duel-list').WMDuelList({

  });

  $('#get-value').click(function() {
    var value = $('#wm-duel-list').WMDuelList('getValue');
    console.log(value[0]);
  });
});
body {
  font-family: Arial;
}

.wmdl-container {
  position: relative;
  box-sizing: border-box;
  padding: 0;
  margin: 0 0 15px 0;
}

.wmdl-container * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.wmdl-container:after,
.wmdl-header:after {
  clear: both;
  content: " ";
  height: 0;
  display: block;
}

.wmdl-container:before {
  content: "\21C4";
  display: block;
  position: absolute;
  font-size: 200%;
  font-weight: 900;
  color: #000;
  top: 50%;
  left: 50%;
  -moz-transform: translatex(-50%) translatey(-50%);
  -ms-transform: translatex(-50%) translatey(-50%);
  -o-transform: translatex(-50%) translatey(-50%);
  -webkit-transform: translatex(-50%) translatey(-50%);
  transform: translatex(-50%) translatey(-50%);
}

.wmdl-header {
  position: relative;
}

.wmdl-header>div {
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: "...";
  padding: 10px 15px;
  background-color: #0275D8;
  color: #fff;
  font-size: 110%;
  font-weight: bold;
  text-align: center;
}

.wmdl-header>div,
.wmdl-selectable-list,
.wmdl-selected-list {
  position: relative;
  float: left;
  width: calc(50% - 20px);
}

.wmdl-selectable-list,
.wmdl-selected-list {
  list-style: none;
  border: 1px solid #ccc;
  border-radius: 5px;
  height: 211px;
  overflow-y: auto;
  overflow-x: hidden;
}

.wmdl-header>div:first-child,
.wmdl-selectable-list {
  margin-right: 40px;
}

.has-header .wmdl-selectable-list,
.has-header .wmdl-selected-list {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

.wmdl-selectable-list>li,
.wmdl-selected-list>li {
  list-style-type: none;
  padding: 7px 15px;
  border-bottom: 1px solid #ccc;
  cursor: pointer;
}

.wmdl-selectable-list>li.wmdl-has-group,
.wmdl-selected-list>li.wmdl-has-group {
  padding: 0;
}

.wmdl-selectable-list>li:not(.wmdl-has-group):hover,
.wmdl-selected-list>li:not(.wmdl-has-group):hover {
  background-color: #0275D8;
  color: #fff;
}

.wmdl-selectable-list>li.wmdl-has-group>span,
.wmdl-selected-list>li.wmdl-has-group>span {
  display: block;
  padding: 4px 15px;
  background-color: #ccc;
}

.wmdl-group {
  list-style: none;
  padding: 0;
  margin: 0;
}

.wmdl-group>li {
  padding: 7px 25px;
  list-style-type: none;
  border-bottom: 1px solid #ccc;
}

.wmdl-group>li:hover {
  background-color: #0275D8;
  color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="wm-duel-list" multiple="multiple">
		<option value="1">Item 1</option>
		<option value="2">Item 2</option>
		<option value="3" selected>Item 3</option>
		<option value="4" selected>Item 4</option>
		<option value="5" selected>Item 5</option>
		<option value="6" selected>Item 6</option>
		<option value="7" selected>Item 7</option>
		<option value="8">Item 8</option>
		<option value="9">Item 9</option>
		<option value="10">Item 10</option>
	</select>

<div class="div">
  <button id="get-value">Get</button>
</div>

答案 1 :(得分:1)

在进入each循环之前,可以更改主插件函数以检查字符串。

如果是字符串并且该方法存在则返回方法调用,如果方法不存在则抛出错误或执行其他操作

类似的东西:

  // jQuery plugin interface
  $.fn.WMDuelList = function(opt) {
    var args = Array.prototype.slice.call(arguments, 1);

    if (typeof opt === 'string') {
      var instance = this.data('WMPlugin');
      if (instance && instance[opt]) {
        return instance[opt]();
      } else {
        console.error('Either method does not exist or plugin hasn\'t been initialized')
      }

    } else {
      return this.each(function() {
        var item = $(this),
          instance = item.data('WMPlugin');
        if (!instance) {
          // create plugin instance if not created
          item.data('WMPlugin', new WMPlugin(this, opt));
        }

      });
    }

  }

DEMO