所以我编写了一个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());
});
};
答案 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()循环的旁边,这个关键字可以让你访问单个项目。