Is there a way to dynamically insert a <span></span> tag into every line of a <pre></pre> block in HTML without manually coding each line?

One of my recent challenges was figuring out how to incorporate line numbers into source code using CSS. I finally achieved the desired effect, as shown below:

https://i.sstatic.net/A0P12.png

However, achieving this required me to consistently use <span>...</span> tags within the HTML code:

<pre class="code">
  <span>var links = document.getElementsByClassName("link");</span>
  <span>for(var i = 0; i &lt; links.length; i++){</span>
  <span>  links[i].onclick=function(){</span>
  <span>   alert(i+1);</span>
  <span>  };</span>
  <span>}</span>
</pre>

To achieve the desired outcome of displaying line numbers, I had to position the span tags at the beginning and end of lines. However, I am confident that there must be a more efficient solution that does not require manually adding each span tag. Perhaps utilizing JavaScript or jQuery could provide a better alternative, but I am unsure of how to proceed. Any assistance would be greatly appreciated.

NOTE:
My dilemma is not related to displaying line numbers when <span> tags are already present in the HTML code. Rather, I am seeking guidance on how to automatically insert these tags into suitable locations if they are absent from the original code, enabling me to apply CSS styles accordingly.

Answer №1

I have combined @Stewartside's response with the specific information you requested.

Here is a basic JavaScript code snippet that replaces any lines in an element with a code class with a span tag, applying @Stewartside's CSS:

var codeElement = document.getElementsByClassName("code"); //array of code blocks
var formattedCode = codeElement[0].textContent.replace("\r\n", "\n").split("\n");
var codeLength = formattedCode.length;
formattedCode.forEach(function(line, index, array) {
  if (codeLength - 1 == index) return; 
  array[index] = "<span>" + line + "</span>";
});

codeElement[0].innerHTML = formattedCode.join("\n");

$(".code-jquery").each(function(index, codeElement) {
  var formattedCode = $(codeElement).html().replace("\r\n", "\n").split("\n");
  
  var codeLength = formattedCode.length;
  $(codeElement).text("");
  $.each(formattedCode, function(index, line) {
    if (codeLength - 1 == index) return;
    $(codeElement).append("<span>" + line + "</span>\n")
  });
});
pre {
  background: #eee;
  counter-reset: section; /* Reset the counter to 0 for each new pre */
}
pre span:before {
  counter-increment: section; /* Increment the section counter*/
  content: counter(section); /* Display the counter */
  padding: 0 5px;
  border-right: 1px solid #777;
  margin-right: 5px;
  color: #777
}

pre.code-jquery span {
  color: green;
}
<pre class="code">
  var links = document.getElementsByClassName("link");
  for(var i = 0; i &lt; links.length; i++) {
    links[i].onclick = function() {
    alert(i+1);
  };
  }
</pre>

//jQuery version
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre class="code-jquery">
  var links = document.getElementsByClassName("link");
  for(var i = 0; i &lt; links.length; i++) {
    links[i].onclick = function() {
    alert(i+1);
  };
  }
</pre>

Answer №2

One way to accomplish this is by utilizing CSS counters

You won't need any JavaScript or jQuery for this, as it was introduced in CSS 2.1 and has widespread browser support.

pre {
  background: #eee;
  counter-reset: section; /* Reset the counter to 0 for each new pre */
}
pre span:before {
  counter-increment: section; /* Increment the section counter*/
  content: counter(section); /* Display the counter */
  padding: 0 5px;
  border-right: 1px solid #777;
  margin-right: 5px;
  color: #777
}
<pre class="code">
  <span>var links = document.getElementsByClassName("link");</span>
  <span>for(var i = 0; i &lt; links.length; i++){</span>
  <span>  links[i].onclick=function(){</span>
  <span>   alert(i+1);</span>
  <span>  };</span>
  <span>}</span>
</pre>

<pre class="code">
  <span>var links = document.getElementsByClassName("link");</span>
  <span>for(var i = 0; i &lt; links.length; i++){</span>
  <span>  links[i].onclick=function(){</span>
  <span>   alert(i+1);</span>
  <span>  };</span>
  <span>}</span>
</pre>

Answer №3

If you want to add a span before each line, you can use the codepen link provided. I am currently utilizing the jQuery insertBefore() method for this task.

Here is an explanation of the code: $('.code') selects the pre tag. Using jQuery's .find() method will target all the spans inside the pre tag. The .each() function in jQuery acts as a for loop, iterating through each span tag within the pre tag. The .insertBefore() function inserts the content specified in the selector before the element mentioned inside the function.

var iCount = 1;
$('.code').find('span').each(function(){
  
  $( "<span>"+iCount+"| </span>" ).insertBefore( this);
  iCount++;
});
pre{
   background: #eee
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre class="code">
  <span>var links = document.getElementsByClassName("link");</span>
  <span>for(var i = 0; i &lt; links.length; i++){</span>
  <span>  links[i].onclick=function(){</span>
  <span>   alert(i+1);</span>
  <span>  };</span>
  <span>}</span>
</pre>

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

Experiencing problems with the CSS styles after including the file.php in

I have a main PHP page called index.php where all other PHP files are included using index.php?page=example. These pages are located in a separate folder, as shown below: public_html/index.php public_html/css/style.php public_html/pages/ The index.php fi ...

Serialize all form fields using JQuery

I'm currently utilizing the following code snippet: var data = $(":input,:submit", this).serializeArray(); This code successfully captures form data for the specified elements. However, I am now facing an issue with retrieving selected entries from ...

Searching for different forms of multiple words using regular expressions

I have a value saved in a variable: var myvalue = "hello bye"; var myText = "hellobye is here and hello-bye here and hello.bye" Is there a way to check if different versions of myvalue are present in the text? I am currently using this pattern: hello ...

Attempting to utilize a Python web scraping tool to extract content from a webpage that undergoes regular text updates

I must admit that I am a complete beginner who is feeling lost and unsure of what to do. My goal is to extract 4 pairs of numbers from a webpage using a web scraper. These numbers change when modified on a different page, but I'm unable to pull the d ...

What is the proper way to execute a Python script within an HTML document?

After creating some mini games with Python a while back, I've now transitioned to working with HTML. While I understand how to link a CSS file to an HTML file, I'm unsure about linking a Python file to specific words within an HTML file. I attem ...

Submit numerous queries to verify the presence of a name and assign it to the name attribute

I have a collection of unique devices. As part of a process, I need to assign a default name to each device ("DeviceX" - where X is a sequential number), but some of the names may already be in use. To handle this, I must make a request to check ...

What is the best way to keep a bootstrap navbar fixed at the top when scrolling? (It's a bit tricky)

Check out this image of my website header. HERE Is there a way to achieve a smooth scrolling effect for the blue navbar as I scroll down the page? (Specifically just the navbar, excluding the logo and social media elements). Using position:fixed; does ...

Looping in REACT with state updates can cause the values to be overwritten

I'm encountering a problem with my function in React that updates the state. It fetches data from a URL in an array and creates a new item, but when trying to update another state array with this new object, it keeps overriding the first item each tim ...

Adjust the background color of a div dynamically depending on a specified percentage, similar to a progress bar

I have a div containing some text along with a percentage value (e.g. 78%). I would like to represent this percentage as the background color of the entire div, not just a portion of it. <div class="my-div"> <div class="percentage-colored" ...

Jquery pop-up information bubble

I'm currently using: jQuery Bubble Popup v.2.3.1 http://maxvergelli.wordpress.com/jquery-bubble-popup/ The following code should be included within the document ready section: $('.bubble').CreateBubblePopup({ align: 'cent ...

Guide to correctly setting up the iotivity-node npm package

I will be very specific and break down my question into points. Currently, I am operating on an Ubuntu 14.04 LTS machine with node.js installed 1. Overall Goal: I am aiming to successfully install the iotivity-node npm package on my local computer 2. C ...

Comparing Node.js and green threads for calling multiple web services

I am working on a project that requires my webserver to make calls to multiple web services. Initially, I planned to implement this feature in Node.js but I am now exploring the option of using gevent instead. This is because I find callback code challengi ...

Discovering the value of an item when the editItem function is triggered in jsGrid

Within my jsGrid setup, I have invoked the editItem function in this manner: editItem: function(item) { var $row = this.rowByItem(item); if ($row.length) { console.log('$row: '+JSON ...

Where is the best place to implement HTML form validation: on the frontend or backend?

Is it important to validate all values before submitting the form to the backend server, as mentioned in the title? ...

Looking to expand the width of the b-modal component in a Vue.js application using Bootstrap

Using bootstrap v4 for VueJS, I encountered a challenge with increasing the width of b-modal. Despite trying various solutions mentioned here, nothing seemed to work. <b-modal :ref="fieldName" :id="fieldName" :title="msg" size="lg" modal-class="b-modal ...

Using more than one button to activate a single Material-UI Popper component

I recently found myself in a situation where I needed to activate the Material-UI <Popper /> component from various clickable elements. According to the Popper component API on the official Material-UI website, setting the anchorEl property determine ...

Switching Between Background Images in Angular

Looking to change the background-image of an element upon clicking it. Currently, this is what's in place: <div class="item-center text-center" toggle-class="active cable"> <div class="quiz-background"></div> <p class="size ...

Is there a way to give only the left corners of a button a rounded look?

Here is the visual representation of the button: https://i.stack.imgur.com/Bjlkp.png ...

Enhance React component props for a styled component element using TypeScript

Looking to enhance the properties of a React component in TypeScript to include standard HTML button attributes along with specific React features such as ref. My research suggests that React.HTMLProps is the ideal type for this purpose (since React.HTMLA ...

Guide on incorporating an SVG file according to the user's role within an Angular application

How can I dynamically import an SVG file based on the user's role, whether they are an admin or a regular user? Currently, my code in layout.ts looks like this: <div class="layout-body h-100 "> <ng-container [ngTemplateOutlet]=&q ...