Với một sửa đổi nhỏ, bạn có thể làm như thế này:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
<style>
#grid {
display: grid;
grid-template-columns: repeat(3, 50px);
grid-template-rows: repeat(2, 50px);
}
.cell {
display: flex;
justify-content: center;
align-items: center;
border: solid 1px #ccc;
}
.active {
background-color: #80aaff;
}
</style>
<script>
document.addEventListener('DOMContentLoaded',e=>{
const grid = document.getElementById('grid')
const cells= grid.querySelectorAll('div');
grid.addEventListener('click',function(e){
e.stopPropagation();
cells.forEach( cell=>{
cell.classList.remove('active')
});
event.target.classList.add('active');
if( event.ctrlKey ) {
Array.from(cells).some( cell=>{
cell.classList.add('active')
if( cell==event.target )return true;
})
}
});
});
</script>
</head>
<body>
<div id="grid">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell">6</div>
</div>
</body>
</html>
document.addEventListener('DOMContentLoaded',e=>{
const grid = document.getElementById('grid')
const cells= grid.querySelectorAll('div');
grid.addEventListener('click',function(e){
e.stopPropagation();
cells.forEach( cell=>{
cell.classList.remove('active')
});
e.target.classList.add('active');
if( e.ctrlKey ) {
Array.from(cells).some( cell=>{
cell.classList.add('active')
if( cell==e.target )return true;
})
}
});
});
#grid {
display: grid;
grid-template-columns: repeat(3, 50px);
grid-template-rows: repeat(2, 50px);
}
.cell {
display: flex;
justify-content: center;
align-items: center;
border: solid 1px #ccc;
}
.active {
background-color: #80aaff;
}
<div id="grid">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell">6</div>
</div>
Sau khi nhận xét về điều này không hoạt động ngược, tôi đã băm lại bản gốc một chút để nó hoạt động theo cả hai hướng lựa chọn. Phiên bản chỉnh sửa sử dụng các dataset
thuộc tính - trong trường hợp này được chỉ định là số nguyên. Một bản ghi được lưu giữ ô ban đầu được nhấp và, nếu ctrl
nhấn phím, một phép tính đơn giản được thực hiện để xác định xem người dùng đang chọn tiến hay lùi - điều này ảnh hưởng đến vòng lặp được sử dụng và do đó việc gán lớp hoạt động. Một điều chỉnh nhỏ cho CSS bằng các biến chỉ là để thuận tiện ...
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
<style>
:root{
--rows:2;
--cols:3;
--size:50px;
}
#grid {
display:grid;
grid-template-columns:repeat(var(--cols),var(--size));
grid-template-rows:repeat(var(--rows),var(--size));
width:calc(var(--size) * var(--cols));
}
.cell {
display: flex;
flex:1;
justify-content: center;
align-items: center;
border: solid 1px #ccc;
margin:1px;
cursor:pointer;
}
.active {
background-color: #80aaff;
}
</style>
<script>
document.addEventListener('DOMContentLoaded',e=>{
let range=[];
const grid = document.getElementById('grid')
const cells = grid.querySelectorAll('div');
const getcell=function(i){
return grid.querySelector('[data-index="'+i+'"]');
}
const clickhandler=function(e){
e.stopPropagation();
range.push( e.target );
/* clear cells of the "active" class */
cells.forEach( cell=>{
cell.classList.remove('active')
});
/* Assign the initially selected cell as "active" */
e.target.classList.add('active');
if( e.ctrlKey ) {
/* Is the user selecting forwards or backwards? */
if( range[0].dataset.index < e.target.dataset.index ){
for( let i=range[0].dataset.index; i < e.target.dataset.index; i++ )getcell(i).classList.add('active')
} else if( range[0].dataset.index == e.target.dataset.index ){
e.target.classList.add('active')
} else {
for( let i=range[0].dataset.index; i > e.target.dataset.index; i-- )getcell(i).classList.add('active')
}
range=[];
}
};
/* assign an integer index to each cell within parent */
cells.forEach( ( cell, index )=>{
cell.dataset.index = index + 1;
});
grid.addEventListener( 'click', clickhandler );
});
</script>
</head>
<body>
<div id="grid">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell">6</div>
</div>
</body>
</html>
document.addEventListener('DOMContentLoaded',e=>{
let range=[];
const grid = document.getElementById('grid')
const cells = grid.querySelectorAll('div');
const getcell=function(i){
return grid.querySelector('[data-index="'+i+'"]');
}
const clickhandler=function(e){
e.stopPropagation();
range.push( e.target );
/* clear cells of the "active" class */
cells.forEach( cell=>{
cell.classList.remove('active')
});
/* Assign the initially selected cell as "active" */
e.target.classList.add('active');
if( e.ctrlKey ) {
/* Is the user selecting forwards or backwards? */
if( range[0].dataset.index < e.target.dataset.index ){
for( let i=range[0].dataset.index; i < e.target.dataset.index; i++ )getcell(i).classList.add('active')
} else if( range[0].dataset.index == e.target.dataset.index ){
e.target.classList.add('active')
} else {
for( let i=range[0].dataset.index; i > e.target.dataset.index; i-- )getcell(i).classList.add('active')
}
range=[];
}
};
/* assign an integer index to each cell within parent */
cells.forEach( ( cell, index )=>{
cell.dataset.index = index + 1;
});
grid.addEventListener( 'click', clickhandler );
});
:root{
--rows:2;
--cols:3;
--size:50px;
}
#grid {
display:grid;
grid-template-columns:repeat(var(--cols),var(--size));
grid-template-rows:repeat(var(--rows),var(--size));
width:calc(var(--size) * var(--cols));
}
.cell {
display: flex;
flex:1;
justify-content: center;
align-items: center;
border: solid 1px #ccc;
margin:1px;
cursor:pointer;
}
.active {
background-color: #80aaff;
}
<div id="grid">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell">6</div>
</div>