rayontik
rayontik

Reputation: 21

Using document.getElementsByClassName

I coded two lines of PHP that allow me to protect an email address.

$mymail=strrev($mymail);
$mymail=str_replace("@","<b>@</b>",$mymail);
echo "<span class='spdefense'>".$mymail."</span>";

[email protected] becomes moc.liamg<b>@</b>okitot in source code The problem is that users can no longer copy and paste e-mail addresses transformed in this way. So I want to create a javascript function that allows on a ctrl+c to: Reverse string and remove <b> tags around @ for all email adresses on a page. No matter to reverse string and replace <b> tags. Mail adress is inside a span element with a class.

longueur=document.getElementsByClassName("spdefense");
for(var i= 0; i < longueur.length; i++)
{
    machaine= document.getElementsByClassName("spdefense")[i].textContent;
    machaine.split().reverse().join();
    machaine.replace("<b>@</b>", "@");
}

I looked at "copy" and "clipboard" but I can't produce a valid code, to tell the truth I'm not sure if can be done...

Upvotes: 0

Views: 430

Answers (2)

Jack_Hu
Jack_Hu

Reputation: 1379

A few things:

  • You want to re-use the longueur variable, as that's more efficient than grabbing all the classes twice.
  • You want to define it in the local block scope, not in the global one, using the const keyword.
  • You want to use the spread operator [...] to convert the string to an array of characters.
  • You want to join on an empty string .join(''), as the default for join is to use commas ,.
  • You want to save the result back to a variable.
  • You want that variable, machaine, to also be block scoped, rather than globally scoped.
  • You want to export the result out of the loop somehow, using an array, output, in the below example, seems appropriate.
const longueur = document.getElementsByClassName("spdefense");
const output = [];
for(var i = 0; i < longueur.length; i++)
{
    const machaine = [...longueur[i].textContent].reverse().join('');
    output.push(machaine.replace("<b>@</b>", "@"));
}
console.log(output);

That should work a little better... I haven't tested it, but it seems right.

As for the copy & paste, you can take a browse of the API documentation over at MDN.

The long and short of it is that you can use something like:

function setClipboard(text) {
    const type = "text/plain";
    const blob = new Blob([text], { type });
    const data = [new ClipboardItem({ [type]: blob })];

    navigator.clipboard.write(data).then(
        function () {
        /* success */
        },
        function () {
        /* failure */
        }
    );
}

On a button click, which will add whatever text is, to the users system clipboard. There are permission considerations to take in to account, but chrome has it enabled by default (IIRC).

Upvotes: 1

Rounin
Rounin

Reputation: 29453

You can write to the clipboard via:

  • navigator.clipboard.writeText()

Consequently, when a user copies an email address, you can:

  • grab the obfuscated contents of the <span> which registered the copy event
  • deobfuscated those contents
  • write the deobfuscated contents to navigator.clipboard

Working Example:

const obfuscatedEmail = document.getElementsByClassName('obfuscated-email')[0];

obfuscatedEmail.addEventListener('copy', (e) => {
  e.preventDefault();
  let deobfuscatedEmail = e.target.textContent.split('').reverse().join('');
  navigator.clipboard.writeText(deobfuscatedEmail);
});
textarea {
  display: block;
  width: 300px;
  height: 60px;
  margin-top: 12px;
  resize: none;
}
<h2>Copy and Paste the obfuscated email below:</h2>

<span class="obfuscated-email">moc.liamg<b>@</b>okitot</span>

<textarea></textarea>

Upvotes: 0

Related Questions