首页 > 解决方案 > 带有标签触发事件两次的输入类型复选框

问题描述

我正在尝试使用 tickMark 动态创建圆形复选框,这些复选框附加到id="demo"调用get(data)方法的两个按钮的 onclick 上。

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

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

这里有什么问题, getdata(idD + '_chckBox')被调用了两次或更多,而roundcheckbox没有被检查?

我正在尝试切换复选框并显示刻度线。如果有任何更好的方法可以做到这一点,也欢迎。

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

索引.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>

标签: javascriptjqueryhtmlcss

解决方案


这里有几个错误。

  1. 你使用一些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>

代码笔


推荐阅读