-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
142 lines (115 loc) · 5.19 KB
/
script.js
File metadata and controls
142 lines (115 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* ==========================================================
PORTAFOLIO - Carolina Hernandez
Archivo de interactividad.
Este archivo controla:
- Los tags de expertise (clic para ver descripcion)
- El menu hamburguesa en moviles
- La sombra de la barra al hacer scroll
- El link activo en la navegacion segun la seccion visible
========================================================== */
document.addEventListener('DOMContentLoaded', () => {
// --- Tags de expertise ---
// Al hacer clic en un tag, se muestra su descripcion debajo
const skillTags = document.querySelectorAll('.skill-tag');
const skillDescs = document.querySelectorAll('.skill-desc');
skillTags.forEach(tag => {
tag.addEventListener('click', () => {
const skillId = tag.dataset.skill;
const desc = document.getElementById(`desc-${skillId}`);
// Si el tag ya esta activo, se desactiva (toggle)
if (tag.classList.contains('active')) {
tag.classList.remove('active');
desc.classList.remove('active');
return;
}
// Se desactivan todos los demas
skillTags.forEach(t => t.classList.remove('active'));
skillDescs.forEach(d => d.classList.remove('active'));
// Se activa el seleccionado
tag.classList.add('active');
desc.classList.add('active');
});
});
// --- Sombra en la barra de navegacion al hacer scroll ---
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', () => {
if (window.scrollY > 10) {
navbar.classList.add('scrolled');
} else {
navbar.classList.remove('scrolled');
}
});
// --- Link activo segun la seccion visible ---
// Resalta el link de la seccion que se esta viendo
const sections = document.querySelectorAll('section[id]');
const navItems = document.querySelectorAll('.nav-links a');
const observerOptions = {
rootMargin: '-100px 0px -60% 0px',
threshold: 0
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.getAttribute('id');
navItems.forEach(item => {
item.classList.remove('active');
if (item.getAttribute('href') === `#${id}`) {
item.classList.add('active');
}
});
}
});
}, observerOptions);
sections.forEach(section => observer.observe(section));
// --- Fade-in al scroll ---
// Las secciones con clase .fade-in aparecen suavemente al entrar en el viewport
const fadeElements = document.querySelectorAll('.fade-in');
const fadeObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.1 });
fadeElements.forEach(el => fadeObserver.observe(el));
// --- Cambio de idioma (espanol / ingles) ---
// Se guarda la preferencia en localStorage para que persista entre visitas
const langToggle = document.getElementById('langToggle');
// Limpieza unica: si el valor guardado era del default anterior, se borra para usar el nuevo default (ingles)
if (!localStorage.getItem('lang_v2')) {
localStorage.removeItem('lang');
localStorage.setItem('lang_v2', 'migrado');
}
let idiomaActual = localStorage.getItem('lang') || 'en';
// Se aplica el idioma guardado al cargar la pagina
aplicarIdioma(idiomaActual);
langToggle.addEventListener('click', () => {
// Alterna entre espanol e ingles
idiomaActual = idiomaActual === 'es' ? 'en' : 'es';
localStorage.setItem('lang', idiomaActual);
aplicarIdioma(idiomaActual);
});
// Recorre todos los elementos con data-i18n y reemplaza su texto
function aplicarIdioma(lang) {
// Actualiza el boton para mostrar el idioma al que se puede cambiar
langToggle.textContent = lang === 'es' ? 'EN' : 'ES';
// Cambia el atributo lang del HTML (importante para accesibilidad y SEO)
document.documentElement.lang = lang;
// Recorre cada elemento marcado con data-i18n
document.querySelectorAll('[data-i18n]').forEach(el => {
const clave = el.getAttribute('data-i18n');
if (traducciones[clave] && traducciones[clave][lang]) {
el.textContent = traducciones[clave][lang];
}
});
// Actualiza el titulo de la pagina (pestaña del navegador)
if (traducciones['page-title'] && traducciones['page-title'][lang]) {
document.title = traducciones['page-title'][lang];
}
// Actualiza la meta description (para SEO)
const metaDesc = document.querySelector('meta[name="description"]');
if (metaDesc && traducciones['meta-description'] && traducciones['meta-description'][lang]) {
metaDesc.setAttribute('content', traducciones['meta-description'][lang]);
}
}
});