I'm trying to create a quick/dirty way to add some syntax highlighting for pre/code tags in html using javascript.
The problem i'm running into, is that if i edit either the text() or html(), I get escaped content. That is, the added tags render as pre/code, or i get a bunch of eascape characters.
Consider the following html:
<pre>
<code class="target">
public interface __iIFoo { }
public class __tBar : __iIFoo { }
var list = new List__/__iIFoo\__();
</code>
</pre>
The goal here is to replace occurrences of __iIFoo with:
<span class="interface">IFoo</span>
So that it can be highlighted with css. And of course, when it's rendered, I don't want to see the actual SPAN tag.
Here's what I've tried:
$(function(){
var iPatt = /__i\w+/g
$.each($(".target").text().match(iPatt), function(i,match){
var replace = '<span class="interface">'+match.substring(3)+'</span>';
$(".target").text(function(){
return $(this).text().replace(match, replace);
});
});
});
This works, BUT, the span tags I'm adding show up in the rendered content e.g. they are just like all the other pre code. I don't want to see it!
Use .html() instead of .text(). When you use .text(), the value is the literal text that you want users to see, so it replaces special HTML characters with entities so they'll show up literally.
DEMO
.text() treats value as text and .html() render it as html content
$(".target").html(function () { //replace text with html
return $(this).text().replace(match, replace);
});
Try using it with html instead:
$(function(){
var iPatt = /__i\w+/g
$.each($(".target").text().match(iPatt), function(i,match){
var replace = '<span class="interface">'+match.substring(3)+'</span>';
$(".target").html(function(){
return $(this).text().replace(match, replace);
});
});
});
As I said in my comment, change the html rather than the text (fiddle).
As a side-note, it's worrisome that you're completely overwriting the contents of .target every time you encounter a match. You should take advantage of RegExp capture groups and perform only one assignment.
(function () {
var iPattern = /__i(\w+)/g,
iTemplate = "<span class='interface'>$1</span>";
$(".target").each(function () {
this.innerHTML = this.innerHTML.replace(iPattern, iTemplate);
});
})();
Related
I am trying to replace all dashes(-) by a "br" but it gives me issues.
I have tried
var strNewString = $('.member__designation').html().replace(/-/g,'<br>');
$('.member__designation').html(strNewString);
Here is the html
Before applying the code above
After applying the code above
You likely want
$('.member__designation').each(function() {
this.textContent = this.textContent.replace(/-/g,'<br>')
})
assuming $('.member__designation') only has text and not html
IF there is only SIMPLE HTML like <b> then do
$('.member__designation').each(function() {
this.innerHTML = this.innerHTML.replace(/-/g,'<br>')
})
It looks like you grab all elements with class .member__designation and you replace them with whatever your regex grabs. I think you must change your implementation
Using jQuery, I need to parse the contents of each <p> tag individually and then replace the text with the new text.
The code at the moment looks like:
str = $('p').text();
str = str.replace('yadayada','yada');
$('p').text(str);
This is currently getting the contents of all the <p> tags, concatenating them then replacing the massive block of text into each <p> which is close but not quite what I'd like it to do.
Is there a way to get the contents of each <p> block one at a time and replacing it with only it's contents? I do not know what ids or classes are being applied to them hence the need to use the generic tag.
Any help is much appreciated! :)
Use the text(fn)
A function returning the text content to set. Receives the index position of the element in the set and the old text value as arguments.
$('p').text(function(_ text){
return text.replace('yadayada','yada');
});
Use the text() version that accepts a callback as the second argument and return the replaced content from the callback
$('p').text(function(i, str) {
return str.replace('yadayada', 'yada');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>yadayada-1</p>
<p>yadayada-2</p>
<p>yadayada-3</p>
<p>4</p>
You can use .each method on the colletion:
$('p').each(function (pEl) {
var text = pEl.textContent;
});
I am attempting to write my own piece of Javascript that converts html to ascii code (for learning purposes) so that the browser will render the code as you would see it in a text editor.
After looking around on Stack I have gotten as far as below. I am trying to turn an html element into a string; at this stage I am just trying to .replace() the angular brackets into ascii. If anyone could tell me where I am going wrong as far as having my test <body> tag showing up in the console that would be much appreciated.
<code class="lang-html">
<body></body>
</code>
(function() {
var html = $('.lang-html').innerHTML;
html.replace('<', '<');
html.replace('>', '>');
console.log(html);
});
Just to clarify, I am expecting that the console would spit out <body></body>.
Any help would be much appreciated.
A few things:
$('.lang-html').innerHTML
Assuming this is jQuery, this won't work. .innerHTML only works on raw DOM elements, like what's returned from document.getElementById(...). Instead, $('.lang-html') returns a jQuery collection, which has its own accessor methods. You should do:
$('.lang-html').html() // get the HTML as text from this element
Moving on, .replace() won't modify the original string. It returns a new copy. In the simplest case you can do:
var html = $('.lang-html')
.html()
.replace('<', '<')
.replace('>', '>');
But you still have to re-assign it to the HTML source. Again, jQuery provides a simple API for this.
$('.lang-html').html(html);
However, there's one more problem. .replace() only replaces the first match in a string. To replace all of them, you need to construct a regex and use the /g (global) flag. Here's the complete code:
var $element = $('.lang-html');
var html = $element.html()
.replace(/</g, '<')
.replace(/>/g, '>');
$element.html(html)
If you want get html code representation of an DOMElement in your browser then you won't need the replace to escape the html special chars. But you can use the browser to take care of all edge cases.
You could just use innerHTML/outerHTML and textContent.
This will e.g. will replace the content of the body with its html code representation.
var elm = document.getElementsByTagName('body')[0];
elm.textContent = elm.outerHTML;
Or if you just want to have the result as string but not displayed in the browsers then you could wrap that into a function:
function escapeHTML(html) {
var div = document.createElement('div');
div.textContent = html;
return div.innerHTML;
}
console.log( escapeHTML('<div>test</div>') );
You can also do a
$('.lang-html').prop("innerText")
which will hand you back the contents of that div, as real text.
No further translation should be needed.
Actually <body> tags will not be returned in the innerHTML of the posted code because the HTML is invalid. To explain:
To cater for changes to the DOM made in Javascript, browsers dynamically create innerHTML strings from the DOM by inspecting child elements of a specified node and generating HTML code from them.
Since <body> tags are only valid immediately following the head section, browsers silently respond to the <code> tag in your post by first creating a body element in which to place it. The <body> tags which follow are then ignored because they are invalid in this position. Hence there is no body element child of the code node, and no body tags in its innerHTML
Update (2): To pretty print the HTML without viewing page source you could try.
(function() {
var body = document.body;
var html = body.parentNode.outerHTML;
html = html.replace(/</g, '<');
html = html.replace(/>/g, '>');
html = html.replace(/\ /g, " ");
html = html.replace(/\n/g, '<br>\n');
// console.log(html);
body.innerHTML = html;
body.style.fontFamily = "monospace";
});
I am trying to change color of a part of strings. I have a list of DOM elements, and for each of them, the text can contain some hashtags. I would like to put in color all hashtags words which could be found in the text.
Here is the begin of the code :
var listOfText = document.getElementsByClassName("titleTweet");
for (var nodetext in listOfText) {
var divContent = listOfText[nodetext].innerHTML;
if (divContent.indexOf("#") !== -1) {
// Do job here
}
}
For example, divContent can be equals to "Hello my #friends ! How are you ?"
I would like to update the dom elements to put in red color the word "#friends".
I don't know how to do that using javascript or jQuery.
You can use a regexp to find the hastags and wrap them with html. Then use the .html() method to replace the original element's html with the new string.
Example snippet
$('#myDiv').replace(/#[a-z0-1A-Z]+/g, '<span style="color: red;">$&</span>'));
Working example - http://jsfiddle.net/4p4mA/1/
Edited the example to work on all divs on the page.
Note: This will only work so long as your element only contains text, because it is replacing all the child nodes with its text value.
use regex for this, find text having hashtag and replave that in span tag for each element.
$('.titleTweet').each(function(){
var $this=$(this);
$this.html($this.text()
.replace(/#[a-z0-1A-Z]+/g, '<span style="color: red;">$&</span>'));
});
See demo here
.innerHTML is a poor basis to starting replacing text. You'll want to navigate down to the text nodes and use .nodeValue to get the text. Then you can start splitting up the text nodes.
I have a DIV element that's filled with a bunch of HTML entities that I want to remove:
<div class="text">
<p><p><span style="line-height:25px;"></span><span style="line-height:25px;">Hej hop!</span> <span style="line-height:25px;"></span><span</p>
</div>
I'm using jQuery and created this code but it isn't working:
$('.text').each(function () {
$(this).replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
});
I'm trying to replace the text with the phrase "Hej Hop!".
The regex is not wrong..
Here is how I did it with some other pages:
text = text.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
But this was in a javascript function with parameters that returned the text.. But on this specific page I need to use jquery and iterate and check...
Question Solved:
$('text').each(function () {
$(this).html(function (i, v) {
return $('<div>').html(v).text();
});
});
You just need:
$('.text').empty();
edit — if you want to remove the markup from the contents of the element, the simplest thing to do would be what Marc B suggested in a comment:
$('.text').each(function() {
$(this).text($(this).text());
});
You can strip them like this using .html()
$('div.text').html(function(i,v){
return $('<div>').html(v).text();
// create new div - append HTML and get the text from the div
});
http://jsfiddle.net/UA9P9/
It still leaves some characters in there so you will probably need to regex them out with your regex
$('div.text').html(function(i,v){
return $.trim($('<div>').html(v).text().replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, ""));
});
http://jsfiddle.net/VfxaT/
These are Ascii code so the Regex for that is: /xxx[\x00-\x7F]+xxx/