splitting an html line into separate variables with JS - javascript

In pure javascript (not using JQuery/dojo/etc), what is the best/easiest/quickest way to split a string, such as
var tempString = '<span id="35287845" class="smallIcon" title="time clock" style="color:blue;font-size:14px;" contenteditable="false">cookie</span>';
into
var id = 'id="35287845"';
var class = 'class="smallIcon"';
var title = 'title="time clock"';
var style = 'style="color:blue;font-size:14px;"';
var contenteditable = 'contenteditable="false"';
Things to note:
a "space" cannot be used as a proper delimiter, since it may appear in a value, such as title, above (time clock).
maintaining the double quotes around each variable, such as id="35287845" is important
the opening/closing span tags can be discarded, as well as the content, which in this case, is "cookie"

Here is one approach, which is to place the input string as innerhtml into a javascript created dom element and then leverage the attributes array
//Input html string
var tempString = '<span id="35287845" class="smallIcon" title="time clock" style="color:blue;font-size:14px;" contenteditable="false">cookie</span>';
//make element to contain html string
var tempDiv = document.createElement("div");
//place html string as innerhtml to temp element
tempDiv.innerHTML = tempString;
//leverage attributes array on element
var attributeArray = tempDiv.firstChild.attributes;
//log results
console.log(attributeArray);
Note that you may now do something like
var classString = attributeArray.class;
or
var titleString = attributeArray.title;
Edit
Here is a function that will do it:
function getAttributesFromString(htmlString)
{
var tempDiv = document.createElement("div");
tempDiv.innerHTML = htmlString;
return tempDiv.firstChild.attributes;
}

I think you are trying to get the properties in the span, check this response telling you how to do it.
Get all Attributes from a HTML element with Javascript/jQuery
also you could get the properties and make the string concatenating the the values with your strings.
(You can fin a explanation in pure javascript there)

Related

How can I get the raw value of a text node?

Let's say I have the following:
var div = document.createElement('div');
div.innerHTML = "<";
var nodes = div.childNodes;
console.log(nodes)
then in all fields of nodes[0] (i.e. nodes[0].data, nodes[0].nodeValue, nodes[0].textContent, nodes[0].wholeText) I get <. Can I retrieve the "raw" value of a text node somehow? In this case <. Or is the only option to first retrieve it parsed, and then to escape the html somewhat like this:
function escapeHtml(html) {
var text = document.createTextNode(html);
var div = document.createElement('div');
div.appendChild(text);
return div.innerHTML;
}
Note: I consciously chose childNodes in order to get text-nodes as well as non-text-nodes.

Assigning javascript array elements class or id for css styling

I'm trying to assign class and id to items in an array I created in js and input into my html. I'm doing this so I can style them in my stylesheet. Each item will not be styled the same way.
I'm a beginner so trying to keep it to code I can understand and make it as clean as possible, i.e. not making each of these items an element in the html.
This part works fine:
var pool =['A','B','3','J','R','1','Q','F','5','T','0','K','N','C','R','U']
var letters = pool.join('');
document.getElementById('key').innerHTML = letters;
This part not so much:
var char1 = letters[1];
char1.classList.add('hoverRed');
There is a similar question here that didn't work for me, it just showed [object][object][object] when I ran it.
Your code attempts to apply a style to an array element, but CSS only applies to HTML. If you wish to style one character in a string, that character must be wrapped in an HTML element (a <span> is the best choice for wrapping an inline value).
This code shows how to accomplish this:
var pool =['A','B','3','J','R','1','Q','F','5','T','0','K','N','C','R','U']
var letters = pool.join('');
// Replace a specific character with the same character, but wrapped in a <span>
// so it can be styled
letters = letters.replace(letters[1], "<span>" + letters[1] + "</span>");
// Insert the letters string into the div
var theDiv = document.getElementById('key');
// Inject the string into the div
theDiv.innerHTML = letters;
// Get a reference to the span:
var theSpan = theDiv.querySelector("span");
// Add the style to the <span> that wraps the character, not the character itself
theSpan.classList.add('hoverRed');
.hoverRed {
color:red;
}
<div id="key"></div>
And, this snippet shows how you could apply CSS to any letter:
var pool =['A','B','3','J','R','1','Q','F','5','T','0','K','N','C','R','U'];
// Leave the original array alone so that it can be manipulated any way needed
// in the future, but create a new array that wraps each array element within
// a <span>. This can be accomplished in several ways, but the map() array method
// is the most straight-forward.
var charSpanArray = pool.map(function(char){
return "<span>" + char + "</span>";
});
// Decide which character(s) need CSS applied to them. This data can come from anywhere
// Here, we'll just say that the 2nd and 5th ones should.
// Loop through the new array and on the 2nd and 5th elements, apply the CSS class
charSpanArray.forEach(function(element, index, array){
// Check for the particular array elements in question
if(index === 1 || index === 4){
// Update those strings to include the CSS
array[index] = element.replace("<span>","<span class='hoverRed'>");
}
});
// Now, turn the new array into a string
var letters = charSpanArray.join('');
// For diagnostics, print the string to the console just to see what we've got
console.log(letters);
// Get a reference to the div container
var theDiv = document.getElementById('key');
// Inject the string into the div
theDiv.innerHTML = letters;
.hoverRed {
color:red;
}
<div id="key"></div>
You're on the right track, but missed one key thing.
In your example, pool contains characters. When you combine them using join, you get a string. Setting that string as the innerHTML of an element doesn't give the string super powers, it's still just a string.
In order to get a classList, you need to change your letters into elements and work with them.
I've included an es6 example (and a working plunker) of how to get the functionality you want below.
let pool = ['A','B','3','J','R','1','Q','F','5','T','0','K','N','C','R','U']
const letterToElement = function(char) {
//Create the element
let e = document.createElement("SPAN");
//Create the text node
let t = document.createTextNode(char);
//Put the text node on the element
e.appendChild(t);
//Add the class name you want
e.className += "hoverRed";
return e;
};
//create your elements from your pool and append them to the "key" element
window.onload = function() {
let container = document.getElementById("key");
pool.map(l => letterToElement(l))
.forEach(e => container.appendChild(e));
}
https://plnkr.co/edit/mBhA60aUCEGSs0t0MDGu

jQuery: create html elements from comma separated string?

I'm trying to create HTML elements (div's) from a comma separated string using jQuery.
Lets say I have a string that looks like this:
options ="some texts, another text, some more text";
and I need to create something like this:
<div>some texts</div>
<div>another text</div>
<div>some more text</div>
I first split the comma separated string like so:
var str = options;
var temp = new Array();
temp = str.split(", ");
And then I need to create the div's after this function which I have no idea how to do this.
Could someone please advise on this?
Try this:
var options ="some texts, another text, some more text";
var temp = options.split(", "); // first split string and convert it to array
var str = '';
$.each(temp, function(i,v) { // loop through array
str += "<div>"+v+"</div>"; // create html string and store it in str variable
});
$("body").append(str);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
You can do something like this using jQuery
var options = "some texts, another text, some more text";
var temp = options.split(", ");
// iterate and generate array of jQuery elements
var divs = temp.map(function(txt) {
// generate div using jQuery with text content as array element
return $('<div/>', {
text: txt
})
})
// update html content, use `append()` if you want to append instead of replacing entire content
$('body').html(divs);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You don't need to convert to an array- just replace the commas and associated spaces with a closing div and opening div tag and then add an opening one to start with and a closing one to end with and you have the html structure.
var options ="some texts, another text, some more text";
var temp = "<div>" + options.replace(/, /g,"</div><div>") + "</div>;
//this will give: <div>some texts</div><div>another text</div><div>some more text</div>
$("body").append(temp);
Assuming you want the text interpreted as text, not HTML, you'll want to loop over the array your code gives you and create elements individually, like this:
var options = "some texts, <another> text, some more text";
options.split(", ").forEach(function(opt) {
$("<div>").text(opt).appendTo(document.body);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Note that I changed one of your entries to demonstrate the importance of ensuring they're treated as text, not HTML.
About your code:
var str = options;
var temp = new Array();
temp = str.split(", ");
The call to new Array() is completely unnecessary there, because you're overwriting the value of your temp variable on the very next line. split returns an array, it doesn't fill in one that it magically reaches out and grabs from the left-hand side of the assignment. :-) (There's also no reason to do var str = options; Just use options directly.)
Try this:
<div id="main-div"></div>
<script type = "text/javascript">
var options ="some texts, another text, some more text";
options.split(',').forEach(function(item){
$("#main-div").append("<div>"+item+"</div>");
});
</script>
var str = options;
var temp = str.split(", ").map(function(strOption) {
return '<div>' + strOption + '</div>';
}).join('');
myHTMLElement.innerHTML = $(temp);

JS Regex for a word which is not contained in <a>?

I'm using the following js to highlight the content of searched string in html, but the problem is that this also affects the url string.
var a = new RegExp(keywords, "igm");
container.innerHTML = container.innerHTML.replace(a, "<span style='background:#FF0;'>" + keywords + "</span>");
If the keyword is in the url, then the url will be relaced with xxxx.com/<span style='background:#FF0;'>product</span> which is wrong.
So is there any way to filter out the words that not contained in url? Not sure if there is a RegExp could do this. Thanks in advance.
Here is a block of code that does what you ask:
// prepare the replacement as a function
function do_replacement(node) {
var a = new RegExp(keywords, "igm");
node.innerHTML = node.innerHTML.replace(a,
"<span style='background:#FF0;'>" + keywords + "</span>");
}
// back up the links
var link_backups = new Array();
var link_refs = new Array();
var container_links = container.getElementsByTagName("a");
for (var i = 0; i < container_links.length; i++) {
var copy = container_links[i].cloneNode(true);
// the link target (href) is not contained in the link's innerHTML
// remove this line if you don't want to replace the link's TEXT
do_replacement(copy);
link_backups.push(copy);
link_refs[i] = container_links[i];
}
do_replacement(container);
// restore the backed up links
// (this uses link_refs[] because container_links[] could have changed)
for (var i = 0; i < link_refs.length; i++) {
container.replaceChild(link_backups[i], link_refs[i]);
}
This will (probably) fail if your keywords matches the tag name (<a>) of the links, e.g. when keywords = "a".
However, I'm sure you'll merely run into another instance of HTML code that you don't actually want to replace. JS doesn't really have the best of ways to manipulate just the DOM's text. For example, changing Node.textContent will kill all of the node's HTML content.

Javascript regex to replace text div and < >

var text='<div id="main"><div class="replace">< **My Text** ></div><div>Test</div></div>'
I want to replace div with class="replace" and html entities < > comes inside that div with some other text.
I.e the output :
'<div id="main"> Hello **My Text** Hello <div>Test</div> </div>'
I've tried
var div = new RegExp('<[//]{0,1}(div|DIV)[^><]*>', 'g');
text = text.replace(div, "Hello");
but this will replace all div.
Any help gratefully received!
If a Jquery solution is acceptable:
text = $(text) // Convert HTML string to Jquery object
.wrap("<div />") // Wrap in a container element to make...
.parent() // the whole element searchable
.find("div.replace") // Find <div class="replace" />
.each(function() // Iterate over each div.replace
{
$(this)
.replaceWith($(this).html() // Replace div with content
.replace("<", "<sometext>")
.replace(">", "</sometext>")); // Replace text
})
.end().html(); // return html of $(text)
This sets text to:
<div id="main"><sometext> My Text </sometext><div>Test</div></div>
And to replace it back again:
text = text.replace('<sometext>', '<div class="replace"><')
.replace('</sometext>', '></div>');
http://api.jquery.com/jquery/#jQuery2
http://api.jquery.com/each/
http://api.jquery.com/find/
http://api.jquery.com/html/
In pure JS it will be something like this:
var elements = document.getElementsByClassName('replace');
var replaceTag = document.createElement('replacetext');
for (var i = elements.length - 1; i >= 0; i--) {
var e = elements[i];
e.parentNode.replaceChild(replaceTag, e);
};​
Here is one crazy regex which matches what you want:
var text='<div id="main"><div class="replace">< **My Text** ></div><div>Test</div></div>'
var r = /(<(div|DIV)\s+class\s*?=('|")\s*?replace('|")\s*?>)(\s*?<)(.*?)(>\s*?)(<\/(div|DIV)\s*?>)/g;
The whole replacement can be made with:
text.replace(r, function () {
return 'Hello' + arguments[6] + 'Hello';
});
Please let me know if there are issues with the solution :).
Btw: I'm totally against regexes like the one in the answer...If you have made it with that complex regex there's probably better way to handle the problem...
Consider using the DOM instead; you already have the structure you want, so swap out the node itself (borrowing heavily from #maxwell's code, but moving children around as well):
var elements = document.getElementsByClassName('replace');
for(var i = elements.length-1; i>= 0; --i) {
var element = elements[i];
var newElement = document.createElement('replacetext');
var children = element.childNodes;
for(var ch = 0; ch < children.length; ++i) {
var child = children[ch];
element.removeChild(child);
newElement.appendChild(child);
}
element.parentNode.insertBefore(newElement,element);
element.parentNode.removeChild(element);
}
For each element of the given class, then, it will move each of its children over to the new element before using that element's position to insert the new element and finally removing itself.
My only questionmark is whether the modification of items in the array return by getElementByClassName will cause problems; it might need an extra check to see if the element is valid before processing it, or you may prefer to write this as a recursive function and process the tree from deepest node first.
It may seem like more work, but this should be faster (no re-parsing of the html after you've changed it, element moves are just reference value assignments) and much more robust. Attempting to parsing HTML may damage your health.
Rereading the question (always a good plan), you begin with the text in a string. If that is truly the start point (i.e. you're not just pulling that out of an innerHTML value), then to use the above just create a temporary parent element:
var fosterer = document.createElement('div');
fosterer.innerHTML = text; // your variable from the question
And then proceed using fosterer.getElementsByClassName.

Categories

Resources