Gmail에서 사용자는 이메일 목록에서 하나의 확인란을 클릭하고 Shift 키를 누른 상태에서 두 번째 확인란을 선택할 수 있습니다. 그러면 JavaScript는 두 체크 박스 사이에있는 체크 박스를 선택 / 선택 취소합니다.
이것이 어떻게 이루어지는 지 궁금합니다. 이 JQuery 또는 일부 기본 (또는 복잡한) JavaScript입니까?
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>
나는 gyo의 예제를 정말 좋아하고 코드를 추가하여 동일한 이름의 모든 확인란에서 작동합니다.
또한 MutationObserver를 추가하여 이벤트가 새로 추가 된 확인란에서도 처리됩니다.
$(document).ready(function() {
var previouslyClicked = {};
var rangeEventHandler = function(event) {
if (event.shiftKey && previouslyClicked[this.name] && this != previouslyClicked[this.name]) {
var $checkboxes = $('input[type=checkbox][name='+this.name+']').filter(':visible');
var start = $checkboxes.index( this );
var end = $checkboxes.index( previouslyClicked[this.name] );
// console.log('range', start, end, this, previouslyClicked[this.name]);
$checkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', previouslyClicked[this.name].checked);
} else {
previouslyClicked[this.name] = this;
}
};
if ("MutationObserver" in window) { // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver to refresh on new checkboxes
var mutationCallback = function(mutationList, observer) {
mutationList.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeName == 'INPUT' && node.type == 'checkbox') {
$(node).on('click.selectRange', rangeEventHandler);
}
});
});
};
var observer = new MutationObserver(mutationCallback);
observer.observe(document, {
childList: true,
attributes: false, // since name is dynamically read
subtree: true
});
}
$('input[type=checkbox][name]').on('click.selectRange', rangeEventHandler);
});
<html>
<head>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
First:
<input type="checkbox" name="first">
<input type="checkbox" name="first">
<input type="checkbox" name="first">
<input type="checkbox" name="first">
<input type="checkbox" name="first">
</div>
<div>
Second:
<input type="checkbox" name="second">
<input type="checkbox" name="second">
<input type="checkbox" name="second">
<input type="checkbox" name="second">
<input type="checkbox" name="second">
</div>
</body>
</html>
@BC에서 jQuery 버전을 가져 왔습니다. 코드가 실제로 문제를 꽤 우아하게 해결하고 있기 때문에 ES6 버전으로 변환했습니다.
function enableGroupSelection( selector ) {
let lastChecked = null;
const checkboxes = Array.from( document.querySelectorAll( selector ) );
checkboxes.forEach( checkbox => checkbox.addEventListener( 'click', event => {
if ( !lastChecked ) {
lastChecked = checkbox;
return;
}
if ( event.shiftKey ) {
const start = checkboxes.indexOf( checkbox );
const end = checkboxes.indexOf( lastChecked );
checkboxes
.slice( Math.min( start, end ), Math.max( start, end ) + 1 )
.forEach( checkbox => checkbox.checked = lastChecked.checked );
}
lastChecked = checkbox;
} ) );
}
선택 및 선택 취소 확인란 모두에 대해 더 나은 솔루션을 찾았습니다.
핵심 자바 스크립트 및 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', e.target.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>
Outlooks 다중 선택과 유사한 또 다른 구현도 있습니다.
<script type="text/javascript">
function inRange(x, range)
{
return (x >= range[0] && x <= range[1]);
}
$(document).ready(function() {
var $chkboxes = $('.chkbox');
var firstClick = 1;
var lastClick = null;
var range = [];
$chkboxes.click(function(e) {
if(!e.shiftKey && !e.ctrlKey) {
$('#index-' + firstClick).prop('checked', false);
firstClick = $chkboxes.index(this) + 1;
if (firstClick !== null && firstClick !== ($chkboxes.index(this)+1)) {
$('#index-' + firstClick).prop('checked', true);
}
} else if (e.shiftKey) {
lastClick = $chkboxes.index(this) + 1;
if ((firstClick < lastClick) && !inRange(lastClick, range)) {
for (i = firstClick; i < lastClick; i++) {
$('#index-' + i).prop('checked', true);
}
range = [firstClick, lastClick];
} else if ((firstClick > lastClick) && !inRange(lastClick, range)) {
for (i = lastClick; i < firstClick; i++) {
$('#index-' + i).prop('checked', true);
}
range = [lastClick, firstClick];
} else if ((firstClick < lastClick) && inRange(lastClick, range)) {
for (i = 1; i < 100; i++) {
$('#index-' + i).prop('checked', false);
}
for (i = firstClick; i < lastClick; i++) {
$('#index-' + i).prop('checked', true);
}
range = [firstClick, lastClick];
}else if ((firstClick > lastClick) && inRange(lastClick, range)) {
for (i = 1; i < 100; i++) {
$('#index-' + i).prop('checked', false);
}
for (i = lastClick; i < firstClick; i++) {
$('#index-' + i).prop('checked', true);
}
range = [lastClick, firstClick];
}
}
});
});
이것은 내가 작성하고 사용하는 jquery 솔루션입니다.
chksel
chksel_index
또한 각각 에는 동일한 색인을 포함 checkbox
하는 이름 rg
이 지정된 속성 이 있습니다.
var chksel_last=-1;
$('.chksel').click(function(ev){
if(ev.shiftKey){var i=0;
if(chksel_last >=0){
if($(this).attr('rg') >= chksel_last){
for(i=chksel_last;i<=$(this).attr('rg');i++){$('.chksel_'+i).attr('checked','true')}}
if($(this).attr('rg') <= chksel_last){for(i=$(this).attr('rg');i<=chksel_last;i++){$('.chksel_'+i).attr('checked','true')}}
}
chksel_last=$(this).attr('rg');
}else{chksel_last=$(this).attr('rg');}
})
이 솔루션은 나를 위해 작동하며 DataTables https://jsfiddle.net/6ouhv7bw/4/ 기반 ajax
<table id="dataTable">
<tbody>
<tr>
<td><input type="checkbox"></td>
</tr>
<tr>
<td><input type="checkbox"></td>
</tr>
<tr>
<td><input type="checkbox"></td>
</tr>
<tr>
<td><input type="checkbox"></td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function() {
var $chkboxes = $('#dataTable');
var $range = '#dataTable tbody';
var $first = false;
var $indexWrapp = 'tr';
var lastChecked = null;
var $checkboxes = 'input[type="checkbox"]';
$chkboxes.on('click',$checkboxes,function(e) {
if ($first===false) {
lastChecked = $(this).closest($indexWrapp).index();
lastCheckedInput = $(this).prop('checked');
$first=true;
return;
}
if (e.shiftKey) {
var start = lastChecked;
var end = $(this).closest($indexWrapp).index();
$( $range+' '+$indexWrapp).each(function() {
$currIndex=$(this).index();
if( $currIndex>=start && $currIndex<=end ){
$(this).find($checkboxes).prop('checked', lastCheckedInput);
}
})
}
lastCheckedInput = $(this).prop('checked');
lastChecked = $(this).closest($indexWrapp).index();
});
</script>