我正在尝试动态创建带有tickMark的圆形复选框,单击两个单击id="demo"
方法的按钮后,它们会附加到get(data)
上。
问题是,当同时调用两个按钮时,复选框未获得刻度,并导致两次调用getdata(idD + '_chckBox')
方法,如在console.log中所示。
但是,我正在使用e.preventDefault(); e.stopPropagation();
。
这里是什么问题,getdata(idD + '_chckBox')
被调用了两次或多次,并且roundcheckbox没有被选中?
我正在尝试切换复选框并显示刻度线。如果有更好的方法可以实现,也欢迎您。
在for循环中的动态html中,绑定onclick
和onscroll
方法的最佳和最简便的方法是什么,以便可以在调用的onclick方法中将对象作为参数传递。
var data0 = [{
"title": "a"
},
{
"title": "b"
},
{
"title": "c"
},
{
"title": "d"
},
];
var data1 = [{
"title": "ads"
},
{
"title": "bd"
},
{
"title": "fc"
},
{
"title": "dg"
},
];
var html = "<div id='parent' ' + 'onscroll="loadMoreContent(event)" ></div>";
$(html ).appendTo('body');
$(document).on('click', '#btn11', () => {
get(data0, 'parent');
})
$(document).on('click', '#btn00', () => {
get(data1,'parent');
})
function loadMoreContent(event){
// gettting server data (data01 ) on ajax call
var data01 = [{
"title": "aaa"
},
{
"title": "sdw3b"
},
{
"title": "c433"
},
{
"title": "34d"
},
];
get(data01 , idToAppend)
}
function get(data, idToAppend) {
var html = '';
html += '<div class="col-12 parentdiv">';
$.each(data, function(key, msgItem) {
var idD = msgItem.title + key;
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget" id="' + idD + '_roundCheckboxWidget">';
html += '<input id="' + idD + '_chckBox" class="" type="checkbox" tid="" title="discard">';
html += '<label id="' + idD + '_chckBox_label" for="' + msgItem.title + '" ></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
});
html += '</div>';
$('#'+ idToAppend).append(html);
$.each(data, function(index, element) {
var idD = element.title + index;
const self = this;
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
if (e.target.tagName === "LABEL") {
e.preventDefault();
e.stopPropagation();
console.log('#' + idD + '_chckBox_label');
getdata(idD + '_chckBox');
}
});
});
}
function getdata(id) {
console.log(id);
$("#" + id).prop("checked", !$("#" + id).prop("checked"));
return true;
}
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11" onclick="get()">Try It</button>
<button id="btn00" onclick="get()">Try It2</button>
<div id="demo"></div>
答案 0 :(得分:4)
这里有几个错误。
id
。尝试使它们唯一,但是您使用了静态的数组key
。因此,每次单击按钮都会产生重复的ID。您需要一个柜台。.each()
循环来定义委托事件处理程序...这是对委托的误解。checkbox
上的for=
属性不需要一行代码时,您可以使用一个函数来切换label
状态。loadMoreContent()
函数不清楚...我假设您想要“无限滚动” ...所以您必须检查是否到达页面底部才能调用Ajax请求...否则,您将在每次滚动时触发大量请求……上下!这是操作方法:
(请参见代码中的注释)
// checkbox title arrays
var data0 = [{ "title": "a" }, { "title": "b" }, { "title": "c" }, { "title": "d" }];
var data1 = [{ "title": "ads" }, { "title": "bd" }, { "title": "fc" }, { "title": "dg" }];
// Appends th "parent" div on load.
var html = "<div id='parent'></div>";
$(html).appendTo('body');
// Button handlers
$(document).on('click', '#btn11', () => {
get(data0,'parent');
})
$(document).on('click', '#btn00', () => {
get(data1,'parent');
})
// Simulated Ajax request... I assume.
function loadMoreContent(idToAppend){
// gettting server data (data01 ) on ajax call
var data01 = [{ "title": "aaa" }, { "title": "sdw3b" }, { "title": "c433" }, { "title": "34d" } ];
get(data01 , idToAppend)
}
// Main function. It needs a counter to create UNIQUE ids.
var checkbox_counter = 0;
function get(data, idToAppend) {
var html = '';
html += '<div class="col-12 parentdiv">';
$.each(data, function(key, msgItem) {
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget">';
html += '<input id="checkbox_'+checkbox_counter+'" type="checkbox" tid="" title="discard">';
html += '<label for="checkbox_'+checkbox_counter+'"></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
// Increment the checkbox counter
checkbox_counter++;
});
html += '</div>';
$('#'+ idToAppend).append(html);
}
// Just to console log the id of the checkbox...
$(document).on('click', 'label', function(){
var checkbox_id = $(this).prev("[type='checkbox']").attr("id");
console.log(checkbox_id);
});
// On scroll handler, check if the bottom of the page is reached to load some more...
$(document).on('scroll', function(){
var scrolled = Math.ceil($(window).scrollTop());
var viewport_height = $(window).outerHeight();
var window_full_height = $(document).outerHeight();
//console.log(scrolled +" "+ viewport_height +" "+ window_full_height);
if(scrolled + viewport_height == window_full_height){
console.log("reached the bottom... Loading some more!");
// Call the Ajax request
loadMoreContent("parent");
}
});
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11" onclick="get()">Try It</button>
<button id="btn00" onclick="get()">Try It2</button>
<div id="demo"></div>
答案 1 :(得分:2)
代码有两个问题:
onclick="get()"
,还使用jQuery添加了click
事件,它将触发两次。删除onclick ="get()"
get()
时,都会在复选框中添加新的click
侦听器。为防止在您的数组中使用布尔值,只能应用一次click
事件
var data0 = [{
"title": "a"
},
{
"title": "b"
},
{
"title": "c"
},
{
"title": "d"
},
false
];
var data1 = [{
"title": "ads"
},
{
"title": "bd"
},
{
"title": "fc"
},
{
"title": "dg"
},
false
];
$(document).on('click', '#btn11', () => {
get(data0);
})
$(document).on('click', '#btn00', () => {
get(data1);
})
function get(data) {
var html = '';
html += '<div class="col-12 parentdiv"';
$.each(data, function(key, msgItem) {
var idD = msgItem.title + key;
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget" id="' + idD + '_roundCheckboxWidget">';
html += '<input id="' + idD + '_chckBox" class="" type="checkbox" tid="" title="discard">';
html += '<label id="' + idD + '_chckBox_label" for="' + msgItem.title + '" ></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
});
html += '</div>';
$('#demo').html(html);
if(data[data.length - 1]) return false;
$.each(data, function(index, element) {
var idD = element.title + index;
const self = this;
if(index === data.length - 1) return false;
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
if (e.target.tagName === "LABEL") {
e.preventDefault();
e.stopPropagation();
//console.log('#' + idD + '_chckBox_label');
getdata(idD + '_chckBox');
}
});
});
data[data.length -1] = true;
}
function getdata(id) {
//console.log(id);
$("#" + id).prop("checked", !$("#" + id).prop("checked"));
return true;
}
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11">Try It</button>
<button id="btn00">Try It2</button>
<div id="demo"></div>
答案 2 :(得分:2)
TL; DR
在绑定一个新的事件处理程序之前,先解除其绑定。使用此代码:
$(document).off('click', '#' + idD + '_chckBox_label').on('click', '#' + idD + '_chckBox_label', (e) => {
长答案
您不能使用e.preventDefault(); e.stopPropagation();
停止不同函数调用。这是东西,
假设您的dom中有一个元素,并且两次添加了事件处理程序,在这种情况下,无论如何,这两个事件处理程序都将被执行。
这里您需要的是
“在添加新的单击处理程序之前删除现有的单击处理程序”。
此行:
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
将事件处理程序添加到标签。但是当您再次单击按钮时,它将再次运行并添加另一个事件处理程序。
因此,单击按钮的次数与添加到元素中的事件处理程序的次数相同。
但是当您刷新时,它是固定的。原因:刷新页面将加载一个全新的页面,并且所有以前的处理程序都消失了。您需要以编程方式执行此操作,这是您可以执行的操作。
$(document).off('click', '#' + idD + '_chckBox_label').on('click', '#' + idD + '_chckBox_label', (e) => {
此代码说明,请关闭所有以前的单击处理程序并添加一个新的单击处理程序。
奖金:
如果您具有命名函数,则可以删除特定的事件处理程序,例如:
$(document).off(<event_type>, <el_selector>, <event_handler>).on(<event_type>, <el_selector>, <event_handler>);
希望这会有所帮助。让我知道您是否有任何反问。
PS:复制粘贴时,代码中有一些错别字,但是我认为运行代码不是这里的议程:)
答案 3 :(得分:0)
您在这里有2个点击事件监听器:
$(document).on('click', '#btn11', () => {
get(data0);
})
$(document).on('click', '#btn00', () => {
get(data1);
})
您的get()
函数包含两个$.each()
循环,其中第二个循环是在此处添加另一个事件侦听器:
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
if (e.target.tagName === "LABEL") {
e.preventDefault();
e.stopPropagation();
console.log('#' + idD + '_chckBox_label');
getdata(idD + '_chckBox');
}
});
据我所知,当您单击第二个按钮时,可能有3个事件侦听器对该事件做出响应。