Checklist em Cartela
Cartela onde uma linha ou coluna inteira reúne os termos realmente trabalhados num vídeo, áudio ou texto de referência — o resto são distratores. O aprendiz marca os termos que reconhece e verifica se identificou a linha ou coluna certa.
Experimente
Cartela de Palavras
Marque todas as frutas da cartela. Se marcar exatamente as cinco — e nenhuma outra — elas completam uma linha inteira.
Marcados: 0
Código-fonte
Dados de exemplo
Cartela 5×5 com uma linha inteira de gabarito. Os distratores ficam embaralhados entre as outras linhas de propósito: se cada linha fosse uma categoria, a cartela viraria uma tabela e a busca deixaria de ter graça.
| 1 |
<?php
|
| 2 |
$instrucao = 'Marque os meios de transporte. Se marcar exatamente os cinco — e nenhum outro — eles completam uma linha inteira.';
|
| 3 |
$cartela = [
|
| 4 |
[
|
| 5 |
['termo' => 'Martelo', 'correta' => false],
|
| 6 |
['termo' => 'Médico', 'correta' => false],
|
| 7 |
['termo' => 'Cadeira', 'correta' => false],
|
| 8 |
['termo' => 'Violão', 'correta' => false],
|
| 9 |
['termo' => 'Arroz', 'correta' => false],
|
| 10 |
],
|
| 11 |
[
|
| 12 |
['termo' => 'Professor', 'correta' => false],
|
| 13 |
['termo' => 'Mesa', 'correta' => false],
|
| 14 |
['termo' => 'Feijão', 'correta' => false],
|
| 15 |
['termo' => 'Flauta', 'correta' => false],
|
| 16 |
['termo' => 'Serrote', 'correta' => false],
|
| 17 |
],
|
| 18 |
[
|
| 19 |
['termo' => 'Ônibus', 'correta' => true],
|
| 20 |
['termo' => 'Bicicleta', 'correta' => true],
|
| 21 |
['termo' => 'Avião', 'correta' => true],
|
| 22 |
['termo' => 'Trem', 'correta' => true],
|
| 23 |
['termo' => 'Barco', 'correta' => true],
|
| 24 |
],
|
| 25 |
[
|
| 26 |
['termo' => 'Sofá', 'correta' => false],
|
| 27 |
['termo' => 'Pedreiro', 'correta' => false],
|
| 28 |
['termo' => 'Tambor', 'correta' => false],
|
| 29 |
['termo' => 'Alface', 'correta' => false],
|
| 30 |
['termo' => 'Alicate', 'correta' => false],
|
| 31 |
],
|
| 32 |
[
|
| 33 |
['termo' => 'Piano', 'correta' => false],
|
| 34 |
['termo' => 'Estante', 'correta' => false],
|
| 35 |
['termo' => 'Padeiro', 'correta' => false],
|
| 36 |
['termo' => 'Tomate', 'correta' => false],
|
| 37 |
['termo' => 'Chave', 'correta' => false],
|
| 38 |
],
|
| 39 |
];
|
| 40 |
?>
|
| 41 |
$cols = count($cartela[0]);
|
| 42 |
?>
|
| 43 |
|
Cartela
Cada célula guarda o gabarito (data-correta) e o que foi marcado (data-marcada); o número de colunas vem do tamanho da primeira linha, então a grade nunca sai de sincronia com o conteúdo.
| 1 |
<div class="questao" data-tipo="checklist-cartela" data-cols="<?= $cols ?>">
|
| 2 |
|
| 3 |
<p class="questao-instrucao"><?= htmlspecialchars($instrucao) ?></p>
|
| 4 |
|
| 5 |
<div class="cartela-grade" style="grid-template-columns: repeat(<?= $cols ?>, 1fr);">
|
| 6 |
<?php foreach ($cartela as $linha): foreach ($linha as $celula): ?>
|
| 7 |
<button type="button"
|
| 8 |
class="cartela-celula"
|
| 9 |
data-correta="<?= $celula['correta'] ? 'true' : 'false' ?>"
|
| 10 |
data-marcada="false">
|
| 11 |
<?= htmlspecialchars($celula['termo']) ?>
|
| 12 |
</button>
|
| 13 |
<?php endforeach; endforeach; ?>
|
| 14 |
</div>
|
| 15 |
|
Ações
Verificar, painel de resultado e reiniciar — os dois últimos nascem ocultos.
| 1 |
<button type="button" class="cartela-verificar">Verificar</button>
|
| 2 |
|
| 3 |
<div class="cartela-painel" hidden>
|
| 4 |
<p class="cartela-painel-mensagem"></p>
|
| 5 |
</div>
|
| 6 |
|
| 7 |
<button type="button" class="cartela-reset" hidden>Tentar novamente</button>
|
| 8 |
|
| 9 |
</div>
|
Instrução
Texto de introdução acima da cartela.
| 1 |
.questao-instrucao {
|
| 2 |
margin: 0 0 16px;
|
| 3 |
font-size: 15px;
|
| 4 |
font-weight: 500;
|
| 5 |
line-height: 1.6;
|
| 6 |
}
|
Grade da cartela
Colunas dinâmicas via style inline — o número de termos por linha varia por atividade.
| 1 |
.cartela-grade {
|
| 2 |
display: grid;
|
| 3 |
gap: 6px;
|
| 4 |
margin-bottom: 16px;
|
| 5 |
}
|
Células
Botão quadrado de texto centralizado.
| 1 |
.cartela-celula {
|
| 2 |
min-height: 44px;
|
| 3 |
padding: 8px 4px;
|
| 4 |
border: 1px solid #cbd5e1;
|
| 5 |
border-radius: 8px;
|
| 6 |
background: #f8fafc;
|
| 7 |
font: inherit;
|
| 8 |
font-size: 12px;
|
| 9 |
font-weight: 600;
|
| 10 |
text-align: center;
|
| 11 |
cursor: pointer;
|
| 12 |
}
|
| 13 |
|
| 14 |
.cartela-celula:disabled {
|
| 15 |
cursor: not-allowed;
|
| 16 |
}
|
Estado selecionado
Realce neutro enquanto aguarda a verificação — verde/vermelho antes da hora entregaria a resposta.
| 1 |
.cartela-celula.selecionada {
|
| 2 |
outline: 2px solid #6366f1;
|
| 3 |
background: rgba(99, 102, 241, 0.1);
|
| 4 |
}
|
Resultado da verificação
Verde para acerto, vermelho para marcação errada, âmbar para termo do gabarito esquecido.
| 1 |
.cartela-celula.acerto { border-color: #22c55e; background: rgba(34, 197, 94, 0.1); }
|
| 2 |
.cartela-celula.erro { border-color: #ef4444; background: rgba(239, 68, 68, 0.1); }
|
| 3 |
.cartela-celula.omissao { border-color: #f59e0b; background: rgba(245, 158, 11, 0.1); }
|
Ações
Botões de largura total, um de cada vez na tela.
| 1 |
.cartela-verificar,
|
| 2 |
.cartela-reset {
|
| 3 |
display: block;
|
| 4 |
width: 100%;
|
| 5 |
padding: 12px 16px;
|
| 6 |
border: none;
|
| 7 |
border-radius: 10px;
|
| 8 |
font: inherit;
|
| 9 |
font-weight: 600;
|
| 10 |
cursor: pointer;
|
| 11 |
}
|
| 12 |
|
| 13 |
.cartela-verificar {
|
| 14 |
background: #4f46e5;
|
| 15 |
color: #fff;
|
| 16 |
}
|
| 17 |
|
| 18 |
.cartela-reset {
|
| 19 |
background: #e5e7eb;
|
| 20 |
color: #1f2937;
|
| 21 |
}
|
Estado oculto
O atributo hidden nativo tem a mesma especificidade da regra de exibição acima — sem isto, "Tentar novamente" apareceria antes de verificar.
| 1 |
.cartela-verificar[hidden],
|
| 2 |
.cartela-reset[hidden] {
|
| 3 |
display: none;
|
| 4 |
}
|
Painel de resultado
Caixa de destaque com a mensagem final, abaixo da cartela.
| 1 |
.cartela-painel {
|
| 2 |
margin: 16px 0;
|
| 3 |
padding: 16px;
|
| 4 |
border-radius: 12px;
|
| 5 |
background: #1e3a8a;
|
| 6 |
color: #dbeafe;
|
| 7 |
font-weight: 600;
|
| 8 |
}
|
Encontrar os elementos da cartela
Localiza as células, o número de colunas e as ações.
| 1 |
document.addEventListener('DOMContentLoaded', function () {
|
| 2 |
document.querySelectorAll('.questao[data-tipo="checklist-cartela"]').forEach(function (questao) {
|
| 3 |
var cols = parseInt(questao.dataset.cols, 10) || 5;
|
| 4 |
var celulas = questao.querySelectorAll('.cartela-celula');
|
| 5 |
var verificar = questao.querySelector('.cartela-verificar');
|
| 6 |
var painel = questao.querySelector('.cartela-painel');
|
| 7 |
var reset = questao.querySelector('.cartela-reset');
|
Achar uma linha ou coluna completa do gabarito
Só conta como sucesso se toda célula de uma linha/coluna for gabarito E estiver marcada — acertar itens do gabarito espalhados pela cartela não é suficiente.
| 1 |
function linhaOuColunaCompleta() {
|
| 2 |
var total = celulas.length;
|
| 3 |
var rows = total / cols;
|
| 4 |
var estado = Array.prototype.map.call(celulas, function (c) {
|
| 5 |
return { correta: c.dataset.correta === 'true', marcada: c.dataset.marcada === 'true' };
|
| 6 |
});
|
| 7 |
|
| 8 |
for (var r = 0; r < rows; r++) {
|
| 9 |
var linha = true;
|
| 10 |
for (var c = 0; c < cols; c++) {
|
| 11 |
var e = estado[r * cols + c];
|
| 12 |
if (!e.correta || !e.marcada) { linha = false; break; }
|
| 13 |
}
|
| 14 |
if (linha) return true;
|
| 15 |
}
|
| 16 |
for (var c2 = 0; c2 < cols; c2++) {
|
| 17 |
var coluna = true;
|
| 18 |
for (var r2 = 0; r2 < rows; r2++) {
|
| 19 |
var e2 = estado[r2 * cols + c2];
|
| 20 |
if (!e2.correta || !e2.marcada) { coluna = false; break; }
|
| 21 |
}
|
| 22 |
if (coluna) return true;
|
| 23 |
}
|
| 24 |
return false;
|
| 25 |
}
|
Marcar uma célula
Alterna livremente antes de verificar — nada é corrigido no clique, só o realce muda.
| 1 |
celulas.forEach(function (celula) {
|
| 2 |
celula.addEventListener('click', function () {
|
| 3 |
if (celula.disabled) return;
|
| 4 |
var marcada = celula.dataset.marcada === 'true';
|
| 5 |
celula.dataset.marcada = marcada ? 'false' : 'true';
|
| 6 |
celula.classList.toggle('selecionada', !marcada);
|
| 7 |
});
|
| 8 |
});
|
Verificar
Classifica cada célula em acerto, erro ou omissão, e só celebra quando uma linha ou coluna inteira do gabarito foi marcada certa.
| 1 |
verificar.addEventListener('click', function () {
|
| 2 |
var acertos = 0, erros = 0, omissoes = 0;
|
| 3 |
celulas.forEach(function (celula) {
|
| 4 |
var correta = celula.dataset.correta === 'true';
|
| 5 |
var marcada = celula.dataset.marcada === 'true';
|
| 6 |
celula.disabled = true;
|
| 7 |
celula.classList.remove('selecionada');
|
| 8 |
if (correta && marcada) { acertos++; celula.classList.add('acerto'); }
|
| 9 |
else if (!correta && marcada) { erros++; celula.classList.add('erro'); }
|
| 10 |
else if (correta && !marcada) { omissoes++; celula.classList.add('omissao'); }
|
| 11 |
});
|
| 12 |
|
| 13 |
var mensagem = painel.querySelector('.cartela-painel-mensagem');
|
| 14 |
if (linhaOuColunaCompleta()) {
|
| 15 |
mensagem.textContent = 'Certo! Você reconheceu a linha certa.';
|
| 16 |
} else {
|
| 17 |
var partes = [acertos + ' corretos'];
|
| 18 |
if (erros) partes.push(erros + ' incorretos');
|
| 19 |
if (omissoes) partes.push(omissoes + ' esquecidos');
|
| 20 |
mensagem.textContent = partes.join(' · ') + '. Nenhuma linha ou coluna foi completada certa.';
|
| 21 |
}
|
| 22 |
painel.hidden = false;
|
| 23 |
|
| 24 |
verificar.hidden = true;
|
| 25 |
reset.hidden = false;
|
| 26 |
});
|
Reiniciar
Limpa marcação e classes de resultado, reabilita as células e devolve o botão de verificar.
| 1 |
reset.addEventListener('click', function () {
|
| 2 |
celulas.forEach(function (celula) {
|
| 3 |
celula.disabled = false;
|
| 4 |
celula.dataset.marcada = 'false';
|
| 5 |
celula.classList.remove('selecionada', 'acerto', 'erro', 'omissao');
|
| 6 |
});
|
| 7 |
painel.hidden = true;
|
| 8 |
verificar.hidden = false;
|
| 9 |
reset.hidden = true;
|
| 10 |
});
|