Read each line of an element in jQuery - javascript

Suppose I have this html markup:
<div id="wrapper">
<pre class="highlight">
$(function(){
// hide all links except for the first
$('ul.child:not(:first)').hide();
$("a.slide:first").css("background-color","#FF9900");
$('ul.parent a.slide').click(function(){
$('ul.parent a.slide').css("background-color","#3399FF");
$('ul.parent a.slide').mouseout(function(){
$(this).css("background-color","#3399FF");
});
$('ul.parent a.slide').mouseover(function(){
$(this).css("background-color","#66CC66");
});
});
});
</pre>
</div>
What is the easiest way to read each line of code present in the div. How do I extract each line of code from that div or loop over each line styling in any way I want.
Edit:
I have added the pre tag after the wrapper class, please consider that also.

Do you mean something like this:
var lines = $("#wrapper pre").text().split("\n");
$.each(lines, function(n, elem) {
console.log(elem);
});
Since this is text (and not html) you should treat it as such. The only way to do it is to read it and then use string parsing routines.

Mostly just need straight JavaScript:
var text;
text = $('#wrapper pre').text(); // Or .html, doesn't really matter with the input you showed
text = text.replace("\r\n", "\n"); // Just in case
text = text.split("\n");
// text is now an array of lines
Some browsers will trim the first line break, some won't, so there are a couple of edge cases (no pun). But that's basically it.

Related

Replace non-code text on webpage

I searched through a bunch of related questions that help with replacing site innerHTML using JavaScript, but most reply on targetting the ID or Class of the text. However, my can be either inside a span or td tag, possibly elsewhere. I finally was able to gather a few resources to make the following code work:
$("body").children().each(function() {
$(this).html($(this).html().replace(/\$/g,"%"));
});
The problem with the above code is that I randomly see some code artifacts or other issues on the loaded page. I think it has something to do with there being multiple "$" part of the website code and the above script is converting it to %, hence breaking things.using JavaScript or Jquery
Is there any way to modify the code (JavaScript/jQuery) so that it does not affect code elements and only replaces the visible text (i.e. >Here<)?
Thanks!
---Edit---
It looks like the reason I'm getting a conflict with some other code is that of this error "Uncaught TypeError: Cannot read property 'innerText' of undefined". So I'm guessing there are some elements that don't have innerText (even though they don't meet the regex criteria) and it breaks other inline script code.
Is there anything I can add or modify the code with to not try the .replace if it doesn't meet the regex expression or to not replace if it's undefined?
Wholesale regex modifications to the DOM are a little dangerous; it's best to limit your work to only the DOM nodes you're certain you need to check. In this case, you want text nodes only (the visible parts of the document.)
This answer gives a convenient way to select all text nodes contained within a given element. Then you can iterate through that list and replace nodes based on your regex, without having to worry about accidentally modifying the surrounding HTML tags or attributes:
var getTextNodesIn = function(el) {
return $(el)
.find(":not(iframe, script)") // skip <script> and <iframe> tags
.andSelf()
.contents()
.filter(function() {
return this.nodeType == 3; // text nodes only
}
);
};
getTextNodesIn($('#foo')).each(function() {
var txt = $(this).text().trim(); // trimming surrounding whitespace
txt = txt.replace(/^\$\d$/g,"%"); // your regex
$(this).replaceWith(txt);
})
console.log($('#foo').html()); // tags and attributes were not changed
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo"> Some sample data, including bits that a naive regex would trip up on:
foo<span data-attr="$1">bar<i>$1</i>$12</span><div>baz</div>
<p>$2</p>
$3
<div>bat</div>$0
<!-- $1 -->
<script>
// embedded script tag:
console.log("<b>$1</b>"); // won't be replaced
</script>
</div>
I did it solved it slightly differently and test each value against regex before attempting to replace it:
var regEx = new RegExp(/^\$\d$/);
var allElements = document.querySelectorAll("*");
for (var i = 0; i < allElements.length; i++){
var allElementsText = allElements[i].innerText;
var regExTest = regEx.test(allElementsText);
if (regExTest=== true) {
console.log(el[i]);
var newText = allElementsText.replace(regEx, '%');
allElements[i].innerText=newText;
}
}
Does anyone see any potential issues with this?
One issue I found is that it does not work if part of the page refreshes after the page has loaded. Is there any way to have it re-run the script when new content is generated on page?

javascript replace text after the page has loaded

I want to remove/hide a piece of text that loads on my page.
The element doesn't have an id to relate to so I want to use a text-specific method.
Let's say the text is:"remove this line of text".
The html looks like this:
<div class="aClassName">
<p>
<strong>remove this line of text</strong>
... the rest of the content.
</p>
I have tried the following:
jQuery(document).ready(function($){
document.body.innerHTML = document.body.innerHTML.replace('remove this line of text', '');
});
Didn't work. So I tried this:
jQuery(document).ready(function($){
$("body").children().each(function () {
$(this).html( $(this).html().replace(/remove this line of text/g,"") );
});
});
Didn't work. The idea is that after the page is loaded it removes the line.It doesn't produces any errors as well. Not even in the firebug.
Anyone?
Target Elements Based On Their Content
You could accomplish this using the :contains() pseudoselector in jQuery that would allow you to target certain elements based on their contents :
$(function(){
// This will remove any strong elements that contain "remove this line of text"
$('strong:contains("remove this line of text")').remove();
});
You can see a working example of this here.
Broader Approach (Just Targets Elements Based On Selectors)
If you wanted a more simply target it by a more general selector (i.e. any <strong> tags that appear beneath a class called aClassName :
$('.aClassName strong').remove();
You can see an example of this approach here.
I guess you can use find() and text(), i.e.:
$('.aClassName').find('strong').text("123");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="aClassName">
<p>
<strong>remove this line of text</strong>
... the rest of the content.
</p>
Or simply:
$('strong:contains("remove this line of text")').text("New text");
Update:
After analyzing the link supplied on the comments, you can use the following:
$('.payment_method_mollie_wc_gateway_ideal').find('strong').text("");

How do get contents of a p element one at a time

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;
});

Add actual HTML elements to PRE/CODE contents

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);
});
})();

What is the Javascript Regexp for finding the attributes in a <span> tags?

I have a <div contenteditable="true> that I am trying to use to get text from users. I would use a simple <textarea>, but I need line-breaks and eventually lists and tables etc. I am trying to build something that is semi a rich-text editor, but not a full fledged one. I do not want to use a rich text editor.
I am trying to eliminate the attributes on <span> tags from the text that is typed into the <div contenteditable="true> . Is there a way to do that with Regexp? I was having difficulties coming up with a Regexp because I can't figure out how to make it so that the string starts with <span and ends with > and any number of characters can be in between. Is there a way to combine that in one Regexp? I came up with /^<span >$/ but that does not work because there is no division between the two strings. Would something like this work: /^[<span][>]$/g?
Use DOM functions for it. Here's some code using jQuery to make it easier and nicer to read:
$('#your-div span').each(function() {
var elem = this, $elem = $(this);
$.each(elem.attributes, function(i, attr) {
if(attr) {
$elem.removeAttr(attr.name);
}
});
});
Demo: http://jsfiddle.net/ThiefMaster/qfsAb/
However, in your case you might want to remove attributes not only from spans but from all elements unless the attribute is e.g. align or href.
So, here's some JS for that: http://jsfiddle.net/ThiefMaster/qfsAb/1/
$('#your-div').children().each(function() {
var elem = this, $elem = $(this);
$.each(elem.attributes, function(i, attr) {
if(attr && attr.name != 'href' && attr.name != 'align') {
$elem.removeAttr(attr.name);
}
});
});
Parse the HTML and then strip out the attributes afterwards. If you're doing this in a browser, you have a high grade HTML parser right at your disposal (or you have IE), so use it!
I made a working demo at http://jsfiddle.net/b3DSQ/
$('#editor span').each(function(i, el) {
var attrs = el.attributes;
$.each(attrs, function(i, a) {
$(el).removeAttr(a.name);
});
});
[I changed an earlier version which copied the contents into memory, edited, and then replaced - hadn't realised that the stuff typed into the div was automatically valid in the DOM].
Try this:
your_string.replace(/<span[^>]*>/g, '<span>');
This will break however if the user writes something like <span title="Go > there">

Categories

Resources