Best way to search for elements in innerHTML - javascript

I'm using innerHTML to get the inner HTML of an li element that is clicked. I would then like to search that HTML for some paragraph tags and find their value, is there a good way to do that? I can't rewrite any of the list's HTML, that's being generated elsewhere in the project but I do know the class names used for the tags. jQuery answers are fine.

The best way to 'search' the HTML is to use the DOM. Note that if the container element in which you want to search exists in your DOM already, you do not need to contruct a new dummy element and can just retrieve this parent node and use the same approach.
var el = document.createElement('div'),
someHtmlToSearch = '<div><p>test content in p</p></div>',
pContent;
el.innerHTML = someHtmlToSearch;
pContent = el.querySelector('p').innerHTML; //search for the first p tag
console.log(pContent); //test content in p

Using jQuery:
// Attach onclick listener to li items of interest
$("your-li-selector").on('click', function () {
// Select all p tags within the clicked element
var pTags = $('p', this);
// Iterate over all p tags
pTags.each(function () {
// Do search actions with `this.innerHtml` or `$(this).html()`
});
});

$("li").click(function(){
var myPrag=this.innerHTML.find("p");
});
Then use myParag
P.s. not tested

Related

jQuery insertBefore, Apend for dynamically created elements

Please take a look at code, it is working, it should add just one p tag, but for some reason it is inserting several p tags. P tags are not dynamically created, but some of the content in the p tag is created dynamically(just for info, if it is important).
jQuery("div.content").on("click", ".add", function (e) {
var ptag = jQuery('p.test-me');
ptag.insertBefore('.main-content');
return false;
});
I would just like to insert one p tag(not several) on click before other p tag with class .main-content.
Thank you in advance.
You can try this:
var ptag = jQuery('p.test-me').eq(0);
ptag.insertBefore('.main-content');
In your code as you are referring p elements with class name .test-me there might be possibility of retrieving multiple elements if you have p more than one p elements with that class name. As you said it is appending multiple p elements, it is confirmed that there are multiple elements with the class name .test-me. If you do not want more than one element to be appended, and very sure about what element to be append just use id instead of class name, else just get first element of element list.
// with id
var ptag = jQuery('#id-of-p').clone().attr('id','');
// with className but first element
var ptag = jQuery('.test-me').first(); or .eq(0);
// with id, but should have .test-me class name, then only append?
var ptag = jQuery('#id-of-p.test-me').clone().attr('id','');

select html with native javascript

I want to toggle a class to the html tag element. I've made it work with the body element but I cannot find the solution to also toggle a class to the html tag.
document.querySelector('[data-menu-mobile]').addEventListener('click', function(){
document.body.classList.toggle('nav-main-mobile-open');
document.html.classList.toggle('html-color-fill');
});
I know this seems to be wrong:
document.html.classList.toggle('html-color-fill');
What is the correct way to do this?
There's no document.html object, to get to the root element you should use document.documentElement.
document.documentElement.classList.toggle('html-color-fill')
This should work:
var elements = document.getElementsByClassName("myclass");
//iterate through all found elements
Array.prototype.forEach.call(elements, function(element) {
element.className = "html-color-fill";
//or remove class with:
//element.className = "";
});

Moving the content of a DIV to another DIV with jQuery

http://www.frostjedi.com/terra/scripts/demo/jquery02.html
According to this link elements can be moved around by doing $('#container1').append($('#container2')). Unfortunately, it doesn't seem to be working for me. Any ideas?
See jsfiddle http://jsfiddle.net/Tu7Nc/1/
You must append not your div exactly, but your div's content(inner HTML) with Jquery's html() function.
HTML:
<div id="1">aaa</div>
<div id="2">bbb</div>​
Jquery:
$("#1").append($("#2").html());
Result:
aaabbb
bbb
It is best not to use html().
I ran into some issues due to html interpreting the contents as a string instead of a DOM node.
Use contents instead and your other scripts should not break due to broken references.
I needed to nest the contents of a DIV into a child of itself, here is how I did it.
example:
<div id="xy">
<span>contents</span>
</div>
<script>
contents = $("#xy").contents(); //reference the contents of id xy
$("#xy").append('<div class="test-class" />'); //create div with class test-class inside id xy
$("#xy").find(">.test-class").append(contents); //find direct child of xy with class test-class and move contents to new div
</script>
[EDIT]
The previous example works but here is a cleaner and more efficient example:
<script>
var content = $("#xy").contents(); //find element
var wrapper = $('<div style="border: 1px solid #000;"/>'); //create wrapper element
content.after(wrapper); //insert wrapper after found element
wrapper.append(content); //move element into wrapper
</script>
To move contents of a div (id=container2) to another div (id=container1) with jquery.
$('#container2').contents().appendTo('#container1');
You can also do:
var el1 = document.getElementById('container1');
var el2 = document.getElementById('container2');
if (el1 && el2) el1.appendChild(el2);
or as one statement, but not nearly as robust:
document.getElementById('container1').appendChild(document.getElementById('container2'));
Edit
On reflection (several years later…) it seems the intention is to move the content of one div to another. So the following does that in plain JS:
var el1 = document.getElementById('container1');
var el2 = document.getElementById('container2');
if (el1 && el2) {
while (el2.firstChild) el1.appendChild(el2.firstChild);
}
// Remove el2 if required
el2.parentNode.removeChild(el2);
This has the benefit of retaining any dynamically added listeners on descendants of el2 that solutions using innerHTML will strip away.
$('#container1').append($('#container2').html())
Well, this one could be an alternative if you want to Append:
document.getElementById("div2").innerHTML=document.getElementById("div2").innerHTML+document.getElementById("div1").innerHTML
if you wanted to rewrite contents:
document.getElementById("div2").innerHTML=document.getElementById("div1").innerHTML
I suggest a general approach with a function and jQuery:
function MoveContent(destId, srcId) {
$('#' + destId).append($('#' + srcId).contents().detach());
}
Content of a detached source node is appended to a destination node with call:
MoveContent('dest','src');
The first parameter is an id of a new parent node (destination), the second is an id of an old parent node (source).
Please see an example at: http://jsfiddle.net/dukrjzne/3/

can't get correct results from this jquery object

I have the following bit of javascript and have tried a number of different ways to get the text from the div with the class dvservicestitle, and any li tags in the div with the dvservicescontent class. Neither work and I'm not sure why. Anyone have an idea what's wrong with this code?
if (html == "") html = "<div class='dvservicestitle'>Our Services</div><div class='dvservicescontent'><ul></ul></div>";
var title = $(html).find(".dvservicestitle");
var elements = $("dvservicescontent li", $(html));
The reason is because the find() method finds children nodes on the current node. Your HTML variable IS the div that you are looking for so the find() method doesn't find it. You need to wrap it in another container.
html = "<div class='dvservicestitle'>Our Services</div><div class='dvservicescontent'><ul></ul></div>";
$(html).find(".dvservicestitle")
>> []
$(html).hasClass("dvservicestitle")
>> true
html = "<div><div class='dvservicestitle'>Our Services</div><div class='dvservicescontent'><ul></ul></div></div>"
$(html).find(".dvservicestitle")
>> [<div class=​"dvservicestitle">​Our Services​</div>​]
you can use:
var title = $(".dvservicestitle").text();
var elements = $(".dvservicescontent li").text();
.find searches descendants which you don't have. The div to search exists at top level, so it is one of the elements in the jQuery object.
Use .filter to filter the correct element:
$(html).filter(".dvservicestile").text();
var title = $(html).find(".dvservicestitle").html();
var elements = $(html).find('.dvservicescontent ul').children();

How to use jQuery selector/find() against text string without inserting into the DOM?

I have a text string i'm trying to select the spans from using jQuery. I'd like to grab the spans w/o adding the element to the dom -- if that's possible?
After reading the jquery docs i was under the assumption that i could create a fragment by wrapping the string in a jquery selector tag, then using.find() to find the elements i want.
I have code that is similar to this but from the looks of the last line, it's obvious that no spans are being selected; any help would be greatly appreciated:
// 'text' is normally generated automatically...
// just made it an escaped string for example purposes.
var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = $(text).find('span');
console.log(text); // => <span id="blah1">Y</span><br/><span id="blah2">o</span><br/>
console.log(spans.length); // => 0
Thanks.
You want to use filter(), not find()
var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = $(text).filter('span');
console.log(spans.length);
jsFiddle
From the jQuery docs
filter:
The supplied selector is tested against each element; all elements
matching the selector will be included in the result.
find:
the .find() method allows us to search through the descendants of
these elements in the DOM tree and construct a new jQuery object from
the matching elements.
with your html fragment, there is no wrapper element, so there is no descendants, hence why find() does not work.
You are basically doing:
var elems = jQuery("<span id=\"blah1\">Y</span>").add("<br/>").add("<span id=\"blah2\">o</span>").add("<br/>");
If you want find to work with find(), you need to wrap it in an element.
var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = jQuery("<div></div>").append(text).find("span");
console.log(spans.length);
You want to use filter in this case:
var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = $(text).filter('span');
console.log(spans.length); // 2
Demo: http://jsfiddle.net/ambiguous/TGY3J/
Or wrap it in a <div> and use find:
var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = $('<div>' + text + '</div>').find('span');
console.log(spans.length); // 2
Demo: http://jsfiddle.net/ambiguous/qbCjk/
find works on descendants but without the <div> wrapper, your $(text) doesn't have any <span> descendants. Wrapping your HTML in a <div> is probably your best bet, that way you don't have to worry about how deep your desired elements are.

Categories