Code
/**
* Arreglo de telefonos
*/
var telefonos = [
"316 841 1233",
"321 876 5432",
"318 220 0880",
"313 123 4567",
"315 321 7654",
"315 366 6666",
"2874566",
"2661588",
"2662255",
"3153274802",
"2771521"
];
$(document).ready(function() {
/* Elementos */
var body = document.body;
var html = body.innerHTML;
var htmlModificado;
/* Buscamos cada telefono del arreglo */
telefonos.forEach(function(telefono) {
/* Creamos la etiqueta "phone" */
var phone = crearPhone(telefono);
htmlModificado = html.replace(telefono, phone.outerHTML);
body.innerHTML = htmlModificado;
html = body.innerHTML;
});
});
function generarMensaje(elemento) {
console.log("Enviando mensaje a " + elemento.innerHTML);
}
function crearPhone(telefono) {
var phone = document.createElement("phone");
phone.innerHTML = telefono;
phone.setAttribute("class", "enlace");
phone.onclick = function() {
generarMensaje(this);
}
return phone;
}
.enlace {
cursor: pointer;
font-weight: bold;
text-decoration: underline;
color: blue;
}
.enlace:hover {
text-decoration: none;
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="contenido">
<div>
<div>316 841 1233</div>
<div>321 876 5432</div>
<div>318 220 0880</div>
</div>
<div>
<a>313 123 4567</a>
<br>
<a>315 321 7654</a>
<br>
<a>315 366 6666</a>
</div>
<div>
2874566 - 2661588 - 2662255
</div>
<div>
3153274802 - 2771521
</div>
</div>
Context
I am working on a Chrome extension, which will be in charge of making certain modifications in the DOM of a site, looking for some texts and replacing them with certain custom labels, which will allow to carry out some specific actions.
That is, the extension will do this:
1) Find a text where the word "love" is
<a>Hay amor en el aire.</a>
2) Add the custom label
<a>Hay <palabra onclick="buscar()">amor</palabra> en el aire.</a>
Goal
In the previously exposed example, I need to do the following:
Having a site, with a list of numbers at different levels and within different tags within the DOM, I will base myself on an array that contains these numbers, and I will look for them one by one, I will enclose them in a custom tag called
<phone>
, allowing each one of these numbers have a different action than the rest of the surrounding text.
Problem
In this section of my code:
function crearPhone(telefono) {
var phone = document.createElement("phone");
phone.innerHTML = telefono;
phone.setAttribute("class", "enlace");
phone.onclick = function() {
generarMensaje(this);
}
return phone;
}
I create the function to which I will indicate the number that we are going to enclose in the label <phone>
, assigning the class, the event, there onclick
.
If the code is executed, all the phone numbers have changed color successfully, the problem is that none of them execute the function that was assigned during the onclick
:
phone.onclick = function() {
generarMensaje(this);
}
Therefore the code does not print any messages or errors to the console.
Note
It should be clarified that I must solve the problem using pure JavaScript , it does not help me to use a library such as jQuery or others, since in said environment I cannot use it.
The problem is
Phone.outerHTML
that since it doesn't serialize events to the DOM, the dophone.onclick = ...
affects the DOM element but not its serialized HTML element.Solution
replace
phone.onclick
withphone.setAttribute('onclick',...)
A better alternative
Since you're working on serialized elements, they still need to be parsed by DOM.parser , either directly or indirectly with the innerHTML / outerHTML sets . It's best to directly edit the DOM instead of the serialized html.
What the above code does is recursively parse all the text, to any depth, replace that text with an element
phone
( UnknownHTMLElement ) and finally make the node a dummy node (empty), the reason for the dummy node is to simplify the code