[javascript] Gmail과 같은 여러 확인란을 Shift- 선택하려면 어떻게합니까?

Gmail에서 사용자는 이메일 목록에서 하나의 확인란을 클릭하고 Shift 키를 누른 상태에서 두 번째 확인란을 선택할 수 있습니다. 그러면 JavaScript는 두 체크 박스 사이에있는 체크 박스를 선택 / 선택 취소합니다.

이것이 어떻게 이루어지는 지 궁금합니다. 이 JQuery 또는 일부 기본 (또는 복잡한) JavaScript입니까?



답변

jquery를 사용하는 자체 포함 된 데모를 작성했습니다.

$(document).ready(function() {
    var $chkboxes = $('.chkbox');
    var lastChecked = null;

    $chkboxes.click(function(e) {
        if (!lastChecked) {
            lastChecked = this;
            return;
        }

        if (e.shiftKey) {
            var start = $chkboxes.index(this);
            var end = $chkboxes.index(lastChecked);

            $chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', lastChecked.checked);
        }

        lastChecked = this;
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
</head>
<body>
    <input type="checkbox" id="id_chk1" class="chkbox" value="1" />Check 1<br/>
    <input type="checkbox" id="id_chk2" class="chkbox" value="2" />Check 2<br/>
    <input type="checkbox" id="id_chk3" class="chkbox" value="3" />Check 3<br/>
    <input type="checkbox" id="id_chk4" class="chkbox" value="4" />Check 4<br/>
    <input type="checkbox" id="id_chk5" class="chkbox" value="5" />Check 5<br/>
    <input type="checkbox" id="id_chk6" class="chkbox" value="6" />Check 6<br/>
    <input type="checkbox" id="id_chk7" class="chkbox" value="7" />Check 7<br/>
</body>
</html>


답변

이것은 매우 간단한 자바 스크립트를 통해 이루어집니다.

마지막으로 선택한 상자의 ID를 추적하고 다른 확인란이 선택되면 shiftKey 이벤트 속성 을 사용 하여 확인란을 클릭하는 동안 shift가 유지되었는지 확인합니다. 그렇다면 두 확인란 사이에있는 각 확인란의 속성 을 true로 설정합니다.

상자가 선택되었는지 확인하기 위해 확인란에 onclick 이벤트를 사용합니다.


답변

최근에 그 기능 등을 제공하는 jQuery 플러그인을 작성했습니다.

플러그인을 포함시킨 후 다음 코드 스 니펫을 사용하여 체크 박스 컨텍스트를 초기화하면됩니다.

$('#table4').checkboxes({ range: true });

다음은 문서, 데모 및 다운로드 링크입니다. http://rmariuzzo.github.io/checkboxes.js/


답변

온라인에서 찾을 수있는 모든 답변은 jQuery에 완전히 의존하는 것 같습니다. JQuery는 기능을 거의 추가하지 않습니다. 다음은 프레임 워크가 필요없는 빠른 버전입니다.

function allow_group_select_checkboxes(checkbox_wrapper_id){
    var lastChecked = null;
    var checkboxes = document.querySelectorAll('#'+checkbox_wrapper_id+' input[type="checkbox"]');

    //I'm attaching an index attribute because it's easy, but you could do this other ways...
    for (var i=0;i<checkboxes.length;i++){
        checkboxes[i].setAttribute('data-index',i);
    }

    for (var i=0;i<checkboxes.length;i++){
        checkboxes[i].addEventListener("click",function(e){

            if(lastChecked && e.shiftKey) {
                var i = parseInt(lastChecked.getAttribute('data-index'));
                var j = parseInt(this.getAttribute('data-index'));
                var check_or_uncheck = this.checked;

                var low = i; var high=j;
                if (i>j){
                    var low = j; var high=i;
                }

                for(var c=0;c<checkboxes.length;c++){
                    if (low <= c && c <=high){
                        checkboxes[c].checked = check_or_uncheck;
                    }
                }
            }
            lastChecked = this;
        });
    }
}

그런 다음 필요할 때마다 초기화합니다.

allow_group_select_checkboxes('[id of a wrapper that contains the checkboxes]')


답변

글은 꽤 오래되었지만 방금 만난 해결책이 있습니다.
jQuery Field Plug-In


답변

에서이 솔루션있어 http://abcoder.com/javascript/jquery/simple-check-uncheck-all-jquery-function/을 (아직) :

JavaScript 및 HTML 코드

var NUM_BOXES = 10;

// last checkbox the user clicked
var last = -1;

function check(event) {
  // in IE, the event object is a property of the window object
  // in Mozilla, event object is passed to event handlers as a parameter
  if (!event) { event = window.event }
  var num = parseInt(/box\[(\d+)\]/.exec(this.name)[1]);
  if (event.shiftKey && last != -1) {
     var di = num > last ? 1 : -1;
     for (var i = last; i != num; i += di) {
        document.forms.boxes['box[' + i + ']'].checked = true;
     }
  }
  last = num;
}

function init() {
  for (var i = 0; i < NUM_BOXES; i++) {
    document.forms.boxes['box[' + i + ']'].onclick = check;
  }
}
<body onload="init()">
    <form name="boxes">
    <input name="box[0]" type="checkbox">
    <input name="box[1]" type="checkbox">
    <input name="box[2]" type="checkbox">
    <input name="box[3]" type="checkbox">
    <input name="box[4]" type="checkbox">
    <input name="box[5]" type="checkbox">
    <input name="box[6]" type="checkbox">
    <input name="box[7]" type="checkbox">
    <input name="box[8]" type="checkbox">
    <input name="box[9]" type="checkbox">
    </form>
</body>


답변

제공된 훌륭한 답변에서 영감을 얻은 여기 Array.prototype에는 for루프가 아닌 배열 함수를 사용하도록 노드 목록을 강제 하는 데 사용하는 일반 JavaScript 버전 이 있습니다.

(function () { // encapsulating variables with IIFE
  var lastcheck = null // no checkboxes clicked yet

  // get desired checkboxes
  var checkboxes = document.querySelectorAll('div.itemslist input[type=checkbox]')

  // loop over checkboxes to add event listener
  Array.prototype.forEach.call(checkboxes, function (cbx, idx) {
    cbx.addEventListener('click', function (evt) {

      // test for shift key, not first checkbox, and not same checkbox
      if ( evt.shiftKey && null !== lastcheck && idx !== lastcheck ) {

        // get range of checks between last-checkbox and shift-checkbox
        // Math.min/max does our sorting for us
        Array.prototype.slice.call(checkboxes, Math.min(lastcheck, idx), Math.max(lastcheck, idx))
          // and loop over each
          .forEach(function (ccbx) {
            ccbx.checked = true
        })
      }
      lastcheck = idx // set this checkbox as last-checked for later
    })
  })
}())
<div class="itemslist">
  <input type="checkbox" name="one"   value="1">
  <input type="checkbox" name="two"   value="2">
  <input type="checkbox" name="three" value="3">
  <input type="checkbox" name="four"  value="4">
  <input type="checkbox" name="five"  value="5">
</div>