接受函数作为jQuery插件变量并返回参数

时间:2017-01-14 12:46:21

标签: javascript jquery callback

我觉得这很简单,而且我有一棵木头用于树木#34;那一刻,但那一刻已持续了一天,所以现在是时候寻求帮助了!我已经用Google搜索并阅读了大量的SO答案,但我再次无法应用我已经看到的确切问题的答案,这无疑是由于我自己的缺点。

为了说明问题,我有这个示例jQuery插件(我试图为此创建一个小提琴但不知道如何在小提琴中包含一个插件外部的插件) :

(function ($) {

    $.fn.test = function (options) {
        var settings = $.extend({
            onItemClick: function () { },
            itemArray: new Array(),
        }, options);

        for (i = 0; i < settings.itemArray.length; i++) {
            var $item = $("<li></li>");
            $item.html(settings.itemArray[i].itemLabel);
            $item.click(function () {
                settings.onItemClick.call(settings.itemArray[i]);
            });
            this.append($item);
        }

        return this;

    };

}(jQuery));

正如您所看到的,我接受了一个函数作为变量 - onItemClick。我已经遗漏了这个存在的测试,并且为了简洁起见是一个功能。

我的示例页面如下所示:

<body>
    <div> 
        <ul id="testList"></ul>
    </div>
</body>
</html>

<script type="text/javascript">
    $(function () {

        var testDataArray = new Array();

        var itemLabel = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"];
        var itemDate = ["2017-01-03", "2015-08-03", "2016-06-21", "2016-12-20", "2013-09-07"];

        for (i = 0; i < itemDate.length; i++) {
            var testData = {};
            testData["itemLabel"] = itemLabel[i];
            testData["itemDate"] = itemDate[i];

            testDataArray[i] = testData;
        };

        $("#testList").test({
            itemArray: testDataArray,
            onItemClick: function (item) {                
                alert(item.itemLabel + ": " + item.item.Date);
            }
        });
    })
</script>

所以,当我从我的页面调用插件时,我希望能够将函数作为参数传递,并且能够在该函数中包含变量,该变量将由插件填充实际值。最后一点是我陷入困境的地方。

我写的代码并没有按原样运作。不出所料,它会抛出错误

  

无法阅读财产&#39; itemDate&#39;未定义的

因为在函数范围内我不知道settings.itemArray我试图附加到项目的click事件。我明白,我只是不明白正确的做法是什么!

1 个答案:

答案 0 :(得分:1)

这是一个工作片段。

你正走在正确的道路上;

  1. 我添加了一个参数&#39; item&#39;到onItemClick回调函数 在插件中
  2. 当你以这种方式从插件中调用函数时,第一个 参数应该是undefined,如同 settings.onItemClick.call(undefined, itemToSend);
  3. 你的插件在dom中创建了许多列表项,但是 原始点击功能无法区分它们 选择数组项时。因此,所有人都回来了 作为arrayitem 5,因此在此版本中列表项的索引 单击被选中,这用于选择数组项, 或者,数组项内容可以附加到dom 元素通过数据属性(如评论)
  4. 您的提醒功能名为item.item.Date而非 item.itemDate
  5. 点击功能已移出for-loop和 选择器与插件的主选择器相关联,以允许 多个列表
  6. 希望这有助于。

    &#13;
    &#13;
    (function($) {
    
      $.fn.test = function(options) {
        var settings = $.extend({
          onItemClick: function(item) {
    
          },
          itemArray: [],
        }, options);
    
    
        var arrayItems = settings.itemArray;
    
        for (i = 0; i < arrayItems.length; i++) {
          var $item = $("<li></li>");
          $item.html(arrayItems[i].itemLabel);
    
          // $item.html(arrayItems[i].itemLabel).data('arrayItems', arrayItems[i]); 
    
          this.append($item);
        }
        $('li', this).click(function() {
          var indx = $(this).index(),
            itemToSend = arrayItems[indx];
          //  var itemToSend = $(this).data('arrayItems');
          settings.onItemClick.call(undefined, itemToSend);
        });
        return this;
    
      };
    
    }(jQuery));
    
    // copy everything above to a separate file and call via html
    
    
    $(function() {
    
      var testDataArray = [];
    
      var itemLabel = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"];
      var itemDate = ["2017-01-03", "2015-08-03", "2016-06-21", "2016-12-20", "2013-09-07"];
    
      for (i = 0; i < itemDate.length; i++) {
        var testData = {};
        testData.itemLabel = itemLabel[i];
        testData.itemDate = itemDate[i];
    
        testDataArray[i] = testData;
      };
    
      $("#testList").test({
        itemArray: testDataArray,
        onItemClick: function(item) {
          console.log(item.itemLabel + ": " + item.itemDate);
        }
      });
    })
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <!--    <script src="/test.js"></script>   -->
    
    <div>
      <ul id="testList"></ul>
    </div>
    &#13;
    &#13;
    &#13;