Let's say I have the following HTML code
<div class="answers">
He<b>y</b> <span class='doesntmatter'>eve</span>ryone
</div>
And I have the following array:
['correct','correct','incorrect','correct','correct','correct','incorrect','incorrect','correct','correct','incorrect']
I want to transform this piece of HTML code, and add a span to each letter with the class in the array (I'll explain)
So, I want to transform the letter H to say <span class='correct'>H</span>
e to say: <span class='correct'>e</span>
y to say: <span class='incorrect'>y</span>
e to say: <span class='correct'>e</span>
And so on. I want to make sure to keep the original HTML, <br> tags, <p> tags and the such. I can't use jQuery(element).text() for this reason (since it breaks the tags).
Anyone has an idea how I would do this? It's much appreciated.
var arr = ['correct','correct','incorrect','correct','correct','correct','incorrect','incorrect','correct','correct','incorrect'],
answer = document.getElementsByClassName("answers")[0],
rex = /(?=\w|<)(?=[^>]*(?:<|$))/,
i = 0, class;
answer.innerHTML = answer.innerHTML.split(rex).map(function(p) {
if (p.indexOf('>')) return p;
class = arr[i++] || 'notDefined';
return '<span class="' + class + '">' + p + '</span>';
}).join('');
Non-word characters are not wrapped. If the text contains html-entities (e.g ) there will be some extra effort.
How about this:
http://jsfiddle.net/bn777pky/
The jQuery needs refined but it's not my strong suit.
HTML
<div class="numbers">123456789</div>
CSS
.correct {
color: red
}
.incorrect {
color: blue;
}
Jquery
$(".numbers").each(function (index) {
var characters = $(this).text().split("");
$this = $(this);
$this.empty();
$.each(characters, function (i, el) {
$this.append("<span>" + el + "</span");
});
$("span").each( function (index) {
index += 1;
if(index % 3 == 0) {
$(this).addClass("incorrect");
}
else {
$(this).addClass("correct");
}
});
});
Related
I am trying to get the last and first index of a string match. For example:
var text = 'I am a string and this is an image <img src="image.jpeg">';
What I would like to do is get the first index and last index of the match. example I have attempted:
<script>
function getLightBox(text) {
var result = str.match(/<img src="(.*?)>/g).map(function(val){
var res = val.replace(/<\/?img src =">/g,'').replace(/?>/g,'');
var tag1 = text.firstIndexOf((/<img src="(.*?)>/g));
var tag2 = text.lastIndexOf((/<img src="(.*?)>/g));
var anchor1 = '<a href="images/' + res +'" data-lightbox="Christmas">';
var anchor2 = '</a>'
var newString = text.substring(0,tag1) + anchor1 + '<img src="' + res + '">' + anchor2 + text.substring(tag2,text.length);
return newString;
});
</script>
wanted output
I am a string and this is an image <img=src"image.jpeg">
I'm unsure if this is the correct way, it doesnt seem to work for me.
Thanks.
You are almost there, I've made some changes:
The regex pattern needs to have .*? to match lazily up to the next src attribute or the > closing tag.
The method used is String.replace, because it allows to have the full matched image img, and also to have the src matched group () in the second argument.
Using string interpolation `` (backticks) eases the concatenion of the resulting string.
Look the final function:
function getLightBox(text = '') {
return text.replace(/<img.*?src="([^"]+)".*?>/g, (img, src) => {
return `${img}`;
});
}
const element = document.getElementById('myElement');
element.innerHTML = getLightBox(element.innerHTML);
img {
padding: 0 10px;
background-color: yellow;
}
a {
padding: 0 20px;
background-color: red;
}
<div id="myElement">
I am a string and this is an image:
<img id="foo" src="image.jpeg" alt="bar">
</div>
You can play with the regex pattern here:
https://regex101.com/r/79HHrn/1
I have the following HTML string:
<div><p>Hello <b>how are</b> you?</div>
I would like to loop the HTML string DOM and wrap each word with a span tag and the word number as id so result will be like this:
<div><p><span id="word-1">Hello</span> <b><span id="word-2">how</span> <span id="word-3">are</span></b> <span id="word-4">you?</span></div>
I've tried to use the JQuery method $.parseHTML but no luck to count the words because DOM node value can contain more than one word in it..
In addition, if inside the word there is inline tags such <b> / <i> so from DOM point of view each tag has a different node value even when its the same word)
Any idea how to solve this issue? how to count words inside a HTML DOM string?
Thanks
Try this.
HTML
<div id="content">
<div><p>Hello <b>how are</b> you?</div>
</div>
Script
var textNodes = $("#content *").contents().filter(function() {
return this.nodeType === 3;
});
var counter = 1;
for(var i = 0;i<textNodes.length;i++)
{
var val = $(textNodes).eq(i).text();
var words = val.split(" ");
var final = "";
for(var j = 0;j<words.length;j++)
{
if(words[j].trim() != "")
{
final += "<span id='"+ counter +"'>"+ words[j] +" </span>";
counter++;
}
}
$($(textNodes)[i]).replaceWith(final);
}
Jsfiddle Link
As of my understanding of your question this should work.
var allText = $("body").text().replace(/<[^>]*>/g, "");
var words = allText.split(' ');
for(var i=0;i<words.length;i++)
{
$(div).append("<span id = 'word-'"+i+">"+words[i]+"</span>")
}
This question already has answers here:
How to wrap each word of an element in a span tag?
(10 answers)
Closed 6 years ago.
for example i have some HTML elements like below
<p> apple,banana,oranger</p>
and i'd like to use the javascript to make it like
<p>apple</p> <p>banana</p> <p>orange</p>
How may i achieve this?
UPDATE 1:
I am using other methods to do my task due to some reaseon and it looks as like below
var node = document.getElementById('discovereedKeywords');
node.innerHTML = node.innerHTML.replace(/,/g, '<p class="tag-item">');
and in reality those <p> tags are actually generate by a for loop, but my method only change the first node it found therefore i tried
Consider the html looks like this
<p class="discovereedKeywords"> apple,banana,oranger</p>
<p class="discovereedKeywords"> apple,oranger,oranger</p>
<p class="discovereedKeywords"> kiwi,melon,pinapple</p>
Javascript
for (var i=0; i <data.result.data.length; i++){
var node[i] = document.getElementByClassName('discovereedKeywords');
node[i].innerHTML = node.innerHTML.replace(/,/g, '<p class="tag-item">');
}
}
but this those work, why?
Use .split to split the string in array. .join the array in string by concatenating </p></p> in between items. Wrap the string in <p>
$('p').get(0).outerHTML = ('<p>' + $('p').text().split(',').join('</p><p>') + '</p>');
p {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<p>apple,banana,oranger</p>
OR using Array#map without jQuery
var elem = document.getElementById('demo');
elem.outerHTML = elem.textContent.split(',').map(function(el) {
return '<p>' + el + '</p>';
}).join('');
p {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<p id='demo'>apple,banana,oranger</p>
You can do something like this
$('#p').html(function(i, v) {
return '<p class="discovereedKeywords">' + v.split(',').join('</p><p class="discovereedKeywords">') + '</p>'; // update the html content
})
.children() // get children p
.unwrap(); // unwrap the parent p
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="p">apple,banana,oranger</p>
Or use replace() here
$('#p').html(function(i, v) {
return v.replace(/([^,]+)(?:,|$)/g, '<p class="discovereedKeywords">$1</p>')
})
.children() // get children p
.unwrap(); // unwrap the parent p
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="p">apple,banana,oranger</p>
I'm developing a javascript library that animate a div with random chart entry.
I need to trasform every char in to a div with maintain the html format.
What is the most efficiently method to do this?
Example:
<div class="base_container">Hi Elia,<br>what's your name?</div>
into:
<div class="base_container">
<span id="char_1">H</span>
<span id="char_2">i</span>
<span id="char_3"> </span>
<span id="char_4">E</span>
<span id="char_5">l</span>
<span id="char_6">i</span>
<span id="char_7">a</span>
<span id="char_8">,</span>
<br>
<span id="char_9">w</span>
<span id="char_10">h</span>
.
.
.
</div>
Thanks you in advance ! The hardest part is maintain the html format !
Accounts for any tags in HTML formatting, not <br> only:
var i = 0,
div = $('<div class="base_container">Hi Elia,<br>whats your <b>name</b>?</div>');
function processContent(element){
element.contents().each(function(){
if(this.nodeType == 3){
/* it's safe to process text nodes only */
var content = this.textContent;
content = content.replace(/./g, function(a){ return '<span id="char_' + ++i + '">' + a + '</span>'; })
$(this).replaceWith($(content));
}else{
/* recursively process child nodes */
return processContent($(this));
}
});
}
processContent(div);
console.log(div.html());
I'm not going to tell you how to do this since that's not your question. The best way to approach this is to simply:
var elem = document.getElementsByClassName('base_container')[0];
var content = elem.innerHTML;
// Do some crazy stuff with regex and string parsing
elem.innerHTML = content;
Hope that helps.
I would do this that way:
var baseContainer = document.querySelector(".base_container");
var textParts = baseContainer.innerHTML.match(/<[^>]+>|&[a-z0-9]+;|./gi);
baseContainer.innerHTML = textParts.map(function (textPart, index) {
return textPart.length > 1 ? textPart : "<div id='char_" + index + "'>" + textPart + "</div>";
}).join("");
I'm using blogger as my blogging platform. In my blog homepage, I create a function to grab all images from single post for each post (there are 5 posts in my homepage), then append all images from single post to single slider, for each post.
This is my function script (I place it after <body> tag):
<script type='text/javascript'>
//<![CDATA[
function stripTags(s, n) {
return s.replace(/<.*?>/ig, "")
.split(/\s+/)
.slice(0, n - 1)
.join(" ")
}
function rm(a) {
var p = document.getElementById(a);
img = p.getElementsByTagName("img").each( function(){
$(".flexslider .slides").append($("<li>").append(this));
});
p.innerHTML = '<div class="entry-container"><div class="entry-content"><div class="entry-image"><div class='flexslider'><ul class='slides'></ul></div></div><div class="entry-header"><h1>' + x + '</h1></div><p>' + stripTags(p.innerHTML, SNIPPET_COUNT) + '</p></div></div>'
}
//]]>
</script>
Then my variable, each post have single variable, different for each post based on it's ID:
<script type='text/javascript'>var x="Post Title",y="http://myblog.url/post-url.html";rm("p8304387062855771110")
My single post markup:
<span id='p8304387062855771110'></span>
The problem is, the append function in my script not work. Am I forget something in my code?
Your jQuery/JavaScript is very ropey. There is no method each on a nodelist. Try not to mix jQuery/JavaScript up so much. And you might consider using a array/join on the html you want to insert to keep the line length readable. That way you might have noticed that your HTML quotes were not consistent.1
var $p = $('#' + a);
$p.find('img').each(function () {
var html = $('<li>').append($(this))
$('.flexslider .slides').append(html);
});
var html = [
'<div class="entry-container"><div class="entry-content">',
'<div class="entry-image"><div class="flexslider">',
'<ul class="slides"></ul></div></div><div class="entry-header">',
'<h1><a href="',
y,
'">',
x,
'</a></h1></div><p>',
stripTags(p.innerHTML, SNIPPET_COUNT),
'</p></div></div>'
].join('');
$p.html(html);
1 Personally I prefer single quotes for JS work and double quotes for HTML attributes and never the twain shall meet.
I think <li> doesnt work try li like this:
$(".flexslider .slides").append($("li").append(this));
You could get rid of type="text/javascript" and //<![CDATA[, it is 2014, after all ;-)
Also, .*? is not what you mean.
<script>
function stripTags(s, n) {
return s.replace(/<[^>]*>/g, "") // Be careful with .*? : it is not correct
.split(/\s+/)
.slice(0, n - 1)
.join(" ")
}
function rm(id) {
var $p = $('#' + id);
img = $p.find("img").each( function(){
$(".flexslider .slides").append($("<li>").append(this));
});
p.innerHTML = '<div class="entry-container"><div class="entry-content"><div class="entry-image"><div class="flexslider"><ul class="slides"></ul></div></div><div class="entry-header"><h1>' + x + '</h1></div><p>' + stripTags(p.innerHTML, SNIPPET_COUNT) + '</p></div></div>'
}
</script>