mostrar y ocultar elementos html con javascript

publicado por: Anonymous

estoy iniciándome en javascript y tengo un problema. Quiero hacer una web de FAQs y que al pinchar en una pregunta se desplieguen las respuestas. Pero al pinchar en la pregunta me aparece este error en el log del navegador Cannot read property ‘getAttribute’ of null y no hace nada he mirado que exista la clase, que haya capturado el elemento, y no se que puedo mirar más. Adjunto código html y javascript actual. Gracias de antemano. Por cierto quiero hacerlo por delegación de eventos

_x000D_

_x000D_

(function(){_x000D_
	window.addEventListener('load', function(){_x000D_
	_x000D_
	var elementosH2 = faqs.getElementsByTagName("h2");_x000D_
	var nodoH2;_x000D_
	for(var i=0; i<elementosH2.length;i++){_x000D_
		nodoH2 = elementosH2[i];_x000D_
		nodoH2.addEventListener("click", cambiar);_x000D_
	}_x000D_
	_x000D_
	function cambiar(e) {_x000D_
			var h2 = e.target; // h2 es el nodoH2 actual_x000D_
			if (h2.getAttribute("class") == "mas") {_x000D_
				h2.setAttribute("class", "menos");_x000D_
			}_x000D_
			else {_x000D_
				h2.setAttribute("class", "mas");_x000D_
			}_x000D_
			if (h2.nextElementSibling.getAttribute("class") == "cerrado") {_x000D_
				h2.nextElementSibling.setAttribute("class", "abierto");_x000D_
			}_x000D_
			else {_x000D_
				h2.nextElementSibling.setAttribute("class", "cerrado");_x000D_
			}_x000D_
		}_x000D_
	});_x000D_
}());

_x000D_

<!doctype html>_x000D_
<html>_x000D_
_x000D_
<head>_x000D_
	<meta charset="UTF-8">_x000D_
	<title> Ejercicio FAQs</title>_x000D_
	<script src="script.js" defer></script>_x000D_
</head>_x000D_
_x000D_
<body>_x000D_
    <section id="faqs">_x000D_
        <h1>FAQs</h1>_x000D_
			<h2 class="mas"><img src="mas.jpg"/> ¿Qué es jQuery?</h2>_x000D_
			<div class="cerrado">_x000D_
				<p>_x000D_
					<img name="" src="menos.jpg"/>_x000D_
					jQuery es una librería de funciones JavaScript que puedes utilizar para desarrollar sitios web._x000D_
				</p>_x000D_
			</div>_x000D_
			<h2 class="mas"><img src="mas.jpg"/>¿Por qué es tan popular jQuery?</h2>_x000D_
			<div class="cerrado">_x000D_
				<p>_x000D_
					<img src="menos.jpg"/>Hay tres razones:_x000D_
				</p>_x000D_
				<ul>_x000D_
					<li>Es gratuito</li>_x000D_
					<li>Te permite hacer más cosas en menos tiempo</li>_x000D_
					<li>Sus funciones son compatibles con todos los navegadores</li>_x000D_
				</ul>_x000D_
			</div>_x000D_
    </section>_x000D_
</body>_x000D_
_x000D_
</html>

_x000D_

_x000D_

_x000D_

solución

Varias cosas a tener en cuenta:

1.- Como te decían en el comentario, no estás pasándole el elemento en la función. addEventListener espera una función como segundo parámetro. Puedes pasárselo como una función anónima:

nodoH2.addEventListener("click", function(){cambiar(this)});

2.- Uso de let y var: Acostúmbrate a usar let más a menudo. var crea variables globales lo que te puede dar problemas de conflicto entre variables o comportamientos no deseados. Más info aquí y aquí.

3.- Añadir el estilo de las imágenes vía CSS (no lo pongo porque no tengo las imágenes en la solución)

4.- Declarar la variable faqs: el motor de JS te la está creando con el valor del DOM “faqs” pero esto es una muy mala idea (más info)

Faltarían cosas como, por ejemplo, cambiar la imagen de los h2 al hacer click

_x000D_

_x000D_

<!doctype html>_x000D_
<html>_x000D_
<head>_x000D_
<meta charset="UTF-8">_x000D_
<title> Ejercicio FAQs</title>  _x000D_
  <style>_x000D_
  .mas{display:inline;}_x000D_
  .cerrado{display:none;}_x000D_
  </style>_x000D_
</head>_x000D_
_x000D_
<body>_x000D_
<section id="faqs">_x000D_
    <h1>FAQs</h1>_x000D_
		<h2 class="mas"><img src="https://cdn3.iconfinder.com/data/icons/fatcow/32/add.png"/> ¿Qué es jQuery?</h2>_x000D_
		<div class="cerrado">_x000D_
			<p>					_x000D_
				jQuery es una librería de funciones JavaScript que puedes utilizar para desarrollar sitios web._x000D_
			</p>_x000D_
		</div>_x000D_
		<br/>_x000D_
		<h2 class="mas"><img src="https://cdn3.iconfinder.com/data/icons/fatcow/32/add.png"/>¿Por qué es tan popular jQuery?</h2>_x000D_
		<div class="cerrado">_x000D_
			<p>_x000D_
				Hay tres razones:_x000D_
			</p>_x000D_
			<ul>_x000D_
				<li>Es gratuito</li>_x000D_
				<li>Te permite hacer más cosas en menos tiempo</li>_x000D_
				<li>Sus funciones son compatibles con todos los navegadores</li>_x000D_
			</ul>_x000D_
		</div>_x000D_
</section>_x000D_
<script>_x000D_
(function(){_x000D_
window.addEventListener('load', function(){_x000D_
_x000D_
var elementosH2 = faqs.getElementsByTagName("h2");_x000D_
var nodoH2;_x000D_
for(var i=0; i<elementosH2.length;i++){_x000D_
	nodoH2 = elementosH2[i];_x000D_
	nodoH2.addEventListener("click", function(){cambiar(this)});_x000D_
}_x000D_
_x000D_
function cambiar(e) {_x000D_
		var h2 = e; // h2 es el nodoH2 actual_x000D_
		if (h2.getAttribute("class") == "mas") {_x000D_
			h2.setAttribute("class", "menos");_x000D_
		}_x000D_
		else {_x000D_
			h2.setAttribute("class", "mas");_x000D_
		}_x000D_
		if (h2.nextElementSibling.getAttribute("class") == "cerrado") {_x000D_
			h2.nextElementSibling.setAttribute("class", "abierto");_x000D_
		}_x000D_
		else {_x000D_
			h2.nextElementSibling.setAttribute("class", "cerrado");_x000D_
		}_x000D_
	}_x000D_
});_x000D_
}());_x000D_
</script>_x000D_
</body>_x000D_
_x000D_
</html>

_x000D_

_x000D_

_x000D_

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *