I need to replace some part of text, e.g. mustache var {{myvar}}, on already loaded page.
Example html:
<html>
<head>
<title>{{MYTITLE}}</title>
</head>
<body>
<p><strong><ul><li>text {{TEXT}}</li></ul></strong></p>
{{ANOTHER}}
</body>
</html>
What's the problem? Use $(html).html(myrenderscript($(html).html()))!
It's ugly, slow and brokes <script> tags.
What do you want?
I want to get closest tag with {{}} and than render and replace.
Your researches?
Firstly, i tried: $('html :contains("{{")). But it returns <title>, <p>, <strong> .... But i need <title> and <li>.
Than i tried to filter them:
$('html :contains("{{")').filter(function (i) {
return $(this).find(':contains("{{")').length === 0
});
...but it WONT return {{ANOTHER}}. And that is my dead end. Your suggestions?
Using http://benalman.com/projects/jquery-replacetext-plugin/ you could do the following:
$('html *').replaceText(/{{([^}]+)}}/, function(fullMatch, key) {
return key;
}, true);
See http://jsfiddle.net/4nvNy/
If all you want to do is replace that text - then surely the following works (or have I mis-understood)
usage is as follows: CONTAINER (body) - replaceTExt (search term (I have built the function to always include {{}} around the term), (replace - this will remove the {{}} as well)
$('body').replaceText("MYTITLE","WHATEVER YOU WANT IT REPLACING WITH");
$.fn.replaceText = function(search, replace, text_only) {
return this.each(function(){
var v1, v2, rem = [];
$(this).find("*").andSelf().contents().each(function(){
if(this.nodeType === 3) {
v1 = this.nodeValue;
v2 = v1.replace("{{" + search + "}}", replace );
if(v1!=v2) {
if(!text_only && /<.*>/.test(v2)) {
$(this).before( v2 );
rem.push(this);
}
else this.nodeValue = v2;
}
}
});
if(rem.length) $(rem).remove();
});
};
You could avoid jQuery altogether if you wanted to with something like this:
<body>
<p><strong>
<ul>
<li>text {{TEXT}}</li>
</ul>
</strong></p>
{{ANOTHER}}
<hr/>
<div id="showResult"></div>
<script>
var body = document.getElementsByTagName('body')[0].innerHTML;
var startIdx = 0, endIdx = 0, replaceArray = [];
var scriptPos = body.indexOf('<script');
while (startIdx != 1) {
startIdx = body.indexOf('{{', endIdx) + 2;
if(startIdx > scriptPos){
break;
}
endIdx = body.indexOf('}}', startIdx);
var keyText = body.substring(startIdx, endIdx);
replaceArray.push({"keyText": keyText, 'startIdx': startIdx, 'endIdx': endIdx});
}
document.getElementById("showResult").innerHTML = JSON.stringify(replaceArray);
</script>
</body>
You can then do what you want with the replaceArray.
Related
I want to prompt user to enter a tag and it will list it in the console.log and will ask again until they type "quit". if that happens then I will use the documentwrite to list in the innertext what the previous tags been searched for.
var selector = prompt("Please enter a selector: ");
var selectorr = document.getElementsByTagName(selector);
var breaker = "quit";
breaker = false;
var textlogger = "elements have been found that match the selector ";
var lengthfinder = selectorr.length;
while(true) {
console.log(lengthfinder + textlogger + selector);
if (selector == breaker) {
for (var i=0; i<divs.length; i++) {
document.write.innerText(textlogger);
}
}
}
If you wanna try jQuery and something fun, take this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Loop with jquery deferred</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
var loop = function () {
return $.Deferred(function (deferred) {
var selector = prompt("Please enter a selector: ");
var quit = 'quit';
var selectors = [];
while (selector && selector != quit) {
selectors.push(selector);
var elements = $(selector);
console.log(elements.length + " elements have been found that match the selector " + selector);
selector = prompt("Please enter a selector: ");
}
if (selector)
{
deferred.resolve(selectors);
}
else
{
deferred.reject();
}
}).promise();
};
$(function () {
loop().done(function (selectors) {
$($.map(selectors, function (item, index) {
return '<div>' + item + '</div>';
}).join('')).appendTo($('body'));
});
});
</script>
</head>
<body>
<div>
<iframe src="http://stackoverflow.com/questions/40392515/will-this-loop-correctly-and-be-able-to-list-tag-names"/>
</div>
</body>
</html>
Here is the version with comments and suggestions on where to put your necessary code for it to work.
Code Preview
var breaker = "quit",
textlogger = "elements have been found that match the selector ",
textList = new Array();
while (true) {
var selector = prompt("Please enter a selector: ");
if (selector == breaker) {
/*
Write your necessary output here
*/
/*
After output you break out
*/
break;
} else {
/*
Write It inside list
*/
textList.push(selector);
}
/*
Write necessary output in console
*/
console.log(selector);
}
I want to prompt user to enter a tag and it will list it in the
console.log and will ask again until they type "quit"
while ("quit" !== prompt("Tag name selector, type `quit` to exit", "quit")) {
console.log("in loop");
}
console.log("exit loop");
I will use the documentwrite to list in the innertext what the
previous tags been searched for.
Either you use: document.write("some text") to append to existing dom or you can use selectorr[i].innerText="some text"
Here is my small example that might help you:
var selector;
while ("quit" !== (selector = prompt("Tag name selector. Use `quit` to cancel search", "quit"))) {
var elements = document.getElementsByTagName(selector);
var count = elements.length;
while (count--) {
elements[count].innerHTML += " [matched]";
}
}
<span>This is my <span> tag 1</span>
<p>This is my <p> tag 1</p>
<div>This is my <div> tag 2</div>
<p>This is my <p> tag 3</p>
<span>This is my <span> tag 2</span>
I know there are many similar questions posted, and have tried a couple solutions, but would really appreciate some guidance with my specific issue.
I would like to remove the following HTML markup from my string for each item in my array:
<SPAN CLASS="KEYWORDSEARCHTERM"> </SPAN>
I have an array of json objects (printArray) with a printArray.header that might contain the HTML markup.
The header text is not always the same.
Below are 2 examples of what the printArray.header might look like:
<SPAN CLASS="KEYWORDSEARCHTERM">MOST EMPOWERED</SPAN> COMPANIES 2016
RECORD WINE PRICES AT <SPAN CLASS="KEYWORDSEARCHTERM">NEDBANK</SPAN> AUCTION
I would like the strip the HTML markup, leaving me with the following results:
MOST EMPOWERED COMPANIES 2016
RECORD WINE PRICES AT NEDBANK AUCTION
Here is my function:
var newHeaderString;
var printArrayWithExtract;
var summaryText;
this.setPrintItems = function(printArray) {
angular.forEach(printArray, function(printItem){
if (printItem.ArticleText === null) {
summaryText = '';
}
else {
summaryText = '... ' + printItem.ArticleText.substring(50, 210) + '...';
}
// Code to replace the HTML markup in printItem.header
// and return newHeaderString
printArrayWithExtract.push(
{
ArticleText: printItem.ArticleText,
Summary: summaryText,
Circulation: printItem.Circulation,
Headline: newHeaderString,
}
);
});
return printArrayWithExtract;
};
Try this function. It will remove all markup tags...
function strip(html)
{
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Call this function sending the html as a string. For example,
var str = '<SPAN CLASS="KEYWORDSEARCHTERM">MOST EMPOWERED</SPAN> COMPANIES 2016';
var expectedText = strip(str);
Here you find your expected text.
It can be done using regular expressions, see below:
var s1 = '<SPAN CLASS="KEYWORDSEARCHTERM">MOST EMPOWERED</SPAN> COMPANIES 2016';
var s2 = 'RECORD WINE PRICES AT <SPAN CLASS="KEYWORDSEARCHTERM">NEDBANK</SPAN> AUCTION';
function removeSpanInText(s) {
return s.replace(/<\/?SPAN[^>]*>/gi, "");
}
$("#x1").text(removeSpanInText(s1));
$("#x2").text(removeSpanInText(s2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
1 ->
<span id="x1"></span>
<br/>2 ->
<span id="x2"></span>
For more info, see e.g. Javascript Regex Replace HTML Tags.
And jQuery is not needed, just used here to show the output.
I used this little replace function:
if (printItem.Headline === null) {
headlineText = '';
}
else {
var str = printItem.Headline;
var rem1 = str.replace('<SPAN CLASS="KEYWORDSEARCHTERM">', '');
var rem2 = rem1.replace('</SPAN>', '');
var newHeaderString = rem2;
}
I'd like to be able to target (and then remove) this string of text:
[UPLOAD]any-possible_FILEname.ANY[/UPLOAD]
HTML:
var filenameRegex = new RegExp("\w\d\.");
$('.posts').contents().filter(':contains([UPLOAD])').filter(':contains([/UPLOAD])').filter(function() {
return filenameRegex.test($(this).text());
console.log('yep');
}).remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="posts">
This is a forum post with lots of blabbing in it.
[UPLOAD]this-is-a-random-unknown-filename.jpg[/UPLOAD]
(Note the above always begins with [UPLOAD] and ends
with [/UPLOAD]. Also note that between these 'tags'
is 1 filename of some kind, such as an image or audio
or text file)
</span>
Thanks, much obliged.
var filenameRegex = /\[UPLOAD][\w\.\-]+\[\/UPLOAD]/gi;
$('.posts').filter(':contains([UPLOAD]):contains([/UPLOAD])').filter(function(i,e) {
return filenameRegex.test($(e).text());
}).each(function(i,e){
$(e).text($(e).text().replace(filenameRegex,''));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="posts">
This is a forum post with lots of blabbing in it.
[UPLOAD]this-is-a-random-unknown-filename.jpg[/UPLOAD]
(Note the above always begins with [UPLOAD] and ends
with [/UPLOAD]. Also note that between these 'tags'
is 1 filename of some kind, such as an image or audio
or text file)
</span>
The regex you need is:
/\[UPLOAD\](.*)\[\/UPLOAD\]/gi
So your code should be like:
var filenameRegex = new RegExp("/\[UPLOAD\](.*)\[\/UPLOAD\]/gi");
$('.posts').contents().filter(':contains([UPLOAD])').filter(':contains([/UPLOAD])').filter(function(){
return filenameRegex.test($(this).text());
console.log('yep');
}).remove();
Not a regular expression, but this seems to do the trick:
var text = 'hello [UPLOAD]very[/UPLOAD] [UPLOAD]cruel[/UPLOAD] world';
var start = '[UPLOAD]';
var end = '[/UPLOAD]';
var index = text.indexOf(start);
while (index > -1)
{
var end_index = text.indexOf(end);
var removed_text = text.substring(index, end_index + end.length));
text = text.substring(0, index) + text.substring(end_index + end.length);
index = text.indexOf(start);
}
I am trying to get the inner text of HTML string, using a JS function(the string is passed as an argument). Here is the code:
function extractContent(value) {
var content_holder = "";
for (var i = 0; i < value.length; i++) {
if (value.charAt(i) === '>') {
continue;
while (value.charAt(i) != '<') {
content_holder += value.charAt(i);
}
}
}
console.log(content_holder);
}
extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>");
The problem is that nothing gets printed on the console(*content_holder* stays empty). I think the problem is caused by the === operator.
Create an element, store the HTML in it, and get its textContent:
function extractContent(s) {
var span = document.createElement('span');
span.innerHTML = s;
return span.textContent || span.innerText;
};
alert(extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>"));
Here's a version that allows you to have spaces between nodes, although you'd probably want that for block-level elements only:
function extractContent(s, space) {
var span= document.createElement('span');
span.innerHTML= s;
if(space) {
var children= span.querySelectorAll('*');
for(var i = 0 ; i < children.length ; i++) {
if(children[i].textContent)
children[i].textContent+= ' ';
else
children[i].innerText+= ' ';
}
}
return [span.textContent || span.innerText].toString().replace(/ +/g,' ');
};
console.log(extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>. Nice to <em>see</em><strong><em>you!</em></strong>"));
console.log(extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>. Nice to <em>see</em><strong><em>you!</em></strong>",true));
One line (more precisely, one statement) version:
function extractContent(html) {
return new DOMParser()
.parseFromString(html, "text/html")
.documentElement.textContent;
}
textContext is a very good technique for achieving desired results but sometimes we don't want to load DOM. So simple workaround will be following regular expression:
let htmlString = "<p>Hello</p><a href='http://w3c.org'>W3C</a>"
let plainText = htmlString.replace(/<[^>]+>/g, '');
use this regax for remove html tags and store only the inner text in html
it shows the HelloW3c only check it
var content_holder = value.replace(/<(?:.|\n)*?>/gm, '');
Try This:-
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
function extractContent(value){
var div = document.createElement('div')
div.innerHTML=value;
var text= div.textContent;
return text;
}
window.onload=function()
{
alert(extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>"));
};
</script>
</body>
</html>
For Node.js
This will use the jsdom library, since node.js doesn't have dom features as in browser.
import * as jsdom from "jsdom";
const html = "<h1>Testing<h1>";
const text = new jsdom.JSDOM(html).window.document.textContent;
console.log(text);
Use match() function to bring out HTML tags
const text = `<div>Hello World</div>`;
console.log(text.match(/<[^>]*?>/g));
You could temporarily write it out to a block level element that is positioned off the page .. some thing like this:
HTML:
<div id="tmp" style="position:absolute;top:-400px;left:-400px;">
</div>
JavaScript:
<script type="text/javascript">
function extractContent(value){
var div=document.getElementById('tmp');
div.innerHTML=value;
console.log(div.children[0].innerHTML);//console out p
}
extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>");
</script>
Using jQuery, in jQuery we can add comma seperated tags.
var readableText = [];
$("p, h1, h2, h3, h4, h5, h6").each(function(){
readableText.push( $(this).text().trim() );
})
console.log( readableText.join(' ') );
you need array to hold values
function extractContent(value) {
var content_holder = new Array();
for(var i=0;i<value.length;i++) {
if(value.charAt(i) === '>') {
continue;
while(value.charAt(i) != '<') {
content_holder.push(value.charAt(i));
console.log(content_holder[i]);
}
}
}
}extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>");
I have a definition list with associated variables and their values. (see fiddle too)
<dl id="myVars">
<dt class="var-name">%name%</dt>
<dd class="var-name">Joe Sample</dd>
<dt class="var-phone">%phone%</dt>
<dd class="var-phone">555-1212</dd>
</dl>
I also have a textarea that one can use any of the above variables within their text. For example:
<textarea>Hello %name%, is this still the right phone number: %phone%?</textarea>
Finally there's a preview div where one can see the interpreted text after the variables are replaced. Like so:
<div id="preview"></div>
Can you help me come up with an efficient way to use jQuery to show live previews at the same time it replaces variables with their values?
Here's a handy fiddle if you're up for helping: http://jsfiddle.net/XAzZr/
http://jsfiddle.net/NFtVc/
var subst = {}, // store substitutions in an object to eliminate DOM lookups
substRegex = /(.*)%(\S*)%(.*)$/i;
function defineSubst(){
$("#myVars dd").each(function(){
var cls = this.className.split(' '),
l = cls.length;
while (l--){
if (cls[l].indexOf('var-') == 0)
subst[cls[l].replace(/var-/, "")] = this.innerHTML;
}
});
}
function getSubst(key){
if (typeof subst[key] == "undefined")
return "[INVALID CODE]";
else
return subst[key];
}
function updatePreview(){
var txt = $('textarea').val().split(' '),
newTxts = [],
regex = /(.*)%(\S*)%(.*)$/i;
$.each(txt, function(){
var m = substRegex.exec(this);
if (m)
newTxts.push(m[1] + getSubst(m[2]) + m[3]);
else
newTxts.push(this);
});
$("#preview").text(newTxts.join(' '));
}
$('document').ready(defineSubst);
$('textarea').keyup(updatePreview);
$('textarea').on('keyup', function() {
var message = this.value.replace(/%(.*?)\S+/g, function(val) {
var elem = $('dt').filter(function() {
return $(this).text() == val;
});
return elem.length ? elem.next('dd').text() : '';
});
$('#preview').text(message);
});
FIDDLE