I'm looking for a solution to a little problem I have, currently I'm looking to get the entire DOM tree from an element (e.g. all the parents), which I can do using .closest('body').first().
The problem is I'm looking for a way to go through each element and parent and remove all of the text/html from them except the original target, so basically have a blank tree but have html in the bottom element.
Although I haven't tried it yet, I was thinking just .each() might work, although something tells me it would have a problem with the nested structure?
Any advice would be great!
Thanks
Dom
UPDATE:
Accepted answer works great! I adapted the code and added to the fiddle below to allow it to work with deep nested structures like the ones I was working with...
Fiddle here: http://jsfiddle.net/RDNTc/2/
That script remove every text nodes of the parent of the target :
$('p').parentsUntil('body').each(function(){
$(this).contents().each(function(){
if(this.nodeType === 3) this.parentNode.removeChild(this);
});
});
http://jsfiddle.net/RDNTc/;
You can traverse up the parents in jQuery using .parents(). Then use .each() to iterate over them in a loop.
Related
I have a line of javascript code that works perfect in IE
document.forms[0].all
what it does, it gets all the dom elements including their child elements.
I want this same in chrome, i used this:
document.forms[0].childNodes
what it does, It gets all the dom elements but not their childs
So, my question is how to achieve the same functionality for chrome?
Thanks
Try
document.forms[0].getElementsByTagName('*')
or
document.forms[0].querySelectorAll('*')
This won't give you text nodes, but DOM elements you will get.
Try this,
document.forms[0].children
You can iterate child elements with
document.forms[0].children[i]
I'm trying to fill an array with all direct child elements of a div.
example:
<div>
<span></span>
<a></a>
</div>
should result in an array containing span and a
How Would I achieve this?
I tried var elements = $('.thediv').children(); but that doesn't seem to work.
Also how Would I then use that information for this kind of function?:
$("element1","element2","element3") depending on the result of the array?
Really thank you for your help! I am kind of lost with this thing
Note: I'm using zepto.js which has a similar syntax to jquery but misses a lot of functions so that might be a problem but I am also happy with solutions using jquery syntax because it should work pretty well :) https://github.com/madrobby/zepto
To get the tags into the array, you could easily use, with jQuery (though I'm unfamiliar with zepto):
var elementsArray = [];
$('div').children().each(
function(i){
elementsArray.push(this.tagName.toLowerCase());
});
JS Fiddle demo.
And to use them, you can try:
for(i=0;i<elementsArray.length;i++){
$('div').find(elementsArray[i]).css('color','red');
}
JS Fiddle demo.
Although this simply uses the tagName of each element, so if there is more than one a within the relevant element all elements matching the selector, effectively $('div').find('a') in this case, will be targeted by the selector.
The above caution seems to be discounted through use of a more complicated selector, and behaviour, and allows for each element to be iterated over one at a time, though I can't help but feel it's a little more complex than it needs to be:
var elementsArray = [];
$('div').children().each(
function(i){
elementsArray.push(this.tagName.toLowerCase());
});
for(i=0;i<elementsArray.length;i++){
$('div')
.find(elementsArray[i])
.not('.edited')
.eq(0).css('color','red')
.addClass('edited');
}
JS Fiddle demo.
Sigh, I'm an idiot. The final iteration of this is below, which reduces the complexity somewhat, and allows for proper iteration over each element according to their position in the array:
var elementsArray = [];
$('div').children().each(
function(i){
elementsArray.push(this.tagName.toLowerCase());
});
for(i=0;i<elementsArray.length;i++){
$('div')
.children()
.eq(i)
.css('color','red');
}
JS Fiddle demo.
Having said the above, though, if you want to "target all elements within," why not simply target those elements with:
$('div').children();
Which will select, and target, each direct child of the div element without first holding them in, or having to hold them in, a user-created array variable.
$("div").children().toArray();
http://api.jquery.com/toArray/
$("element1","element2","element3")
Does this mean you want to use the array as a jQuery selector? Or you really want the tag names?
Each DOM node has a childNodes attribute, which is a NodeList containing all the direct descendants of the node in question.
I use .append to add to a div
$(this).append('<ul><li>test</li></ul>');
how can I search for a <ul> and remove it if it exists in the children of $(this)?
You could use remove(). More information on jQuery remove().
$(this).children("ul").remove();
Note that this will remove all ul elements that are children.
The opposite of .append() is .prepend().
From the jQuery documentation for prepend…
The .prepend() method inserts the specified content as the first child of each element in the jQuery collection (To insert it as the last child, use .append()).
I realize this doesn’t answer the OP’s specific case. But it does answer the question heading. :) And it’s the first hit on Google for “jquery opposite append”.
Use the remove() method:
$(this).children("ul").remove();
What you also should consider, is keeping a reference to the created element, then you can easily remove it specificly:
var newUL = $('<ul><li>test</li></ul>');
$(this).append(newUL);
// Later ...
newUL.remove();
just had the same problem and ive come across this - which actually does the trick for me:
// $("#the_div").contents().remove();
// or short:
$("#the_div").empty();
$("#the_div").append("HTML goes in here...");
Opposite up is children(), but opposite in position is prepend().
Here a very good tutorial.
How can I find out which FORM an HTML element is contained within, using a simple/small bit of JavaScript? In the example below, if I have already got hold of the SPAN called 'message', how can I easily get to the FORM element?
<form name="whatever">
<div>
<span id="message"></span>
</div>
</form>
The SPAN might be nested within other tables or DIVs, but it seems too long-winded to iterate around .parentElement and work my way up the tree. Is there a simpler and shorter way?
If it wasn't a SPAN, but an INPUT element, would that be easier? Do they have a property which points back to the containing FORM? Google says no...
The form a form element belongs to can be accessed through element.form.
When the element you are using as reference is not a form element, you'd still have to iterate through the parentElement or use some other kind of selector.
Using prototype, you could simplify this by using Element.up():
$(element).up('form');
Other answers to this question have pointed out how to do the same in jQuery.
Why not just use:
var nodesForm = node.form;
?
It works on FF3, FF4, google chrome, Opera, IE9 (I tested myself)
Guess you have to iterate through all elements then.
You can try using jQuery:
$("input").parent("form")
http://docs.jquery.com/Traversing/parent#expr
Regarding Gumbo's Post:
As much as prototype and jQuery are useful, some people don't implement them into their projects.
Could someone please explain why Gumbo's solution was downgraded, other than the fact that he repeated what the OP was originally trying to avoid?
node = document.getElementById(this.id);
while (node.nodeName != "FORM" && node.parentNode) {
node = node.parentNode;
}
To answer the OP's question:
Traversing the DOM is the fastest way to achieve this effect - perceived speed is accomplished by 1) better written JS code, or 2) execution time (if you store the form on page load for that element, you'll still be traversing, but you'll have a quicker call to a stored variable when you need to retrieve that information).
There are no attributes nested in non-form elements that would associate it with the form (span.form does not exist).
If you are using a script (php/perl) to generate your page, and you're going to be making a lot of calls to the form, you could embed the form id in the HTML for that element. Still, a look up would need to occur.
I hope this helps,
vol7ron
You could backtrack in the DOM tree until you get to the right node:
node = document.getElementById("message");
while (node.nodeName != "FORM" && node.parentNode) {
node = node.parentNode;
}
Or a small jQuery (ignoring jQuery itself):
$("#message").parents("form:first")
Other than node.parentNode, I don't believe there is a way to find a specific ancestor of a given node. Most libraries usually do what you describe and iterate up through parentNode.
If you're not using a library like prototype, jquery or Ext, it would probably be a good idea. By now, they've resolved all the incompatibilities and quirks in the DOM to make most operations like this a trifle.
So i got this snippet of code:
$(document).ready(function () {
var replacementDoneIn = $("body").html();
var regExMatch = /premier(( {1,5}?)?co(mpany)?([ |\.])?)?/ig;
var replaceWith = "Nikon";
var resultSet = replacementDoneIn.replace(regExMatch, replaceWith);
$("body").html(resultSet);
});
which is some what working for me, but it does not cover more robust and complicated scenario.
I would like to expand find/replace capabilities with a help of jQuery. To properly utilize find/replace of the text inside of the body element excluding any html elements and any attributes and their values.
note: Not being completely certain on how jQuery text() function traverses children of the element it is applied on to.
note: as far as i understand i can loop through all elements in html via $("*"), but does that create any issues for such script
so if you could direct me to the right path, it would be greatly appreciated. Links to resources that address this already, your advices, all will work. Because for some reason my head produces only complicated solutions, so I am wondering may be there are simpler approach.
Thank you in advance.
Check my answer to this question:
How to replace text in html document without affecting the markup?
I posted a simple function that traverses text nodes, replacing its content, without affecting the markup or JavaScript connected event handlers.
If I understand your question correctly, using text() will be the way to go. It includes only the text nodes of of an element and any descendents of that element. So doing
(document.body).text();
will get you the text of all elements contained within the body of the document. Using your regular expression against this should achieve what you need.