What is the best way to mix up all the characters within the content of an HTML document?

<div id="contentContainer">
    <h1>First Page</h1>
    <section id="mainSection">
        <p>Lorem ipsum dolor sit amet</p>
        <ul>
            <li><a href="#">Black world</a></li>
            <li><a href="#">White world</a></li>
            <li><a href="#">666 world</a></li>
        </ul>
    </section>
</div>
<button id="changeTextContent">Change Text</button>

function modifyContent() {
    var content = document.getElementById("contentContainer").innerText;

    var newContent = "";
    var alphabet = "abcdefghijklmnopqrstuvwxyz";
    var upperAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var numbers = "0123456789";

    function isLowercase(char) {
        return char >= "a" && char <= "z";
    }

    function isUppercase(char) {
        return char >= "A" && char <= "Z";
    }

    function isNumber(char) {
        return char >= "0" && char <= "9";
    }   

    for (var i = 0; i < content.length; i++) {
        if (isLowercase(content.charAt(i))) {
            newContent += alphabet[Math.floor(Math.random() * alphabet.length)];
        }
        else if (isUppercase(content.charAt(i))) {
            newContent += upperAlphabet[Math.floor(Math.random() * alphabet.length)];
        }
        else if (isNumber(content.charAt(i))) {
            newContent += numbers[Math.floor(Math.random() * numbers.length)];
        }
        else {
            newContent += content.charAt(i);
        }
    }
    for (var j = 0; j < content.length; j++) {
        content = content.replace(content[j], newContent[j]);
    }

    document.getElementById("contentContainer").innerText = content;
}

I am looking to create a JavaScript function that will randomly change every character inside the #contentContainer without affecting its style. This function should be triggered by clicking on the #changeTextContent button. I have tried writing a function for this purpose but it's not working as expected. Any assistance would be greatly appreciated.

Answer №1

(function(){
      var characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
      var unfilteredElements = document.querySelectorAll('#contents *');
      var filteredElements = [].filter.call(unfilteredElements, function(element){ return !element.children.length; });
      var button = document.querySelector('#randomText');
      button.onclick = shuffleText;
      
      function shuffleText(){
        for(var i = filteredElements.length-1; i > -1; i--){
            var text = filteredElements[i].innerText;
            for(var j = text.length-1; j > -1; j--){
              var randomChar = getRandomCharacter();
              text = text.replace(text[j], randomChar);
            }
            filteredElements[i].innerText = text;
          }    
      }
        
      function getRandomCharacter(){
          var length = characters.length-1;
          var index = Math.floor(Math.random() * (length));
          return characters[index];
      }
    })();
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>JS Playground</title>
</head>
<body style='padding:5px;'>
  <div id="contents">
    <h1>Lorem Ipsum</h1>
    <section id="sectionOne">
        <p>Testing Text</p>
        <ul>
            <li><a href="#">Link One</a></li>
            <li><a href="#">Link Two</a></li>
            <li><a href="#">Link Three</a></li>
        </ul>
    </section>
</div>
<button id="randomText">Shuffle Text</button>
</body>
</html>

Answer №2

Utilizing the treewalker api, this method efficiently locates all text nodes:

UPDATE: Added reset example. UPDATE: Excluded characters that are not in the alphabet.

function getAllTextNodes(node){
  var currentNode, nodes = [];
  var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, 
    { acceptNode: function(node) {
      if(/\S/.test(node.data)) return NodeFilter.FILTER_ACCEPT;
    }}, false);
  while(currentNode = treeWalker.nextNode()) nodes.push(currentNode);
  return nodes;
}

function randomIndex(array) {
    return Math.floor(Math.random() * array.length);
}

function createRandomChar(char) {
  var lower = "abcdefghijklmnopqrstuvwxyz";
  var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  var number = "0123456789";
  if((lower+upper+number).indexOf(char) < 0) return char;
  if(!isNaN(parseInt(char))) return number[randomIndex(number)];
  if(char === char.toLowerCase()) return lower[randomIndex(lower)];
  if(char === char.toUpperCase()) return upper[randomIndex(upper)];
  return char;
}

function randomizeContent(selector) {
    var element = document.querySelector(selector);
    var textNodes = getAllTextNodes(element);
    textNodes.forEach(function(node) {   
      node.textContent = node.textContent.split('').map(function(char) {
        return createRandomChar(char);
      }).join('');
    });
}

// example code
function reset(nodes, originalNodes) {
  nodes.forEach(function(node, index) {
    node.textContent = originalNodes[index] && originalNodes[index].textContent
  });
}

var contentSelector = '#contents';
var contentElement = document.querySelector(contentSelector);
var originalNodes = getAllTextNodes(contentElement).map(function(node) {
  return node.cloneNode();
});

document.querySelector('#randomText').addEventListener('click', function(e) {
  randomizeContent(contentSelector);
});

document.querySelector('#resetRandomText').addEventListener('click', function(e) {
  reset(getAllTextNodes(contentElement), originalNodes);
});
<div id="contents">
    <h1>Article I</h1>
    <section id="sectionOne">
        <p>Hello World</p>
        <ul>
            <li><a href="#">Black world</a></li>
            <li><a href="#">White world</a></li>
            <li><a href="#">666 world</a></li>
        </ul>
    </section>
    <section>
      <p>
      A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart. I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine. I am so happy, my dear friend, so absorbed in the exquisite sense of mere tranquil existence, that I neglect my talents.
      </p>
    </section>
</div>
<button id="randomText">Random Text</button>
<button id="resetRandomText">reset</button>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Absolute positioning causes an element's height to increase

As I delve into the realm of typographical animations and seek to calculate the baseline of a font at various sizes, I've stumbled upon a peculiar discovery: It appears that the height values of elements tend to increase in an erratic manner when thei ...

Using Javascript to upload an image and show it in a small display

Hey there, I have a functioning JavaScript code that loads an image uploaded by the user onto the HTML page. However, the issue is that the image doesn't have a set maximum height or width, causing buttons on the page to move out of view and become in ...

Implementing restriction measures for deterring harmful conduct within ExpressJS

Recently, I was alerted to some potential vulnerabilities in the application I'm currently developing, particularly in relation to the JavaScript code on the front-end. These flaws could allow a user to exploit the system by clicking multiple buttons ...

Managing DOM elements within a Vue 3 template using Typescript

As I delve into the world of Vue 3 as a beginner, I encountered a challenge when it came to managing the DOM within Vue 3 templates. Let's take a look at the source code. MainContainer.vue <template> <div class="main-container" r ...

automatically created button, form control named 'answer' that is not valid

Struggling with a challenge in attaching an event to a dynamically generated button. Despite conducting some research, most of the solutions suggest that this issue is typically related to a form control. However, in my scenario, the error "invalid form co ...

Dynamic linked selection

Basic selection Segment Selection Category selection The choice of one parameter affects the options available in another section, with subjects depending on segments. If a subject is selected, only assignments related to that specific subject will b ...

When using jQuery AJAX, the script is returning blank values

Facing a frustrating issue here. I'm sending an AJAX request to a PHP file, but when I check Chrome Network Tools, it doesn't return any JSON data. However, when I try posting the same data using POSTMAN in Chrome, it returns correctly. Also, if ...

What's the best way to transfer a variable from a PHP file to a jQuery AJAX file so that it can be used as the URL parameter when sending

I am just starting out with javascript, jquery, and ajax. Unfortunately, I've encountered an issue where my code is not working as expected. Below, you can find a detailed description of my code and the problem at hand. If someone could offer some ass ...

Arrange a JavaScript map based on its values and ensure that a specific field index remains at the top position

I'm sure this question may seem simple to some, but as a JavaScript novice, I couldn't find the answer myself. Here is the code snippet I'm working with: Let map = new Map<String,String> map.set('0', select) map.set('1&a ...

Downloading Files from Mongodb Using GridFS

I am working on an application that enables users to upload and download various files. Currently, I am facing a challenge where I am able to retrieve the file from my MongoDB database and download it locally on my machine, but I am encountering difficulti ...

Next.js, Knex, and SWR: Unusual issue disrupting queries

When making API requests using Next API routes and interacting with Knex + MySQL, along with utilizing React and SWR for data fetching, I encountered a strange issue. If a request fails, my SQL queries start to append ", *" to the "select" statement, causi ...

Issue when sending PHP Papa Parse object through AJAX

I am currently working on extracting a CSV local file in PHP using AJAX and have found success with Papa Parse. However, I am facing difficulties passing the results with AJAX. Despite trying various methods such as JSON.stringify, passing only the first f ...

Include a CSS file from an external JavaScript file

Is there a way to include an external CSS file in an external JS file? I am trying to reference and load Default.css inside Common.js like the image below shows. Any suggestions are greatly appreciated! BB ...

Utilizing separate JavaScript files in Bootstrap 5: A guide to implementation

I am currently using Bootstrap, but I am looking to decrease the size of the Javascript files being used. My main requirements are dropdown/collapse and occasionally carousel functionalities, so I only want to include those specific scripts. Within the "d ...

The Bootstrap validator triggers the form submission only after the second click

When I click on the submit button, I am attempting to submit a form that has its default action prevented and first checks a condition before proceeding. Below is the code snippet: $('#payment-form').bootstrapValidator({ live: 'dis ...

What prevents me from extending an Express Request Type?

My current code looks like this: import { Request, Response, NextFunction } from 'express'; interface IUserRequest extends Request { user: User; } async use(req: IUserRequest, res: Response, next: NextFunction) { const apiKey: string = ...

What is the best way to redirect a user to a different URL in Express while also sending additional data along with the request

[NODE, express] Developing a Facebook application where user grants access and is redirected to my site with a unique code at abc.com/heyBuddy/fb/callback?code="adasdasdasda". Once the code is received in route router.get('/heyBuddy/fb/callback', ...

Retrieve data from an AJAX call and PHP script upon successful completion

Utilizing AJAX (jQuery), my aim is to submit a form to user-ajax.php and expect the page to echo back a response like "success". In my AJAX code, I am checking the response value for success but it's not working as expected. Below is the PHP code snip ...

Interested in creating a Twitter bot that can automatically share images from a designated folder in sequential order. Leveraging the power of node.js

Recently, I've been following an online guide to create a Twitter bot that tweets images from a folder on my computer. While I have a vast collection of photos I'd like to share, the guide only demonstrates how to post them in a random sequence. ...

Incorporate JSON when adding a new row to the database using Ruby On Rails

Greetings, fellow developers! I am currently working on an application with a backend in Rails. My goal is to create a user from an AJAX request and have the server return a JSON object containing the newly saved user information. Below is my Rails code s ...