Javascript 在单击之前,无法选择动态添加的列表项
我已经编写了一个小JQuery插件,它基于引导创建了一个下拉框。我已经将其写入数据属性提供url以生成列表项的位置。在ajax调用之后,Jquery循环遍历列表项并将它们插入下拉菜单。我不明白的是,这个插件使用了一个div和.combobox类,并附加了创建combobox所需的html。它使用两个函数,Javascript 在单击之前,无法选择动态添加的列表项,javascript,jquery,html,ajax,twitter-bootstrap,Javascript,Jquery,Html,Ajax,Twitter Bootstrap,我已经编写了一个小JQuery插件,它基于引导创建了一个下拉框。我已经将其写入数据属性提供url以生成列表项的位置。在ajax调用之后,Jquery循环遍历列表项并将它们插入下拉菜单。我不明白的是,这个插件使用了一个div和.combobox类,并附加了创建combobox所需的html。它使用两个函数,\u create()和\u listItems()\u create()实际上是添加html并调用\u listItems()来进行ajax调用,并返回要追加的列表项。看起来像这样: ;(fu
\u create()
和\u listItems()
\u create()
实际上是添加html并调用\u listItems()
来进行ajax调用,并返回要追加的列表项。看起来像这样:
;(function ( $, window, document, undefined ) {
var Combobox = function(element,options) {
this.$element = $(element);
this.$options = $.extend({}, $.fn.combobox.defaults, options);
this.$html = {
input: $('<input type="text" placeholder="[SELECT]" />').addClass('form-control'),
button: $('<div id="test"/>').addClass('input-group-btn')
.append($('<button />')
.addClass('btn btn-default input-sm')
.append('<span class="caret"></span>'))
}
this.$list_type = this.$element.attr('data-type');
this.$url = this.$element.attr('data-url');
this.$defaultValue = this.$element.attr('data-default');
this._create();
this.$input = this.$element.find('input');
this.$button = this.$element.find('button');
this.$list = this.$element.find('ul')
this.$button.on('click',$.proxy(this._toggleList,this));
this.$element.on('click','li',$.proxy(this._itemClicked,this));
this.$element.on('mouseleave',$.proxy(this._toggleList,this));
if(this.$defaultValue) {
this.selectByValue(this.$defaultValue);
}
}
Combobox.prototype = {
constructor: Combobox,
_create: function() {
this.$element.addClass('input-group input-group-sm')
.append(this.$html.input)
.append(this._listItems())
.append(this.$html.button);
},
_itemClicked: function(e){
this.$selectedItem = $(e.target).parent();
this.$input.val(this.$selectedItem.text());
console.log(this.$element.find('[data-value="W"]'))
this._toggleList(e);
e.preventDefault();
},
_listItems: function() {
var list = $('<ul />').addClass('dropdown-menu');
$.ajax({
url: this.$url,
type: 'POST',
data: {opt: this.$list_type},
success:function(data){
$.each(data,function(key,text){
list.append($('<li class="listObjItem" data-value="'+text.id+'"><a href="#">'+text.value+'</a></li>'));
})
}
})
return list
},
selectedItem: function() {
var item = this.$selectedItem;
var data = {};
if (item) {
var txt = this.$selectedItem.text();
data = $.extend({ text: txt }, this.$selectedItem.data());
}
else {
data = { text: this.$input.val()};
}
return data;
},
selectByValue: function(value) {
var selector = '[data-value="'+value+'"]';
this.selectBySelector(selector);
},
selectBySelector: function (selector) {
var $item = this.$element.find(selector);
if (typeof $item[0] !== 'undefined') {
this.$selectedItem = $item;
this.$input.val(this.$selectedItem.text());
}
else {
this.$selectedItem = null;
}
},
enable: function () {
this.$input.removeAttr('disabled');
this.$button.children().removeClass('disabled');
this.$button.on('click',$.proxy(this._toggleList,this));
},
disable: function () {
this.$input.attr('disabled', true);
this.$button.children().addClass('disabled');
this.$button.off('click',$.proxy(this._toggleList,this));
},
_toggleList: function(e) {
if(e.type == 'mouseleave') {
if(this.$list.is(':hidden')) {
return false;
} else {
this.$list.hide();
}
} else {
this.$list.toggle();
e.preventDefault();
}
}
}
$.fn.combobox = function (option) {
return this.each(function () {
if (!$.data(this, 'combobox')) {
$.data(this, 'combobox',
new Combobox( this, option ));
}
});
};
$.fn.combobox.defaults = {};
$.fn.combobox.Constructor = Combobox;
})( jQuery, window, document );
;(函数($,窗口,文档,未定义){
var Combobox=函数(元素、选项){
此.$element=$(element);
这个.$options=$.extend({},$.fn.combobox.defaults,options);
这是。$html={
输入:$('').addClass('form-control'),
按钮:$('').addClass('input-group-btn')
.append($('')
.addClass('btn btn默认输入sm')
.附加(“”))
}
this.$list_type=this.$element.attr('data-type');
this.$url=this.$element.attr('data-url');
this.$defaultValue=this.$element.attr('data-default');
这个;
this.$input=this.$element.find('input');
this.$button=this.$element.find('button');
this.$list=this.$element.find('ul'))
this.$button.on('click',$.proxy(this.\u toggleList,this));
this.$element.on('click','li',$.proxy(this.\u itemClicked,this));
this.$element.on('mouseleave',$.proxy(this._toggleList,this));
如果(此.$defaultValue){
this.selectByValue(this.$defaultValue);
}
}
Combobox.prototype={
构造函数:组合框,
_创建:函数(){
此.$element.addClass('input-group input group sm')
.append(此.$html.input)
.append(此.\u listItems())
.append(此.$html.button);
},
_项目:功能(e){
这是。$selectedItem=$(e.target).parent();
this.$input.val(this.$selectedItem.text());
console.log(this.$element.find('[data value=“W”]'))
此开关列表(e);
e、 预防默认值();
},
_listItems:function(){
var list=$(“
”).addClass('dropdown-menu');
$.ajax({
url:this.$url,
键入:“POST”,
数据:{opt:this.$list_type},
成功:功能(数据){
$。每个(数据、函数(键、文本){
list.append($(');
})
}
})
返回列表
},
selectedItem:function(){
变量项=此项。$selectedItem;
变量数据={};
如果(项目){
var txt=this.$selectedItem.text();
data=$.extend({text:txt},this.$selectedItem.data());
}
否则{
data={text:this.$input.val()};
}
返回数据;
},
selectByValue:函数(值){
变量选择器=“[data value=“”+value+”]”;
此。selectBySelector(选择器);
},
selectBySelector:功能(选择器){
var$item=this.$element.find(选择器);
if(类型为$item[0]!==“未定义”){
此项。$selectedItem=$item;
this.$input.val(this.$selectedItem.text());
}
否则{
此项。$selectedItem=null;
}
},
启用:函数(){
此.$input.removeAttr('disabled');
此.button.children().removeClass('disabled');
this.$button.on('click',$.proxy(this.\u toggleList,this));
},
禁用:函数(){
这是。$input.attr('disabled',true);
此.button.children().addClass('disabled');
this.$button.off('click',$.proxy(this.\u toggleList,this));
},
_切换列表:函数(e){
如果(e.type=='mouseleave'){
如果(此.$list.is(':hidden')){
返回false;
}否则{
这是。$list.hide();
}
}否则{
这是。$list.toggle();
e、 预防默认值();
}
}
}
$.fn.combobox=函数(选项){
返回此。每个(函数(){
if(!$.data(此“组合框”)){
$.data(此“组合框”,
新组合框(此选项));
}
});
};
$.fn.combobox.defaults={};
$.fn.combobox.Constructor=combobox;
})(jQuery、窗口、文档);
问题是,在项目附加到DOM之后,所有内容都是可选的,可以接受列表项目。我当前有一个.on()
语句,它将单击事件与列表项绑定在一起。为了测试这一点,我使用了console.log(this.$element.find('[data value=“W”]'))
并且它不返回元素,但是如果我将同一个控制台日志放在列表项的单击回调中,它将返回元素并且可以选择。我是否做错了什么
编辑
我粘贴了整个插件以避免混淆。“我目前有一个.on()语句将单击事件与列表项绑定。”。代码在哪里?'this.$element.on('click','li',$.proxy(this.\u itemClicked,this));'这是我的第一篇文章,我需要粘贴整个插件吗?这会更有帮助吗?