I've got a HTML-string I'd like to render but append some HTML after the 2nd paragraph first.
function insertStuff() {
//var string = "<div><p>paragraph 1</p><p>paragraph 2</p><p>paragraph 3</p></div>"; works
var string = '<p><img src="http://example.com/my-cool-picture.png" alt="alt text"></p><p>2nd paragraph</p><p>3rd paragrpah</p>' // doesn't work
var parsedHtml = $(string)
parsedHtml.find("p:nth-child(2)").after("<p>My cool insert</p>")
return parsedHtml.html()
}
This works for the HTML string above but the following one only return the <img> after invoking parsedHtml.html()
What am I doing wrong?
Since you are use .html() it will return html of first element.
You can wrap your content in a div like
var parsedHtml = $('<div />').html(string)
Then your code will work.
function insertStuff() {
var string = '<p><img src="http://example.com/my-cool-picture.png" alt="alt text"></p><p>2nd paragraph</p><p>3rd paragrpah</p>'
var parsedHtml = $('<div />').html(string)
parsedHtml.find("p:nth-child(2)").after("<p>My cool insert</p>")
return parsedHtml.html()
}
alert(insertStuff())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Try this
function insertStuff() {
var string = '<div><p><img src="http://example.com/my-cool-picture.png" alt="alt text"></p><p>2nd paragraph</p><p>3rd paragrpah</p></div>';
var parsedHtml = $(string)
parsedHtml.find("p:nth-child(2)").after("<p>My cool insert</p>")
return parsedHtml.html()
}
You should put this string in a div as parent.
That's because html method as getter returns html content of the first element in the set. You should either wrap all the top-level elements in the set with another element and read it's html content or iterate through the set and concatenate each element's outerHTML property.
parsedHtml.map(function() { return this.outerHTML; }).get().join('');
If you want to get the innerHTML of all the elements in the set, replace outerHTML with innerHTML.
when you use find() with a selector it will search inside that selector (in child nodes) that why when you use string with div tag you are getting the desired result and when you delete div the problem occured
Related
I have this string that can represent two things either some text or an anchor tag with text. I wrote something to always return the text like follows:
$(text).is('a') ? $(text).text() : text;
My logic is that if text is an anchor tag ? return the content of the anchor tag : if it's not then it's already just text so return that.
My question is that why does the following expression return true:
$('a').is('a');
Is is checking for the letter or anchor element? How can I check if my text is an anchor tag.
I would prefer not using any regular expressions
Edit:
I have a variable x that can have these values:
x = 'some text' or x = '<a>some text</a>'
How can I always extract the text from my variable x.
'a' is a valid query selector. It will select all the anchor elements in your document. So $('a').is('a') is saying "find anchor tags in the document and tell me if they are anchor tags" -- this will always be true unless there are no anchor tags in your document.
I have this string that can represent two things either some text or an anchor tag with text. I wrote something to always return the text like follows:
$(text).is('a') ? $(text).text() : text;
My logic is that if text is an anchor tag ? return the content of the anchor tag : if it's not then it's already just text so return that.
If possible, I would avoid having text be vague like that.
You certainly can't just dump the text into $() and assume all will be well. For instance, $("Some text here") searches the DOM for elements with the tag here inside elements with the tag text inside elements with the tag Some.
You've said you want to differentiate between
text = "Some text here"
and
text = "<a>Some text here</a>"
I'd just look at the string. Inspired partially by jQuery's check for whether what you pass it is a selector or HTML (here), how about:
text = text.trim();
if (text.substring(0, 2) === "<a" && text.substr(-1) === ">") {
text = $(text).text();
}
or similar?
But again, I'd avoid putting myself in this position in the first place if you have any choice.
Just set the string you have to an element's html. Grab the text of the element and this way you do not worry about if it is an anchor or plain text.
function getText (content) {
var div = document.createElement("div")
div.innerHTML = content
return div.textContent
}
console.log('some text', getText('some text'))
console.log('<a>some text</a>', getText('<a>some text</a>'))
If you want to use jQuery
function getText (content) {
return $("<div></div>", {html: content}).text()
}
console.log('some text', getText('some text'))
console.log('<a>some text</a>', getText('<a>some text</a>'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I have been unable to replicate the issue as you explained it. Please see: https://api.jquery.com/is/
Here is my testing:
$(function() {
var tableData = [
"Text 1",
"Text 2",
"<a>Text 3</a>",
"Text 4"
];
function isLink(el) {
return $(el).is("a");
}
var x = [];
$.each(tableData, function(i, s) {
x.push(isLink(s) ? $(s).text().trim() : s);
});
$(".results").html(x.join(", "));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="results"></div>
You can pass Text, Element, or even a jQuery Object to the function.
I have a variable that contains some HTML elements & content:
var data = '<h1>This is a demo element. <span>This is a span.</span></h1><div id="div-element" data-id="1">This is a div.</div>';
What I'd like to do is modify the data-id within the #div-element.
What I've tried so far:
console.log($(data).find('#div-element').attr('data-id'));
This returns undefinied.
data = $.parseHTML(data);
console.log($(data).find('#div-element').attr('data-id'));
Tried to parse the HTML also, but it returns undefinied as well.
What am I missing here?
I'm using jQuery but a Javascript solution is just as good.
The issue is because you're using find() yet there is no root element in the HTML string you're specifying; all the elements are siblings. In this case you can use filter():
var data = '<h1>This is a demo element. <span>This is a span.</span></h1><div id="div-element" data-id="1">This is a div.</div>';
var id = $(data).filter('#div-element').data('id');
console.log(id);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Also note the use of data('id') over attr('data-id').
Create a dummy element div and set data as its innerHTML
var html = `<h1>This is a demo element. <span>This is a span.</span></h1><div id="div-element" data-id="1">This is a div.</div>`;
var div = document.createElement( "div" );
div.innerHTML = html; //set the html string
//change the attribute of the id-Element
div.querySelector( "[id='div-element']" ).setAttribute( "data-id", "2" );
console.log( div.innerHTML );
In this case following will work.
$("<div>" + data + "</div>").find('#div-element').attr('data-id')
I have this html
<div id="items-content">
<p><img class="fr-dib" src="http://i.imgur.com/bEDR9dc.png" data-imgslap="{{image-key}}" style="width: 214px;"></p>
</div>
And i want to replace src="http://i.imgur.com/bEDR9dc.png" with src="http://i.imgur.com/mJyABlG.jpg"
I have the following jquery
$(document).ready(function() {
$('#items-content').html( 'src="http://i.imgur.com/bEDR9dc.png"' ) {
return 'src="http://i.imgur.com/mJyABlG.jpg"';
}
} );
I'm learning JQuery still and I don't know where I have gone wrong. Would appreciate the help.
Update
I plan on using the same method of replacing the image to replace something like data-imgslap= with src=. Basically how do I replace html text 'x' with 'y' (They will only ever be html attributes text being replaced).
Use attr() to solve this problem
$(document).ready(function() { $('#items-content .fr-dib').attr('src', 'http://i.imgur.com/mJyABlG.jpg"'); } );
Or use regular expression
your_string.replace(/(<img\s class\=\"fr-dib\"\ssrc=")(.*?)("\s?\/>)/, "$1http://i.imgur.com/mJyABlG.jpg $3");
Update a DOM img tag's src
You're looking for jQuery's attr() method to update a single attribute's value:
$(document).ready(function() {
$('#items-content .fr-dib').attr('src', 'http://i.imgur.com/mJyABlG.jpg"');
} );
jsfiddle: https://jsfiddle.net/patrickberkeley/0wefe37t/
Update a DOM img src with a value from a data attr
To update one attribute with another attribute's value (in this example updating an image's src with a data attribute's value):
$(document).ready(function() {
var $img = $('#items-content [data-imgslap]');
var newSrc = $img.data('imgslap');
$img.attr('src', 'http://i.imgur.com/' + newSrc + '.jpg"');
} );
jsfiddle: https://jsfiddle.net/patrickberkeley/bx686410/2/
Regex to replace img src in a string
Based on the comments you've left though, it seems like your goal is to a value in a string (rather than updating an img element's src in the DOM).
In order to do that:
var str = '<div id="items-content"><p><img class="fr-dib" src="http://i.imgur.com/bEDR9dc.png" data-imgslap="mJyABlG" style="width: 214px;"></p></div>';
var newSrc = 'http://i.imgur.com/mJyABlG.png';
var newStr = str.replace(/<img(.*)src=[\"|\'](.*?)[\"|\'](.*)/, "<img$1src='" + newSrc + "'$3");
jsfiddle: https://jsfiddle.net/patrickberkeley/qrdt1esz/1/
Notice you *do not $(document).ready() because you're not selecting something from the dom. The above regex should handle: single and double quotes and any combination of attrs on either side of the img's src.
Ok so I want to .map() the src values of the html content of #stage to the variable srcArray
var content = $('#stage').html();
var srcArray = $.map($(content), function(el) {
return {value: $(el).children().attr('src')};
});
but when I console.log the array, each src value comes up as undefined. Anyone know what's up?
html is
<div id="stage">
<div style="left:xxx, top:xxx">
<img src="xxxxx" style="width:xxx, height:xxx"/>
</div>
</div>
Do I need to convert the src value to a string to have it show up on the chrome console?
You could get all the img from the #stage element.
var srcArray = $('#stage').find('img').map(function() {
return { value: $(this).attr('src') };
}).get();
Problem :
1. statement return {value: $(el).children().attr('src')}; Will execute for each children of 'div#stage' but stage also have a
div which doesn't have any src attribute.
2. In case 'div#stage'have multipleimg` elements then above statement will return only one result
3. Statement $(content) creating new html elements .Never create new content if you just want to treverse (A bad practice).
Solution :
1. Filter children so that only img tag will be selected.
2. Map on children('img') so that if there are more than 1 img element,code will be executed for each img
3. Use $('#stage') instead of $(content) (which is creating new html elements)
Try this-
var content = $('#stage').html();
var srcArray = $.map($(content).children("img"), function (el) {//better way use $.map($('#stage').children("img"), function (el) {
return {
value: $(el).attr('src')
};
});
console.log(JSON.stringify(srcArray))
Update:-
DEMO
Well the issue is with your children() selection and reading the attribute. It will read the attribute of the first child. So if the first child does not have the attribute it will be undefined. So you need to actually select the element you want. It is also weird you are selecting the html and than building a nodeset based on that html. Just do the selection and use map
var srcArray = $('#stage [src]').map(
function () {
return { value: $(this).attr('src')};
}
);
Basically I have this kind of tag (just for example)
<div type="text" onclick="event();" onblur="event();">this div has onclick and onblur functions</div>
and I want to remove some attributes to that tag using a reference variable.
var refAttribs = ['onclick', 'onblur'];
So it should strip out all attributes from refAttribs.
Be careful not to strip out the content of the div. Because it also contains a string from the refAttribs variable.
How do I get rid of them using a regex?
Thanks in advance
As you've stated the tag is a string then you could santise it with the following javascript.
var refAttribs = ['onclick', 'onblur'];
function remove(tagToClean)
{
var result = tagToClean;
for(var i=0; i<refAttribs.length; i++)
{
regex = new RegExp(refAttribs[i] + "=\"[a-zA-Z\(\);]*?\"", "g");
result = result.replace(regex, "");
}
return result;
}
You can call the method by passing in your string.
remove('<div type="text" onclick="event();" onblur="event();">this div has onclick and onblur functions</div>');
I'm not 100% sure what you're trying to do here. Are you trying to modify the DOM? If so you will need to modify the method to accept a handle to a DOM node. A little more information would help.
Well, try this:
To remove onclick, the regex will be:
(<[^>]+)\s+onclick\s*=[\'"].*?[\'"]
Debuggex Demo
The removeAttr function:
function removeAttr(html, attr) {
return html.replace(new RegExp('(<[^>]+)\\s+' + attr + '\\s*=[\'"].*?[\'"]', 'gi'), '$1');
}
http://jsfiddle.net/rooseve/pC4aH/1/