标签类型触发两次的输入类型复选框

时间:2019-03-14 03:13:05

标签: javascript jquery html css

我正在尝试动态创建带有tickMark的圆形复选框,单击两个单击id="demo"方法的按钮后,它们会附加到get(data)上。

问题是,当同时调用两个按钮时,复选框未获得刻度,并导致两次调用getdata(idD + '_chckBox')方法,如在console.log中所示。

但是,我正在使用e.preventDefault(); e.stopPropagation();

这里是什么问题,getdata(idD + '_chckBox')被调用了两次或多次,并且roundcheckbox没有被选中?

我正在尝试切换复选框并显示刻度线。如果有更好的方法可以实现,也欢迎您。

在for循环中的动态html中,绑定onclickonscroll方法的最佳和最简便的方法是什么,以便可以在调用的onclick方法中将对象作为参数传递。

index.html

   

     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 += "&nbsp;" + 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>

4 个答案:

答案 0 :(得分:4)

这里有几个错误。

  1. 您使用了一些{strong>不是唯一的id。尝试使它们唯一,但是您使用了静态的数组key。因此,每次单击按钮都会产生重复的ID。您需要一个柜台。
  2. 您使用.each()循环来定义委托事件处理程序...这是对委托的误解。
  3. checkbox上的for=属性不需要一行代码时,您可以使用一个函数来切换label状态。
  4. 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 += "&nbsp;" + 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>

CodePen

答案 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 += "&nbsp;" + 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个事件侦听器对该事件做出响应。