I have some javascript variable in which it has html script something like below:
<div style="display: inline-block;" class="ms-fontColor"><i title="Sample Text"></i></div>
I want to read just the text that is inside the title tag using javascript or JQuery and get rid of everything else. Is there any way that I can achieve this?
const el = document.createElement( 'div' );
el.innerHTML = `<div style="display: inline-block;" class="ms-fontColor"><i title="Sample Text"></i></div>`;
// If there are more than one <i> elements with title attribute you might wanna do this
const innerEls = el.querySelectorAll('i[title]')
innerEls.forEach(el => {
const value = el.getAttribute('title') // or el.title
})
// If you just want to get the only or the first <i> with title attribute
const innerEl = el.querySelector('i[title]')
//Here's the attribute value
const value = innerEl.getAttribute('title') // or innerEl.title
You can use a DOMParser.
let str = '<div style="display: inline-block;" class="ms-fontColor"><i title="Sample Text"></i></div>';
let doc = new DOMParser().parseFromString(str, "text/html");
console.log(doc.querySelector('i[title]').title);
It took me a second to realize you meant get the title from an HTML String instead of from actual DOM elements. This will convert the string to an html element for jquery:
var $elem = $(document.createElement(htmlString));
var title = $elem.is("[title]")
? $elem.prop("[title]")
: $elem.find("[title]").prop("title");
A simple regex can help with this.
const str = '<div style="display: inline-block;" class="ms-fontColor"><i title="Sample \"Text"></i></div>';
const reg = /title=('|")(.*)\1/;
console.log(str.match(reg)[2]);
There are a few methods you can employ to achieve this some of which depend on the structure of your HTML string. The second approach below works for irrespective of what the structure of your HTML string is.
const str = '<div style="display: inline-block;" class="ms-fontColor"><i title="Sample Text"></i></div><div style="display: inline-block;" class="ms-fontColor"><i title="Sample Text 2"></i></div><div style="display: inline-block;" class="ms-fontColor"><i title="Sample Text 3"></i></div>';
const titles = $(str).find('i[title]').map((index, elem) => elem.title).get();
console.log( titles );
//When the i element is at the top of the hierarchy
const str1 = '<i title="Sample Text"></i><i title="Sample Text 2"></i><i title="Sample Text 3"></i><i title="Sample Text 4"></i><div title="This other sample too">watch this</div>'
//approach 1
const t1 = $(str1).filter('i[title]').map((index, elem) => elem.title).get();
console.log( t1 );
//this approach would not work for `str`
//approach 2
const t21 = $('<div/>').append(str1).find('i[title]').map((index, elem) => elem.title).get();
console.log( t21 );
//this would work for `str` as well
const t22 = $('<div/>').append(str).find('i[title]').map((index, elem) => elem.title).get();
console.log( t22 );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Get the element using querySeletor and on that object just fetch the title using iElement.title
const iElement = document.querySelector("i");
const title = iElement.title;
console.log( title );
<div style="display: inline-block;" class="ms-fontColor">
<i title="Sample Text"></i>
</div>
Related
This code is working fine as expected.
index.html
<div id="sliderContent">
<div class="item" id="item-1">
<img src="images/image1.jpg">
</div>
</div>
<template id="sliderItem">
<div class="item">
<img src="dummy_image.jpg">
</div>
</template>
scripts.js
const next = document.querySelector("#next");
const sliderContent = document.querySelector("#sliderContent");
next.addEventListener('click', () => {
const sliderItem = document.querySelector("#sliderItem");
const moreImages = ['image2.jpg', 'image3.jpg', 'image4.jpg'];
// Create a DocumentFragment first
const moreImagesHTML = document.createDocumentFragment();
moreImages.forEach((item) => {
const sliderItemClone = sliderItem.content.cloneNode(true);
const sliderImage = sliderItemClone.querySelector('img');
sliderImage.src = `images/${item}`;
// Append each item to the DocumentFragment
moreImagesHTML.append(sliderItemClone);
});
// Finally append DocumentFragment to
sliderContent.append(moreImagesHTML);
I am not sure if this is valid and standard way in JS. I am appending the content of the template which is already a DocumentFragment to another DocumentFragment i.e. moreImagesHTML. Is Valid in JS?
I want to assign array elements to multiple divs which also have image tag in them using for loop.
Array consists of image paths.
var img_list = ["one.png", "two.png", "three.png", "four.png"];
By using above array I have to create below HTML Structure. All divs should be inside "outer" div with a data-slide attribute which is without ".png".
<div id="outer">
<div class="slide" data-slide="one"><img src="Images/one.png" /></div>
<div class="slide" data-slide="two"><img src="Images/two.png" /></div>
<div class="slide" data-slide="three"><img src="Images/three.png" /></div>
<div class="slide" data-slide="four"><img src="Images/four.png" /></div>
</div>
This is what I wrote:
for (var i=0; i < img_list.length; i++){
var container = document.getElementById("outer").innerHTML;
var new_card = "<div class=\"slide\" data-slide=\'" + img_list[i] + "\'><img src=\'Images/" + img_list[i] + "\' /></div>";
document.getElementById("outer").innerHTML = new_card;
}
But it is only showing the last image.
Please help.
Each time your for loop runs, it is replacing the html element within the "outer" div with the current img html.
In order to have it append you can simply change
document.getElementById("outer").innerHTML = new_card;
to
document.getElementById("outer").innerHTML += new_card; so that the element is appended rather than overwritten.
The code at the question overwrites the .innerHTML within the for loop by setting .innerHTML to new_card at every iteration of the array. You can substitute .insertAdjacentHTML() for setting .innerHTML. Also, substitute const for var to prevent new_card from being defined globally. Include alt attribute at <img> element. You can .split() img_list[0] at dot character ., .shift() the resulting array to get word before . in the string img_list[i] to set data-* attribute value.
const img_list = ["one.png", "two.png", "three.png", "four.png"];
for (let i = 0, container = document.getElementById("outer"); i < img_list.length; i++) {
const src = img_list[i];
const data = src.split(".").shift();
const new_card = `<div class="slide" data-slide="${data}"><img src="Images/${src}" alt="${data}"/></div>`;
container.insertAdjacentHTML("beforeend", new_card);
}
<div id="outer"></div>
You are changing the innerHTML you need to add to it. And use Template literals for creating html strings
var img_list = ["one.png", "two.png", "three.png", "four.png"];
const outer = document.getElementById('outer')
img_list.forEach(img => {
outer.innerHTML += `<div class="slider" data-slide="${img.split('.')[0]}"><img src="Images/${img}" /></div>`
})
console.log(outer.innerHTML)
<div id="outer">
</div>
#Tony7931, please replace the last line of for loop with below code:
document.getElementById("outer").innerHTML += new_card;
You are almost there but, every time you are overriding the slider div.
You just have to add + at assignments section. like below.
document.getElementById("outer").innerHTML += new_card;
Here is the full example:
var img_list = ["one.png", "two.png", "three.png", "four.png"];
for (var i=0; i < img_list.length; i++){
var container = document.getElementById("outer").innerHTML;
var new_card = "<div class=\"slide\" data-slide=\'" + img_list[i].split('.')[0] + "\'><img src=\'Images/" + img_list[i] + "\' /></div>";
document.getElementById("outer").innerHTML += new_card;
}
<div id="outer"></div>
You could also use map method of array and Element.innerHTML to get the required result.
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
Demo
const img_list = ["one.png", "two.png", "three.png", "four.png"];
let result = img_list.map((v, i) => `<div class="slide" data-slide="${v.split(".")[0]}"><img src="Images/${v}"/>${i+1}</div>`).join('');
document.getElementById('outer').innerHTML = result;
<div id="outer"></div>
You can declare your variables outside of the loop and reuse them. This is more efficient.
const and let are preferable to var. You only need to set container once so it can be const. new_card should be let since you need to assign it more than once.
You can also use template string so you don't need all the back slashes.
using forEach will make the code cleaner:
const img_list = ["one.png", "two.png", "three.png", "four.png"];
const container = document.getElementById("outer")
let new_card;
img_list.forEach(i => {
new_card = `<div class=slide data-slide='${i.split(".")[0]}'><img src='Images/${i}'></div>`
container.innerHTML += new_card;
})
<div id="outer">
</div>
Alternately, using reduce:
const img_list = ["one.png", "two.png", "three.png", "four.png"];
const container = document.getElementById("outer")
const reducer = (a, i) => a + `<div class=slide data-slide='${i.split(".")[0]}'><img src='Images/${i}'></div>`
container.innerHTML = img_list.reduce(reducer, '')
<div id="outer">
</div>
I'm writing a code where in there is a json given and out of the key value pairs of json I need to create HTML divs.
Here is my HTML
<div id="col-md-12">
</div>
<input type="button" onclick="addDivs()" />
and my JS
function addDivs() {
var jsonInput = {
'a': '1',
'b': '2'
}
var colDiv = document.getElementById("col-md-12");
var row = document.createElement("div");
row.className = "row";
Object.keys(jsonInput).forEach(function(k) {
var string = k;
var range = jsonInput[k];
var col4Div = document.createElement("div");
col4Div.className = "col-md-4 icon-plus";
var alcohol = document.createElement("span");
alcohol.className = string;
var strong = document.createElement("strong");
strong.innerHTML = string;
var dropDownArrow = document.createElement("span");
dropDownArrow.className = "down-arrow";
alcohol.innerHTML = strong;
alcohol.innerHTML = dropDownArrow;
alcohol.innerHTML = "<br/>";
alcohol.innerHTML = range;
col4Div.innerHTML = alcohol;
row.innerHTML = col4Div;
});
colDiv.innerHTML=row;
}
when I click the button, it gives me message as [object HTMLDivElement] and in console it shows no error.
I'm really confused on what's going on in the backend. My expected output is
<div class="col-md-12">
<div class="row">
<div class="col-md-4 icon-plus">
<span class="a">
<strong>a</strong>
<span class="down-arrow"></span>
<br /> 1</span>
</div>
<div class="col-md-4 icon-plus">
<span class="b">
<strong>b</strong>
<span class="down-arrow"></span>
<br /> 2</span>
</div>
</div>
</div>
please let me know where am I going wrong and how can I fix it.
Here is a working fiddle. https://jsfiddle.net/p9e7cLg9/1/
Thanks
innerHTML deals in strings (of HTML source code). createElement deals in DOM nodes.
When you convert a DOM node to a string, you get "[object HTMLDivElement]", which isn't useful, so don't do that.
Use the appendChild method to add a DOM node as a child of an existing HTML element.
I use the querySelector in JS to select html markup that I filled in with a JS script. However, anytime I try to store the divs with a class of .card in the const questionCard, I get null.
Why can't I select the cards?
HTML:
<div class='card-container'></div>
JS:
const questionBlock = document.querySelector('.card-container');
const questionCard = document.querySelector('.card');
function build() {
let output = [];
...some unimportant code here...
output.push(
`
<div class='card'>
<div class='question'>${current.question}</div>
<div class='answers'>${answers.join('')}</div>
</div>
`
);
})
questionBlock.innerHTML = output;
}
build();
You need to call document.querySelector('.card') after calling build(). It cannot find HTML elements that do not exist yet.
const questionBlock = document.querySelector('.card-container');
function build() {
let output = [];
...some unimportant code here...
output.push(
`
<div class='card'>
<div class='question'>${current.question}</div>
<div class='answers'>${answers.join('')}</div>
</div>
`
);
})
questionBlock.innerHTML = output;
}
build();
const questionCard = document.querySelector('.card');
An alternative to the more correct answers is:
const questionCard = document.getElementsByClassName('card');
now: questionCard is a live HTMLCollection, and questionCard[0] will be the first element with class including card
I am getting a variable which value always follows this format:
"<div>
</div>
<div>
<span style="font-family:tahoma,geneva,sans-serif;"><span>VALUE 1</span></span></div>
<div>
<strong><span style="font-family:tahoma,geneva,sans-serif;">VALUE 2</span></strong></div>
<div>
<span style="font-family:tahoma,geneva,sans-serif;"> </span>VALUE 3</div>
"
How can I get VALUE 1, VALUE 2 and VALUE 3 using JavaScript (not jQuery or other libs)?
NB:
in Console, I get those values (I call them b)
typeof(b) returns string
The most simplest way using jQuery.
var a = '<div>\
</div>\
<div>\
<span style="font-family:tahoma,geneva,sans-serif;"><span>VALUE 1</span></span></div>\
<div>\
<strong><span style="font-family:tahoma,geneva,sans-serif;">VALUE 2</span></strong></div>\
<div>\
<span style="font-family:tahoma,geneva,sans-serif;">au </span>VALUE 3</div>'
var HTML = $.parseHTML(a)
var val1 = $(HTML[1]).find('span span').text()
var val2 = $(HTML[2]).find('span').text()
$(HTML[3]).find('span').remove()
var val3 = $(HTML[3]).text()
console.log(val1, val2, val3)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Use Array#map and then Array#filter
innerHTML the string to a temp element and use DOM-api to manipulate data.
Use 'span[style]' selector to get only those span elements having style attribute.
var str = '<div>\
</div>\
<div>\
<span style="font-family:tahoma,geneva,sans-serif;"><span>VALUE 1</span></span>\
</div>\
<div>\
<strong><span style="font-family:tahoma,geneva,sans-serif;">VALUE 2</span></strong></div>\
<div>\
<span style="font-family:tahoma,geneva,sans-serif;">VALUE 3</span></div>';
var div = document.createElement('div');
div.innerHTML = str;
var spanElems = div.querySelectorAll('span[style]');
var spans = [].map.call(spanElems, function(el) {
return el.textContent.trim();
}).filter(Boolean);
console.log(spans);
You can save the string as a variable, and then use htmlString.match(/VALUE \d+/gmi)
Update:
If the input is a valid HTML string you could parse with this trick (not jQuery or other libs):
var your_string = `<div> </div><div><span style="font family:tahoma,geneva,sans-serif;"><span>VALUE 1</span>fgfgfg</span></div><div><strong><span style="font-family:tahoma,geneva,sans-serif;">VALUE 2</span></strong></div><div><span style="font-family:tahoma,geneva,sans-serif;"> </span>VALUE 3</div>`
var obj_evaluator = document.createElement("div");
obj_evaluator.innerHTML = your_string;
// get the list of div
var list_div = obj_evaluator.getElementsByTagName('div');
var value1 = (list_div[1].firstChild.firstChild.textContent); //value 1
var value2 = (list_div[2].firstChild.firstChild.textContent); //value 2
var value3 = (list_div[3].lastChild.textContent); //value 3
// create an array
var result = [value1,value2,value3]
// print result
console.log(result);
Old answer (wrong because of the VALUE 3,but if all the VALUE are inside the 'span' then this is the right answer! ):
var obj_evaluator = document.createElement("div");
obj_evaluator.innerHTML = your_string;
// debug row
console.log(obj_evaluator);
var list_span = obj_evaluator.getElementsByTagName('span');
for (var i = 0; i < list_span.length; i++) {
console.log(list_span[i].innerHTML);
// here you can print other info of the node
}