调用jQuery扩展会停止循环

时间:2012-11-12 18:36:27

标签: jquery jquery-plugins for-loop

所以我编写了一个jquery插件,将select元素转换为具有相同功能的可设置div和ul。我之前曾单独调用每个select元素,如下所示:

$("#myElementId").selectList();

但是现在我已经决定我希望能够将“selectList”类添加到选择列表中,然后使用selectList类遍历所有元素并将它们转换为动态元素,如下所示: / p>

var selects = $(".selectList");
for (i=0,j=selects.length;i<j;i++){
    $(selects[i]).selectList();
}

哪种方法很好,但仅适用于第一个元素。出于某种原因,一旦调用.selectList(),它就会结束我的for循环,它永远不会进入下一次迭代。我不知道为什么。我已经验证$(".selectList")确实长于1,如果我在循环中除了console.log(selects[i])之外什么都没有,我会按预期得到每个元素的日志。直到我在其中一个上调用我的扩展名才停止循环。

有人可以向我解释一下这种行为吗?

如果您需要,这是我的插件代码。请不要重新分发或重复使用,并在js文件的注释中记入我:

// Custom select element functionality.
jQuery.fn.selectList = function(){

// Grab the original select element and it's options
var originalSelect = this;
var originalOptions = originalSelect.children("option");
var originalId = originalSelect.attr("id");

// Set the original select item to be hidden
originalSelect.css({"display": "none !important"});

// Set up our replacement block
var newContainer = "<div class='selectList_container' id='" + originalId + "_selectList' tabindex='0'>" + 
                      "<p class='selectList_value'>" + $(originalOptions[0]).html() + "</p>" + 
                      "<div class='selectList_optionsWrapper' style='height: 0 !important'>" + 
                         "<ul class='selectList_options' style='display: none;'></ul>" + 
                      "</div>" + 
                   "</div>";

// Append it to the original container
$(newContainer).insertAfter(originalSelect);

// Set up our new variables.  All references from here on in the script will reference the existing element already added to the document.
newContainer = $("#" + originalId + "_selectList");
var newValue = newContainer.find(".selectList_value");
var newList = newContainer.find(".selectList_options");
var newItems;

// Function to toggle the list
var toggleList = function(){
    newList.toggle();
};

// Create our options and add them to our new list
for (i=0, j=originalOptions.length; i<j; i++){

    // Get original option values
    var thisOption = $(originalOptions[i]);
    var optionText = thisOption.html();
    var optionValue = thisOption.val();

    // Build out our new item
    var newItem = "<li name='" + optionValue + "'";

    // Add a class of first and last to the first and last options to aid in styling
    if (i == 0) {
        newItem += " class='first' ";
    } else if (i == (j-1)){
        newItem += " class='last' ";
    };

    // Close out our new item
    newItem += ">" + optionText + "</li>";

    // Add our new item to the newItems string to be added to the dom later
    newItems += newItem;
};

// Add our new item to the list we've made
$(newItems).appendTo(newList);

// Reference to the new list items
var newOptions = $("#" + originalId + "_selectList .selectList_options li");

// Default CSS values for our new dom elements
newContainer.css({position: "relative"});
newValue.css({cursor: "pointer", display: "block", "text-align": "left"});
newList.css({margin: "0 auto", "z-index": "9999999"});
newOptions.css({cursor: "pointer", display: 'block'})

// Opens and closes the new select list when the select value is clicked on
newValue.click(toggleList);

// Closes the list if the select element loses focus (mimics default select element behavior).
// In order for this to work, the element the blur event listener is being bound to must have the attribute tabIndex=0.
// This tricks the browser into thinking it is a form element, otherwise blur will not fire.
newContainer.blur(function(){
    // This is in a setTimeout function because of the way IE detects the blur. 
    // 150ms is seamless to the end user but upholds the functionality in IE.
    window.setTimeout(function hide_list(){
        if (newList.is(":visible")) {
            toggleList();   
        };
    },150);
});

// Changes the value of our new select value and activates the old select option when one of our new list items is clicked
for (i=0, j=newOptions.length; i<j; i++) {
    $(newOptions[i]).click(function(){
        var thisText = $(this).html();
        var thisValue = $(this).attr("name");

        newValue.html(thisText).attr({"name": thisValue});
        newList.toggle();
        originalSelect.val($(this).attr("name")).trigger('change');
    });
};

// Make sure if the original select list changes without the use of our new elements, that the new elements stay updated.
this.change(function(){
    newValue.html($(this).find("option:selected").text());
});
};

3 个答案:

答案 0 :(得分:1)

如何使用 $。每个,使用它的当前上下文应该有帮助..

$(".selectList").each(function() {

   $(this).selectList()

});

可能会将其转换为DOM元素选择[i] 似乎正在创建问题..

答案 1 :(得分:1)

查看authoring plugin guide。您需要在插件中使用this.each来循环选定元素并返回此选项以保持可链接性。

$.fn.selectList = function() {  

   return this.each(function() {
     var $this = $(this);
   }); 

};

答案 2 :(得分:0)

您应该在

中应用所有代码
$.fn.selectList = function() { 
         this.each(function() {
  :
   //your code
   :
         });
}

阻止以确保它适用于选择器中的所有元素。在each()循环的旁边,这个关键字可以让你访问单个项目。

参考:http://docs.jquery.com/Plugins/Authoring