En una página HTML hay un par de etiquetas de anclaje con métodos onclick(), cuyos códigos no puedo o no debo cambiar. Sin embargo, puedo agregar un nuevo archivo js o jQuery a esta página. ¿Cómo puedo agregar un detector de eventos para los eventos de clic de esas etiquetas de anclaje, que deben activarse/llamarse antes de los métodos onclick() existentes? Después de eso, se deben llamar los métodos onclick() existentes. Algo como lo siguiente.
<a href='#' class="edit" onclick='edit()'>Edit First</a> <a href='#' class="edit" onclick='edit()'>Edit Second</a> <a href='#' class="edit" onclick='edit()'>Edit Third</a>y
const el = document.getElementsByClassName("edit"); el.addEventListener("click", beforeEdit, false); function beforeEdit() { //this should be called before edit(), after that edit() must be called. }Elimine el atributo, luego llame a edit usted mismo en su propio controlador. También deberá iterar sobre los elementos correctamente: getElementsByClassName devuelve una colección, no un elemento.
for (const anchor of document.querySelectorAll('.edit')) { anchor.removeAttribute('onclick'); anchor.addEventListener('click', () => { // insert your function code here, then: edit(); }); }cómo puede obtener/recuperar ese cuerpo del método edit () usando js y ejecutarlo
En otras palabras, su requisito es que onclick="edit()" no siempre sea edit() .
Podrías usar eval pero incluso los estados de la página de MDN:
" Ejecutar JavaScript desde una cadena es un riesgo de seguridad enorme".
Una alternativa, para asegurarse de que su código se ejecute primero, es insertar su código al comienzo de onclick= , por ejemplo:
$(".edit").attr("onclick", (i, attr) => "beforeEdit();"+attr);Fragmento de ejemplo:
$(".edit").attr("onclick", (i, attr) => "beforeEdit();"+attr); function beforeEdit() { console.log("before edit"); } function edit() { console.log("edit"); } function edit2() { console.log("edit2"); } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <a href='#' class="edit" onclick='edit()'>Edit First</a> <a href='#' class="edit" onclick='edit2()'>Edit Second</a> <a href='#' class="edit" onclick='edit()'>Edit Third</a>Dado que los atributos de evento se activan en las fases objetivo o burbujeante , puede agregar un evento de captura en estos elementos y envolver su contenido en un nuevo elemento para que el evento realmente se active en el elemento secundario:
let val = 0; const els = document.querySelectorAll(".edit"); els.forEach(el => el.addEventListener("click", beforeEdit, {capture: true})); function beforeEdit() { console.log("setting global val to ", val = Math.random()); } function edit() { console.log("global val is now", val); event.preventDefault(); } <a href='#' class="edit" onclick='edit()'><span>Edit First</span></a> <a href='#' class="edit" onclick='edit()'><span>Edit Second</span></a> <a href='#' class="edit" onclick='edit()'><span>Edit Third</span></a>O, quizás más limpio, puede adjuntar el controlador de eventos en un padre:
let val = 0; document.body.addEventListener("click", beforeEdit, {capture: true}); function beforeEdit(evt) { if (evt.target.matches("a.edit,a.edit *")) { console.log("setting global val to ", val = Math.random()); } } function edit() { console.log("global val is now", val); event.preventDefault(); } <a href='#' class="edit" onclick='edit()'>Edit First</a> <a href='#' class="edit" onclick='edit()'>Edit Second</a> <a href='#' class="edit" onclick='edit()'>Edit Third</a>