Estoy tratando de mostrar un conjunto básico y permitir que un usuario agregue elementos al conjunto. Esto es lo que tengo hasta ahora:
<head> <script> class _Set extends Set { add(...args) { for (const x of args) { this.add(x) } return this; } } const s = new Set(); const button = document.querySelector('button'); const text = document.getElementById('theText'); button.addEventListener('click', () => { let values, rawValue = document.getElementById('theValue'); if (rawValue.includes(',')) { values = rawValue.split(',').map(x => x.trim()); } else { values = [rawValue,]; } for (value of values) { s.add(value); } text.textContent = `Set(${s.size}) = ${Array.from(s)}`; }); </script> </head> <body> <input type="text" id="theText" placeholder="Enter in a value"/> <input type="button" value="submit"/> Your set now contains: <span id="theSet">{}</span> </body>Supongo que este error ocurre porque javascript intenta ejecutarse antes de que se haya procesado el dom html y esté listo para la secuencia de comandos. ¿Qué estoy haciendo mal aquí y cuál sería la forma correcta de hacer algo como lo anterior?
Debe colocar el script antes de la etiqueta del cuerpo de cierre:
<head> </head> <body> <input type="text" id="theText" placeholder="Enter in a value"/> <input type="button" value="submit"/> Your set now contains: <span id="theSet">{}</span> <script> class _Set extends Set { add(...args) { for (const x of args) { this.add(x) } return this; } } const s = new Set(); const button = document.querySelector('button'); const text = document.getElementById('theSet'); button.addEventListener('click', () => { let values, rawValue = document.getElementById('theValue'); if (rawValue.includes(',')) { values = rawValue.split(',').map(x => x.trim()); } else { values = [rawValue,]; } for (value of values) { s.add(value); } text.textContent = `Set(${s.size}) = ${Array.from(s)}`; }); </script> </body>Hay dos errores aquí.
Primero, debe colocar su secuencia de comandos al final del cuerpo; de lo contrario, intentará obtener elementos que aún no están definidos.
En segundo lugar, el retorno de document.querySelector('button') es nulo. querySelector espera un selector de CSS válido , pero el button no lo es. Podría usar input[type=button] como un selector válido en este caso.
<body> <input type="text" id="theText" placeholder="Enter in a value"/> <input class="button" type="button" value="submit"/> Your set now contains: <span id="theSet">{}</span> <script> class _Set extends Set { add(...args) { for (const x of args) { this.add(x) } return this; } } const s = new Set(); const button = document.querySelector('input[type=button]'); const text = document.getElementById('theSet'); button.addEventListener('click', () => { let values, rawValue = document.getElementById('theValue'); if (rawValue.contains(',')) { values = rawValue.split(',').map(x => x.strip()); } else { values = [rawValue,]; } for (value of values) { s.add(value); } text.textContent = `Set(${s.size}) = ${Array.from(s)}`; }); </script> </body>Hay muchas cosas aquí, pero repasémoslas, con los comentarios en línea.
<body> <input type="text" id="theText" placeholder="Enter in a value"/> <input type="button" value="submit"/> <div>Your set now contains: <span id="theSet">{}</span></div> <script> // move the script to execute within the body of the // html, after the needed nodes have loaded class _Set extends Set { add(...args) { for (const x of args) { super.add(x) } return this; } // moving the helper function to parse strings // into a static method static getArrayFromInput(text) { let arr = []; if (text.includes(',')) { arr = text.split(',').map(x => x.trim()); } else { arr = [text,]; } return arr; } } const s = new _Set(); // css selector needs to be on input[type=button] // and not input[type="button"] or button const button = document.querySelector('input[type=button]'); const text = document.getElementById('theSet'); // now we can add the event listener, // since the button node has been fetched button.addEventListener('click', () => { // get the input[type=text] Node const rawValueNode = document.getElementById('theText'); // pass the value contained in the input // to the function the get the vallues as arr const arr = _Set.getArrayFromInput(rawValueNode.value); // add the values into the set s.add(...arr); // finally, format how we want to response to look in the html text.textContent = `Set(${s.size}) = ${Array.from(s)}`; }); </script> </body>