update template y una actividad
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
# Documentación de CourseNav.js
|
||||
|
||||
**Versión:** 1.1.5
|
||||
**Autor:** Salvador Martínez Gaytán
|
||||
**Licencia:** Comercial Propietaria
|
||||
|
||||
---
|
||||
|
||||
## Descripción
|
||||
|
||||
**CourseNav.js** es una librería en Vanilla JS para gestionar:
|
||||
|
||||
- Carga dinámica de contenido (HTML + scripts)
|
||||
- Navegación “prev/next” con bloqueo hasta completar cada slide
|
||||
- Integración con SCORM (pipwerks wrapper)
|
||||
- Control de audio avanzado (Howler.js)
|
||||
- Diálogos de inicio/retomar con SweetAlert2
|
||||
- Barra de progreso y eventos custom
|
||||
|
||||
No depende de jQuery, Swiper ni Bootstrap, y funciona incluso con CSP/CORS restrictivos.
|
||||
|
||||
---
|
||||
|
||||
## Prerrequisitos
|
||||
|
||||
Antes de `coursenav.js` debes incluir en tu HTML:
|
||||
|
||||
```html
|
||||
<script src="path/to/pipwerks-scorm.js"></script>
|
||||
<script src="path/to/howler.core.min.js"></script>
|
||||
<script src="path/to/sweetalert2.all.min.js"></script>
|
||||
<script src="path/to/coursenav.js"></script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Estructura del DOM requerida
|
||||
|
||||
```html
|
||||
<div id="main-content"></div>
|
||||
<div id="loader-course" style="display:none"></div>
|
||||
<button id="prev-btn">Prev</button>
|
||||
<button id="next-btn">Next</button>
|
||||
<div id="progress-bar"></div>
|
||||
|
||||
<button id="audio-control"></button>
|
||||
<i id="audio-icon"></i>
|
||||
<svg><circle id="progress-circle" r="50"></circle></svg>
|
||||
```
|
||||
|
||||
> Si cambias los IDs, ajusta las llamadas a `document.getElementById(...)` en el código.
|
||||
|
||||
---
|
||||
|
||||
## Inicialización automática
|
||||
|
||||
Al cargarse el DOM, CourseNav:
|
||||
|
||||
1. Inicializa SCORM o sessionStorage
|
||||
2. Carga `config.json` mediante XHR con cookies y cabecera `X-Requested-With`
|
||||
3. Construye el array `courseData.contentArray`
|
||||
4. Muestra diálogo “Retomar / Comenzar de nuevo” o arranca el curso
|
||||
5. Carga el primer slide e instala la navegación
|
||||
|
||||
---
|
||||
|
||||
## API pública
|
||||
|
||||
```js
|
||||
const CN = window.CourseNav;
|
||||
```
|
||||
|
||||
### Control de Audio
|
||||
|
||||
- `CN.audioController`
|
||||
- `loadAudio(url)`
|
||||
- `playAudio()`, `pauseAudio()`, `stopAudio()`
|
||||
- `toggleAudio()`, `toggleMute()`
|
||||
- `CN.createSound(audioUrl)` → retorna `ExtendedHowl`
|
||||
- `CN.soundClick()` → reproduce sonido de clic
|
||||
- `CN.isDebug()` → `true` si debug activo
|
||||
|
||||
### Navegación de Slides
|
||||
|
||||
- `CN.nextSlide()`, `CN.prevSlide()`
|
||||
- `CN.gotoSlide(index)` → salta a slide validado
|
||||
- `CN.isVisited()` → `true` si slide actual ya visitado
|
||||
- `CN.isCompletedSlideIndex(idx)` → `visited` de slide `idx`
|
||||
- `CN.getCurrentSlide()` → `{ title, content, audio, visited }`
|
||||
- `CN.setSlideVisited([state])` → marca visitado + dispara evento
|
||||
- `CN.markSlidesAsVisited(indicesArray)`
|
||||
- `CN.updateProgressBar()` → refresca `#progress-bar`
|
||||
|
||||
### SCORM / Progreso
|
||||
|
||||
- `CN.getStudentName()`
|
||||
- `CN.getLessonLocation()`, `CN.setLessonLocation(loc)`
|
||||
- `CN.getLessonStatus()`, `CN.setLessonStatus(status)`
|
||||
- `CN.getScore()`, `CN.setScore(score)`
|
||||
- `CN.getSuspendData()`, `CN.setSuspendData(data)`
|
||||
- `CN.getScormData(key)`, `CN.setScormData(key,value)`
|
||||
- `CN.save()` → guarda en SCORM o sessionStorage
|
||||
- `CN.completeLesson()` → marca estado SCORM “completed”
|
||||
|
||||
### Utilitarios
|
||||
|
||||
- `CN.resetCourse()` → reinicia todo el progreso
|
||||
- `CN.reload()` → recarga slide actual
|
||||
|
||||
---
|
||||
|
||||
## Eventos personalizados
|
||||
|
||||
```js
|
||||
document.body.addEventListener("slideChange", e => {
|
||||
console.log("Slide cambiado:", e.detail.slideIndex);
|
||||
});
|
||||
|
||||
document.body.addEventListener("slideCompleted", e => {
|
||||
console.log("Slide completado:", e.detail.slideIndex);
|
||||
});
|
||||
```
|
||||
|
||||
> `e.detail` contiene `{ message, slideIndex, totalSlides, slide }`.
|
||||
|
||||
---
|
||||
|
||||
## Ejemplos de uso
|
||||
|
||||
### Saltar a un slide
|
||||
|
||||
```js
|
||||
CourseNav.gotoSlide(4); // va al slide índice 4
|
||||
```
|
||||
|
||||
### Control de audio desde UI
|
||||
|
||||
```html
|
||||
<button id="audio-control">🔊</button>
|
||||
<script>
|
||||
document.getElementById("audio-control")
|
||||
.addEventListener("click", () => CourseNav.audioController.toggleMute());
|
||||
</script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notas técnicas
|
||||
|
||||
- **XHR** en `loadConfig()` para sortear CSP/CORS de SuccessFactors.
|
||||
- **executeInjectedScripts()** re-ejecuta `<script>` externos e inline tras `innerHTML`.
|
||||
- **ExtendedHowl** incluye evento `onTimeUpdate` cada 250 ms.
|
||||
- No hay dependencias externas (jQuery/Swiper/Bootstrap).
|
||||
Reference in New Issue
Block a user