Agregar evento onlick via javascript

Iniciado por SrTrp, 30 Abril 2020, 22:31 PM

0 Miembros y 1 Visitante están viendo este tema.

SrTrp

Quiero agregar el evento onclick con una funcion que envie parametro, pero no me crea el evento en el boton que estoy creando con js.
Código (javascript) [Seleccionar]

var txt= document.createTextNode(this.niveles[cclevels]);
      var btnlevel = document.createElement("button");
      btnlevel.appendChild(txt);
      btnlevel.onclick = empezar(txt);


solo me crea el button con el texto pero sin evento.

EdePC

Saludos,

- El evento onclick necesita una función tal cual, NO el resultado de una función, al poner = empezar(txt) estás diciendo que será igual al resultado de llamar a la función empezar con el parámetro txt

-- Claro que podrías darle el resultado de una función si es que dicha función devuelve una función propiamente dicha, este método clásico que suele abusarse en javascript :laugh:

(puedes probar este código copiándolo y pegándolo en la consola de tu navegador)
Código (javascript) [Seleccionar]
var txt = document.createTextNode('Hola mundo!')
var btnlevel = document.createElement('button')
btnlevel.appendChild(txt)
btnlevel.onclick = empezar(txt)
function empezar(t) {
  return function(){ console.log(t) }
}
document.body.appendChild(btnlevel)


-- Ah! y puedes ver que en realidad tiene el evento dándole click al botón que aparacerá al final de Body o consultándolo manualmente mediante:

Código (javascript) [Seleccionar]
btnlevel.onclick

-- O para ejecutar el evento desde la consola:

Código (javascript) [Seleccionar]
btnlevel.onclick()

----

Otra forma es usando .bind, con esto cambias los parámetros por defecto del evento y los sobre-escribes, para tu ejemplo:

Código (javascript) [Seleccionar]
var txt = document.createTextNode('Hola mundo!')
var btnlevel = document.createElement('button')
btnlevel.appendChild(txt)
btnlevel.onclick = empezar.bind(null,txt)
function empezar(t){ console.log(t) }
document.body.appendChild(btnlevel)


- Referencia: https://developer.mozilla.org/es/docs/Web/javascript/Referencia/Objetos_globales/Function/bind

SrTrp

Muchas gracias ya lo probe y funciono ;-) en cambio también estuve indagando y encontré también esta solución no se cual es mas factible, la función empezar es una función global, o viendolo bien es casi lo mismo pero no se cuan es mas factible..
Código (javascript) [Seleccionar]


var txt= document.createTextNode(this.niveles[cclevels]);
      var btnlevel = document.createElement("button");
      btnlevel.appendChild(textoCelda);
      btnlevel.id = this.niveles[cclevels]
      btnlevel.onclick = function() {
        empezar(this.id);
      };

[u]nsigned

Es lo mismo, solo que en lugar de llamar a una funcion previamente definida, como en el ejemplo de EdePC, en tu caso simplemente estas pasando al vuelo una función anonima. Esta segunda manera es preferible salvo que tengas que usar esa misma funcion en otro lado, en ese caso si te conviene crear una funcion previamente y luego invocarla para no repetir codigo....es la filosofia DRY = Dont Repeat Yourself

PD: espero que sea solo por practica o fines didacticos, porque en el mundo real nadie usa js asi a tan bajo nivel, para eso estan los frameworks frontend, como Vue, React, Angular o Svelte. Si nunca usaste uno y te interesa dar el siguiente paso, te recomiendo empezar por Vue.

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!

@XSStringManolo

#4
Es mejor usar addEventListener. Te permite elegir como manejar la dispersión del evento y al contrario que onclick puedes adjuntar un evento a cualquier elemento del DOM. addEventListener también te permite añadir múltiples eventos iguales en un bucle o en una llamada recursiva utilizando la sintaxis de la función anónima flecha para definir el callback en lugar de una función anónima clásica. En caso de que usases la función anónima clásica, se descartarán totalmente los eventos añadidos a posteriori por considerar que ya se añadieron.
A parte que, si volvieses a asignarle al evento onclick una función, sobrescribirías el evento anterior. Ej:
Código (javascript) [Seleccionar]
btnlevel.onclick=function(){alert(1)};
btnlevel.onclick=function(){alert(2)};


Se imprime solo el alert(2) porque sobrescribes/reasignas el método onclick del botón.


Código (javascript) [Seleccionar]
btnlevel.onclick=function(){alert(1)};
btnlevel.addEventListener("click", function(){alert(2)});


Ahora en cambio se ejecutan alert(1) y alert(2) porque ya no sobrescribiste el evento onclick, si no que añadiste un nuevo evento.

Lo mejor es utilizar siempre que tengas dudas addEventListener para no sobrescribir eventos sin querer dada la naturaleza de que es sencillo que por hoisting de alguna referencia se te ejecute primero un addEventListener y después el onclick sobrescribiendo todo evento asignado al boton.
También es la opción más segura a la hora de trabajar con librerías y código de tercera y también es la forma recomenda por diversos estandares.

En caso de que forzosamente necesites pasar una función sin que se ejecute auto en el onclick sin wrapear en funciones anónimas, puedes pasarle una referencia.

Código (javascript) [Seleccionar]
function AlPulsarBoton() {
alert(1);
alert(2);
}

bttnlevel.onclick=AlPulsarBoton;



[quote author=nsigned link=topic=504431.msg2220757#msg2220757 date=1588297273]PD: espero que sea solo por practica o fines didacticos, porque en el mundo real nadie usa js asi a tan bajo nivel, para eso estan los frameworks frontend, como Vue, React, Angular o Svelte. Si nunca usaste uno y te interesa dar el siguiente paso, te recomiendo empezar por Vue.
[/quote]
Qué es javascript a bajo nivel aquí?

js bajo nivel en navegador para mi sería compilar en runtime a webassembler, crear gráficos con webgl, manejo de video en canvas, paralelismo con workers...

No sé que es tan complejo de crear un elemento, ponerle un string de id y arrancar un juego pasándole como paramátro un string xD

[u]nsigned

Cita de: @XSStringManolo en  1 Mayo 2020, 04:54 AM
Qué es javascript a bajo nivel aquí?

js bajo nivel en navegador para mi sería compilar en runtime a webassembler, crear gráficos con webgl, manejo de video en canvas, paralelismo con workers...

No sé que es tan complejo de crear un elemento, ponerle un string de id y arrancar un juego pasándole como paramátro un string xD

Me referia a JS vanilla :xD

Hacer toda una app con js vanilla seria una locura...por eso le decia lo de los frameworks/librerias de js para frontend, solo para aportarle algo mas de info....

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!

@XSStringManolo

Yo llevo 1 mes entrándole a vue.js de forma esporádica y la impresión que tengo hasta el momento es que es prácticamente un lenguaje nuevo. A mi personalmente no me gustan nada los frameworks, son muy a alto nivel para mi gusto.
Probablemente puedas aprender a programar en vue directamente sin manejar nada de javascript. Entiendo todas las ventajas que ofrece, sobre todo en enfoque comercial.

[u]nsigned

#7
Cita de: @XSStringManolo en  1 Mayo 2020, 05:11 AM
Yo llevo 1 mes entrándole a vue.js de forma esporádica y la impresión que tengo hasta el momento es que es prácticamente un lenguaje nuevo. A mi personalmente no me gustan nada los frameworks, son muy a alto nivel para mi gusto.
Probablemente puedas aprender a programar en vue directamente sin manejar nada de javascript. Entiendo todas las ventajas que ofrece, sobre todo en enfoque comercial.
A mi me encanta justamente por eso, porque ademas de funcionalidad me aporta estructura, y me evita tener que reinventar la ruda porque alguien mucha mas inteligente y sabio que yo ya se tomo las molestias de como implementar el flujo de trabajo y la arquitectura. Y a nivel productividad en solo horas puedo hacer lo que en react o angular me tomaria dias o semanas. Solo es cuestion de acostumbrarse. Ahora tambien lo estoy usando para hacer apps híbridas con Quasar Framework, me permite codear una sola vez y desplegar mi app en todas las plataformas: web movil y desktop, desktop con electron y aplicaciones híbridas de moviles con cordova. Hago todo con vue, no importa lo que el cliente necesite, a mi me da igual jajaja

Angular no me gusta porque no me gusta typescript y porque necesitas el triple o mas de codigo y tiempo para lograr lo mismo, y como no trabajo en equipo, desarollo solo, no necesito de todas las ventajas que aporta con ts. Tiene todas las desventajas que le ves a Vue pero multiplicado por 10 xD

Te he leido aca en el foro y se ve que la tenes re clara en js vanilla, yo creo que lo mejor para vos seria React que es solo una libreria, no te impone ninguna estructura ni arquitectura de software. Tambien esta Svelte que tiene la misma filosofia, pero aun esta muy verde y le faltan muchisimas cosas en mi opinion, auqnue no le he dedicado mas que algunas lecturas esporadicas. Yo te diria que lo que mas se adaptaria a vos seria React, lo unico nuevo con respecto a js vanilla es la sintaxis de JSX pero eso lo dominas en una hora como mucho...

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!

@XSStringManolo

Tal y como me vendes react te lo compro!
Me gustaría masterizar vanilla primero, tiene muchísima API que aún no toqué casi nada o nada, como la de de audio, funciones en smartphones como la de vibrar... También estaba dando prioridad a webassembler porque se me empiezan a quedar los programas muy cortos de rendimiento. El DOM va mal mal a poco que haces. Incluso con un simple requestAnimationFrame escribiendo en un textarea letras con colores, a los 200 caracteres ya me caen los frames a la mitad. No puedo escribir en el DOM archivos de pocos megas... Me limita bastante en mis proyectos.

[u]nsigned

#9
Justamente por eso React y Vue usan un virtual dom, ademas de programar de forma reactiva y no imperativa como  se hacia en jQuery o js vanilla y terminas en un callback hell, aunque claro que en esa epoca aun no existian async/await ni las Promesas nativas. Pero una vez que probas la programacion de componentes y la logica reactiva en lugar de imperativa no hay vuelta atras, es como pasar de hacer un backend en PERL a node o php.

Si no te gusta limitarte o adaptarte a la estructura de un framework proba react, te va a volar la cabeza, ademas te va a abrir la puerta a las aplicaciones moviles NATIVAS (no hibridas) con react native, cosa que vue aun no tiene. Si es que no usas java y android sdk. Y hoy por hoy el negocio va por ese lado.

React es solo un core minimo que implementa reactividad y un dom virtual y cuando se hace un cambio en el dom solo se vuelve a renderizar lo que ha cambiado en lugar de volver a renderizar todo el dom como hace js vanilla.

Para cada cosa como manejo de estado centralizado o manejo de rutas, si bien tenes una opcion principal, react te da la libertad de usar lo que a vos mas te guste, y es js puro con jsx que no es mas que meter html dentro de js.
Y como es progresivo, podes ir aprendiendolo paralelamente a las apis nativas de js y el dom.

Yo ya me acostumbre tanto a vue y tengo tanto vuelo con el que no lo cambio por nada, pero si no existiese me iria sin dudarlo a react.

Si ya has usado webpack con babel y ES6 (7,8) solo te quedaria aprender lo de JSX para tener una base solida, de ahi en mas seria aprender el patron REDUX y cosas asi, pero siempre en js porque hasta el mismo JSX es opcional en React.
https://es.reactjs.org/docs/introducing-jsx.html

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!