Passing Multiple Inner Child Node to Function - javascript

I need to pass the contents of an inside div to a function, for example myfun(string). I have tried using
myfun((this).children[0].innerHTML)
myfun((this).children[1].innerHTML)
myfun((this).children[0].children[0].innerHTML)
but none of those seem to work. I can't just pass the getElementById value because the function should be generic since it would be called by php on various <a> elements (ideally I think it should include the this. keyword).
Thanks for any help.

If you don't need it to work cross-browser, there's:
this.getElementsByClassName('label')[0]
This will fail in IE 8 and below.
If you're absolutely certain the HTML/DOM structure won't change, you could perhaps use:
this.nextSibling.children[0];
But this might have issues in browsers that consider textNodes as childNodes

in your function, "this" refers to the link, and can't be used.
a much cleaner solution would be to have myfunc know that it is going to receive an object which contains the text
javascript:
myfunc(obj){
alert(obj.childNodes[0].nodeValue);
}
html
click
<div id="target">target contents</div>

The object this will apply to the <a> tag that it calls. You need to call the parent div first and then select the children accordingly.
Try using this.parent.children[1].children[0].innerHTML

Try
this.parent.children[1].children[0].innerHTML
But you should really use dynamic IDs instead of this mess.

Related

Using two getElementByIds

Is it possible to do something like:
this.getElementById('first-id').getElementById('second-id')?
When I do this, I get an error "getElementById(...).getElementById is not a function.
The reason I'm trying to do this is because I am able to console log the first-id element, but not the second (when I do this.getElementById('second-id')). I assume it is because my DOM is not completely loaded.
However, I thought since it loaded the first-id element, I'll be able to do another getElementById as the first part is loaded and the next element is nested/a child of the first-id element.
Can someone explain why this logic doesn't work?
An element with a given ID is supposed to be absolutely unique in a document. There should never be more than one element with the same ID. So, calling getElementById on an element to search among its children, if it were possible (which it isn't), wouldn't make a whole lot of sense - instead, search from the whole document. You should only need
document.getElementById('second-id')
Most answers here are correct and will help the OP implement the solution. This will try to answer Is it possible to do something like:, which is what OP asked originally:
this.getElementById('first-id').getElementById('second-id')
getElementById() is a Document interface method and is only available on the Document object. It is not available on the Element, and this.getElementById('first-id').getElementById will be equal to undefined. undefined is not a function and can't be invoked, hence the error.
It makes sense that getElementById() is only available in the Document interface as an ID is (ideally) supposed to be a unique in the DOM. So, providing the function inside other elements is not as useful.
querySelecetor() is both a document and element method and is available on both the objects.
That is why you can do something like :
document.querySelector('#first-id').querySelector('#second-id')
(Searches for #second-id child of #first-id)
You could possibly chain it using Document.querySelector(), but you should never need to use this as ids should be unique.
E.g, something like this:
var selected = document.querySelector('#first-id #second-id');
console.log(selected);
<div id="first-id">
<div id="second-id">1</div>
</div>
<div id="second-id">2</div>
<!-- Don't use duplicate ids - this is just for demonstration -->
You could do something weird like the following, but it's silly.
<script>
window.addEventListener("load", function() {
alert(document.getElementById("parent").ownerDocument.getElementById("child").textContent);
}, false);
</script>
<div id="parent">
<div id="child">Yo</div>
</div>

how to re-write string in jquery to avoid accessing the dom again, and use jquery selector

I am trying to re-write some jquery so that uses a selector I had previously created, so that it doesn't need to access the DOM again. The selector I had created already access the DOM once, and I want to use its contents in a string literal in a function.
My current code is the following:
$(this.$content[$(`.nav a[href$="${window.location.hash}"]`).parent().index()]).show();
which works just fine, but ".nav a" is accessing the DOM, which I do not want in this instance. I want to use this.$navigation, which I had created before and already has the information from the DOM. I tried writing it as
$(this.$content[$(`this.$navigation.find('a')[href$="${window.location.hash}"]`).parent().index()]).show();
where this.navigation = $("#main-nav"), the parent of the .nav elements, but it does not work in this way.
Any suggestions on how I might approach this?
The inner jQuery object should be moved outside of the string literal, and the attribute selector needs to be placed inside the find() call.
$(this.$content[$(this.$navigation).find(`a[href$="${window.location.hash}"]`).parent().index()]).show();
In addition, I would assume from the naming convention that $navigation already holds a jQuery object so does not need to be wrapped again. As such, this should work:
$(this.$content[this.$navigation.find(`a[href$="${window.location.hash}"]`).parent().index()]).show();

Does jQuery remove function really remove Dom elements?

I am really wondering if jQuery remove function really remove elements from DOM.
First, I looked here but the answers are not convincing.
I encountered this problem when I noticed I am still able to manipulate elements on which I have called remove function.
My code:
<div id="container">
<div id="div">
This is a div
</div>
</div>
var div = $('#div');
$('#div').remove();
$('#container').append(div);
Note: My question is not how to solve this? but I want to understand what's going on here!
Actually, this code doesn't remove the #div from the dom, but if I have any data set to the #div, it will be lost. I am pretty confused now about the behaviour of remove function. Can anyone explain this please?
DEMO
I am convinced that div variable is not just a clone of the dom element, is a reference to it, because when I manipulate the div variable, (like div.html('something')) the div within the DOM get updated.
Or am I wrong?
remove() does indeed remove the element from the DOM.
However in your example, the element has been cached in memory because you assigned it to the div variable. Therefore you can still use it, and append it again, and it will still contain all the events the original did.
If what you say is right, why I loose the data bound to the div so?
If you check the source for remove() you'll see that it calls the internal cleanData function which removes the events and clears the data cache for the element. This is why you lose the information.
If you want to remove the element from the DOM, but keep the elements, use detach() instead.
Here's a fiddle to show the difference: http://jsfiddle.net/2VbmX/
had to delete the assigned variable:
delete div;

Accessing a parent added via wrap function

I have an input field fld. I wrap this field inside a div in one part of my code.
input.wrap('<div>')
In another part of the code I obtain the field 'fld' which is a jQuery object.
fld.el contains the input field.
Now, I want the div I previously wrapped around this fld.
fld.el.parent() does not work for me. Nor does fld.el.parents(). Tried fld.el.closest('div') with no luck.
If I load the input element again via id, I am able to access the parent objects.
$('#'+fld.id).parent() works. But I do not want to introduce any ids.
Any way in which I can just make use of the fld.el I have and obtain the parent?
What's the ".el" in fld.el.parent() about? Try fld.parent().
Not 100% sure but try:
parentdivs = fld.el.parents("div:first");
OR
parentdivs = fld.parents("div:first");
This will get your first parent div of an item
Without seeing your code and based on the behavior you're describing, I would guess that fld.el is not a jQuery object.
Try:
$(fld.el).parent();
If you're 100% certain it is a jQuery object (and the above doesn't work) you should post your code, or at least recreate your issue using jsfiddle.net

jQuery wrap syntax

It's end of day. I'm hoping I'm just having a lapse of logic.
I can't get this to work:
var $divA= $("<div></div>").addClass('classA');
var $divB= $("<div></div>").addClass('classB');
$myDiv.after($divA.wrap($divB));
The above should turn this:
<div id="myDiv"></div>
Into this:
<div id="myDiv"></div>
<div class="classB">
<div class="classA"></div>
</div>
But it doesn't seem to work with that 'wrap' in there. I don't get any errors, it just doesn't wrap divA with divB and just inserts divA by itself.
Am I misunderstanding wrap?
UPDATE:
A simpler example that does not work:
$myBox.after($("<p></p>").wrap("<div></div>"));
That will add just the DIV after myBox.
It seems like jQuery doesn't like wrap added to after.
Have you tried
$myDiv.after($divA.wrap('<div class="divB"></div>'));
just for testing purposes?
As far as I understand, you shouldn't pass a jQuery object to the wrap-function:
The .wrap() function can take any
string or object that could be passed
to the $() factory function to specify
a DOM structure. This structure may be
nested several levels deep, but should
contain only one inmost element. The
structure will be wrapped around each
of the elements in the set of matched
elements.
If the example above works, then this is the reason ;-)
Just stumbled onto this thread having the same problem: jQuery .wrap() isn't working
I think if you change your code from
$myDiv.after($divA.wrap($divB)) to $myDiv.after($divA.wrap($divB).parent())
you'll get your wrap.
The confusing part might have been to You that .wrap() returns the inner element, not the parent element.
So you have to use the parent object of the wrapped one like this:
var $divA= $("<div/>").addClass('classA'),
$divB= $("<div/>").addClass('classB');
$myDiv.after($divA.wrap($divB).parent());
($divA.parent() is equal to $divB after the wrapping)
So the key part is that $divA.wrap($divB) returns $divA, NOT $divB
see the reference:
This method returns the original set of elements for chaining
purposes.
http://api.jquery.com/wrap/
I got this to work:
$('div#myDiv').after("<div class='classA'></div>").end().find('.classA').wrap("<div class='classB'></div>");
with your html to solve your initial question. Here's the source for jQuery's end function. This code will go make the chain go up one level (to the myDiv level), and will then wrap based on the find('.classA') at that level. That will find your div added with after, and wrap it in div with classB.
Edit:
Ok, I think this will work for you the way you want:
var divA= $("<div></div>").addClass('classA');
$('div#myDiv').after($(divA).wrap('<div class="divB" />'));
I think the problem was that when calling wrap on divA, it needs to be a jQuery object to work correctly. So really all you were missing was wrapping divA in ().
You're not looking for wrap. You want:
divB.append(divA).insertAfter('#myDiv');
I may be reading this wrong, but if you're using jQuery, isn't the $ a reserved character? have you tried just setting your variable names so they don't use it?
If so:
var divA = $("<div></div>").addClass('classA');
divA.wrap("<div class=\"classB\"></div>");
divA.insertAfter($("#myDiv"));
or
divA.after($("#myDiv"));
Here's the jQuery docs on the matter.

Categories

Resources