Preencher Lacunas (Menu Suspenso)
Apresenta um texto com lacunas que o aprendiz completa escolhendo numa lista de opções, em vez de digitar. Avalia reconhecimento do termo correto e discriminação entre alternativas próximas.
Experimente
Complete o texto sobre o modelo ADDIE preenchendo todas as lacunas:
Código-fonte
Dados de exemplo
Define as frases, as lacunas e a lista de opções compartilhada.
| 1 |
<?php
|
| 2 |
// Todas as lacunas oferecem a mesma lista: assim a escolha depende de ler a
|
| 3 |
// frase, e não de eliminar o que já foi usado.
|
| 4 |
$opcoes = ['Análise', 'Design', 'Desenvolvimento', 'Implementação', 'Avaliação'];
|
| 5 |
|
| 6 |
$linhas = [
|
| 7 |
[
|
| 8 |
['tipo' => 'texto', 'valor' => 'O primeiro passo do ADDIE é a '],
|
| 9 |
['tipo' => 'lacuna', 'resposta' => 'Análise'],
|
| 10 |
['tipo' => 'texto', 'valor' => ', que identifica as necessidades.'],
|
| 11 |
],
|
| 12 |
[
|
| 13 |
['tipo' => 'texto', 'valor' => 'Em seguida, o '],
|
| 14 |
['tipo' => 'lacuna', 'resposta' => 'Design'],
|
| 15 |
['tipo' => 'texto', 'valor' => ' define a estrutura do curso.'],
|
| 16 |
],
|
| 17 |
];
|
| 18 |
?>
|
Texto com as listas no meio
Intercala os trechos de frase com um select por lacuna.
| 1 |
<div class="questao" data-tipo="lacunas-menu-suspenso">
|
| 2 |
|
| 3 |
<p class="questao-instrucao">Complete o texto escolhendo o termo de cada lacuna:</p>
|
| 4 |
|
| 5 |
<?php foreach ($linhas as $linha): ?>
|
| 6 |
<p class="questao-linha">
|
| 7 |
<?php foreach ($linha as $seg): ?>
|
| 8 |
<?php if ($seg['tipo'] === 'texto'): ?>
|
| 9 |
<span><?= htmlspecialchars($seg['valor']) ?></span>
|
| 10 |
<?php else: ?>
|
| 11 |
<?php
|
| 12 |
// O value viaja em minúsculas porque é ele que o JavaScript compara
|
| 13 |
// com o data-resposta. O rótulo visível mantém acento e maiúscula.
|
| 14 |
?>
|
| 15 |
<select class="lacuna-input"
|
| 16 |
data-resposta="<?= htmlspecialchars(mb_strtolower($seg['resposta'])) ?>">
|
| 17 |
<option value="">— escolha —</option>
|
| 18 |
<?php foreach ($opcoes as $opcao): ?>
|
| 19 |
<option value="<?= htmlspecialchars(mb_strtolower($opcao)) ?>">
|
| 20 |
<?= htmlspecialchars($opcao) ?>
|
| 21 |
</option>
|
| 22 |
<?php endforeach; ?>
|
| 23 |
</select>
|
| 24 |
<?php endif; ?>
|
| 25 |
<?php endforeach; ?>
|
| 26 |
</p>
|
| 27 |
<?php endforeach; ?>
|
Área de ação
Reúne verificar, resultado e reiniciar numa caixa própria.
| 1 |
<div class="questao-acoes">
|
| 2 |
<button type="button" class="questao-verificar">Verificar</button>
|
| 3 |
|
| 4 |
<div class="questao-feedback" hidden></div>
|
| 5 |
|
| 6 |
<button type="button" class="questao-reset" hidden>Tentar novamente</button>
|
| 7 |
</div>
|
| 8 |
|
| 9 |
</div>
|
Lacuna
Deixa o select parecer parte da frase, não um formulário.
| 1 |
.lacuna-input {
|
| 2 |
border: none;
|
| 3 |
border-bottom: 2px solid #6366f1;
|
| 4 |
border-radius: 4px 4px 0 0;
|
| 5 |
background: #f1f5f9;
|
| 6 |
color: #4f46e5;
|
| 7 |
font: inherit;
|
| 8 |
padding: 2px 4px;
|
| 9 |
cursor: pointer;
|
| 10 |
}
|
Lacuna certa e errada
Colore a escolha depois de verificar, sem trocar o que foi escolhido.
| 1 |
.lacuna-input.acerto {
|
| 2 |
border-bottom-color: #16a34a;
|
| 3 |
color: #15803d;
|
| 4 |
}
|
| 5 |
|
| 6 |
.lacuna-input.erro {
|
| 7 |
border-bottom-color: #dc2626;
|
| 8 |
color: #b91c1c;
|
| 9 |
}
|
Lacuna bloqueada
Impede que o navegador desbote a resposta já avaliada.
| 1 |
.lacuna-input:disabled {
|
| 2 |
cursor: not-allowed;
|
| 3 |
opacity: 1;
|
| 4 |
-webkit-text-fill-color: currentColor;
|
| 5 |
}
|
Área de ação
Separa os controles do texto da atividade.
| 1 |
.questao-acoes {
|
| 2 |
display: flex;
|
| 3 |
flex-direction: column;
|
| 4 |
gap: 12px;
|
| 5 |
margin-top: 20px;
|
| 6 |
padding: 16px;
|
| 7 |
border: 1px solid #cbd5e1;
|
| 8 |
border-radius: 12px;
|
| 9 |
}
|
| 10 |
|
| 11 |
.questao-verificar,
|
| 12 |
.questao-reset {
|
| 13 |
width: 100%;
|
| 14 |
padding: 12px 16px;
|
| 15 |
border: none;
|
| 16 |
border-radius: 10px;
|
| 17 |
font: inherit;
|
| 18 |
font-weight: 600;
|
| 19 |
cursor: pointer;
|
| 20 |
}
|
| 21 |
|
| 22 |
.questao-verificar { background: #4f46e5; color: #fff; }
|
| 23 |
.questao-reset { background: #e5e7eb; color: #1f2937; }
|
Resultado
Caixa de feedback com uma cor por estado.
| 1 |
.questao-feedback {
|
| 2 |
padding: 12px 16px;
|
| 3 |
border-radius: 10px;
|
| 4 |
line-height: 1.6;
|
| 5 |
}
|
| 6 |
|
| 7 |
.questao-feedback.acerto { background: #dcfce7; color: #14532d; }
|
| 8 |
.questao-feedback.parcial { background: #fef3c7; color: #78350f; }
|
Encontrar os elementos da questão
Localiza as lacunas, os botões e a caixa de resultado.
| 1 |
document.addEventListener('DOMContentLoaded', function () {
|
| 2 |
document.querySelectorAll('.questao[data-tipo="lacunas-menu-suspenso"]').forEach(function (questao) {
|
| 3 |
var lacunas = questao.querySelectorAll('.lacuna-input');
|
| 4 |
var verificar = questao.querySelector('.questao-verificar');
|
| 5 |
var feedback = questao.querySelector('.questao-feedback');
|
| 6 |
var reset = questao.querySelector('.questao-reset');
|
Ler o rótulo da resposta certa
Recupera o texto com acento e maiúscula para mostrar no resultado.
| 1 |
function rotuloCerto(lacuna) {
|
| 2 |
var esperado = lacuna.dataset.resposta;
|
| 3 |
var certa = Array.prototype.filter.call(lacuna.options, function (o) {
|
| 4 |
return o.value === esperado;
|
| 5 |
})[0];
|
| 6 |
return certa ? certa.textContent.trim() : esperado;
|
| 7 |
}
|
Verificar as escolhas
Compara cada lacuna com o gabarito e trava a atividade.
| 1 |
verificar.addEventListener('click', function () {
|
| 2 |
var acertos = 0, embranco = 0, gabarito = [];
|
| 3 |
|
| 4 |
lacunas.forEach(function (lacuna) {
|
| 5 |
if (lacuna.value === '') embranco++;
|
| 6 |
var correta = lacuna.value !== '' && lacuna.value === lacuna.dataset.resposta;
|
| 7 |
|
| 8 |
// A escolha errada continua na tela: trocar pela certa faria parecer
|
| 9 |
// que o site respondeu no lugar de quem estuda.
|
| 10 |
lacuna.classList.add(correta ? 'acerto' : 'erro');
|
| 11 |
lacuna.disabled = true;
|
| 12 |
|
| 13 |
if (correta) acertos++;
|
| 14 |
else gabarito.push(rotuloCerto(lacuna));
|
| 15 |
});
|
| 16 |
|
| 17 |
// Verificar sem escolher nada não é erro de conteúdo: avisa e devolve a
|
| 18 |
// atividade, em vez de queimar a tentativa entregando o gabarito.
|
| 19 |
if (embranco === lacunas.length) {
|
| 20 |
lacunas.forEach(function (lacuna) {
|
| 21 |
lacuna.disabled = false;
|
| 22 |
lacuna.classList.remove('acerto', 'erro');
|
| 23 |
});
|
| 24 |
feedback.className = 'questao-feedback parcial';
|
| 25 |
feedback.textContent = 'Escolha uma opção em cada lacuna antes de verificar.';
|
| 26 |
feedback.hidden = false;
|
| 27 |
return;
|
| 28 |
}
|
| 29 |
|
| 30 |
if (acertos === lacunas.length) {
|
| 31 |
feedback.className = 'questao-feedback acerto';
|
| 32 |
feedback.textContent = 'Correto! Todas as lacunas foram preenchidas corretamente.';
|
| 33 |
} else {
|
| 34 |
feedback.className = 'questao-feedback parcial';
|
| 35 |
feedback.textContent = 'Verifique as lacunas em vermelho. Esperado: ' + gabarito.join(', ') + '.';
|
| 36 |
}
|
| 37 |
feedback.hidden = false;
|
| 38 |
|
| 39 |
verificar.hidden = true;
|
| 40 |
reset.hidden = false;
|
| 41 |
});
|
Reiniciar
Devolve cada lacuna ao rótulo vazio e limpa as cores.
| 1 |
reset.addEventListener('click', function () {
|
| 2 |
lacunas.forEach(function (lacuna) {
|
| 3 |
lacuna.disabled = false;
|
| 4 |
lacuna.selectedIndex = 0;
|
| 5 |
lacuna.classList.remove('acerto', 'erro');
|
| 6 |
});
|
| 7 |
|
| 8 |
feedback.hidden = true;
|
| 9 |
reset.hidden = true;
|
| 10 |
verificar.hidden = false;
|
| 11 |
});
|