Given the following code
var a = $('<div><div></div></div>');
a.css("visibility", "visible");
a.find("* :visible");
I receive an empty array [] as a result instead of a div. What am I doing wrong?
To check if an element is visible, it must be inserted into the DOM. You also don't need the * selector. Try this:
var a = $('<div><div></div></div>'); // create an element
a.css("visibility", "visible");
$("BODY").append(a) // Add the element to the DOM first
a.find(":visible")
alert(a.find(":visible").length); // displays '1'
You haven't added the element to the page, so it's not sized yet. Elements with zero size are not considered visible.
Related
Answer in short: insertAfter() is to be used on the element that you are inserting after another element, not on the element that you want to insert something after. For full code, scroll down.
I have a situation where when the user clicks a button, certain elements get moved to a hidden container, and when the user clicks another button, those elements need to get moved back to their original position.
I do it (in short) like this:
Moving to hidden container:
element.data('original_parent', original_parent);
element.data('original_index', original_parent.index());
element.appendTo(hidden_container);
Moving the items back to their original container:
element.data('original_parent').children().eq(element.data('original_index')).prev().insertAfter(element);
But somehow this isn't working. When I output the children of the original parent to the console, it also lists the elements that are currently in the hidden container as children. Anyone have an idea of how I could fix this?
Your logic may not be not correct as the order in which it is removed and added might deffer – Arun P Johny 1 min ago
You are right. The elements are output to the console first, then I move them, which is why it seemd like an uncorrect parent was being listed as their parent.
Are you sure you're getting any element with doing element.data('original_parent')? – Dhaval Marthak 5 mins ago
An element is being returned for sure.
I have already found out what is happening here. I use the insertAfter function on the original element that I want to insert the element after instead of on the element that I want to insert after the original element. Got my jQuery functions mixed up a bit.
The rest of the code works, though! Full code for those that want to use the idea and come across this post:
function hideNonMatchingLevelElements(jquery_selector) {
var elements = $(jquery_selector);
if (!elements.length)
return false;
var target = $('#js-hidden-level-elements');
if (!target.length) {
console.error('Cannot hide non matching level elements because target cannot be found.');
return false;
}
elements.each(function() {
$(this).data('original_parent', $(this).parent());
$(this).data('original_index', $(this).index());
$(this).appendTo(target);
});
}
function showMatchingLevelElements(jquery_selector) {
var elements = $(jquery_selector);
if (!elements.length)
return false;
elements.each(function() {
// Only show elements that are in the "hidden elements" container.
if ($(this).parent().attr('id') != 'js-hidden-level-elements')
return true; // Continue;
if (!$(this).data('original_parent'))
return true; // Continue.
$(this).insertAfter($(this).data('original_parent').children().eq($(this).data('original_index')).prev());
});
}
I need a method to clone say 4 div's with id's like d_1, d_2, d_3, d_4
including the contents inside each div all at once and then detach all divs, and then I need to find copy of d_1 and its contents from the clone and append it again to the page.
something like:
var cloned=$('[id^="d_"]').clone();
$('[id^="d_"]').detach();
and then find div with id =d_1 from clone and append it to body.
Is it possible?
Use Document Fragment.
var $documentFragment = $(document.createDocumentFragment());
$('[id^="d_"]').each(function(){
$documentFragment.append($(this).clone().addClass("_cloned"));
});
$documentFragment.clone().appendTo(document.body);
If you want looking for an element into the fragment, you can do this:
$(document.body).find("#d_1._cloned"). ... ;
If you want to remove all the element and then append only the first copied into fragment:
$("._cloned", document.body).remove();
$documentFragment.find("#d_1").clone().appendTo(document.body);
You can appendTo() an element to detach and move an element elsewhere.
var els = $('[id^="d_"]')
els.detach();
els.each(function() {
if (this.id.indexOf('d_1') !== -1) {
$(this).appendTo(document.body);
}
});
// do something else with els later, too.
I have a dynamically added div which I want to append in response to a click event.
The initial div is created and rendered when added however trying to add children divs to the first dynamic div does not render - yet in console log the dynamic div shows the new div has been added.
var newDiv = $('<div id="#newDiv'+pID+'" />').css({
display:"inline-block",
width:"90%",
height:"100px",
position:"relative"
})
var newHTML = "<div>some content</div>"
$(newDiv).html(newHTML)
$('#dynDiv'+ID).append($(newDiv))
console.log($('#dynDiv'+pID)) // displays code created successfully
So newDiv is not rendered nor present when "inspecting" the DOM using debugger.
Why is the second attempt to add dynamic content failing ??
Have you remembered to append it to something? Remember, jQuery can have DOM elements present in memory which are not part of the page:
newDiv.appendTo($(parentElement));
eg. http://jsfiddle.net/dTe73/
A couple of other possible errors:
# is not a valid character to put in an id in $('<div id="#newDiv'+pID+'" />')
$('#dynDiv'+ID) looks like a typo for $('#dynDiv'+pID) (or the other way around)
Not an actual error, but redundant use of $: $(newDiv) is absolutely equivalent to newDiv
I found the source of the problem was that the parent div to which I was adding the dynamic div was not unique - there were multiple elements with same name ! This makes sense that it would fail. Thanks for everyones input.
Replace $(newDiv).html(newHTML) with newDiv.html(newHTML)
and $('#dynDiv'+ID).append($(newDiv)) with $('#dynDiv'+ID).append(newDiv)
and it should work.
I need jquery to get the closest id,once the the image is visible.
this is my query so far
(...)
if(isonscreen)
{
//this works, but I need it to find only images inside the content-bubble div tag
// and of course this grabs any image no matter what div the image is inside of
console.log($(this).closest('img').attr('id'));
}
(...)
<div class="content-bubble">
<h2>{{imageTitle}}</h2>
<img src="loading.gif" id="lazyload{{imgId}}" class="content-bubble-img"">
</div>
I've tried this but its not working and returns undefined
console.log($(this).closest('.content-bubble-img').find('img').attr('id'));
console.log($('.content-bubble-img').closest('img').attr('id'));
I thing you want the function find(), not closest().
closest finds the nearest parent of an element, while find().filter(':first') finds the first children inside an element. Or to say it with the doc's words:
closest:
For each element in the set, get the first element that matches the
selector by testing the element itself and traversing up through its
ancestors in the DOM tree.
find:
Get the descendants of each element in the current set of matched
elements, filtered by a selector, jQuery object, or element.
http://api.jquery.com/closest/
http://api.jquery.com/find/
To comment your code:
console.log($(this).closest('img').attr('id'));
This is actually pretty bad since images cant have children, this does only work since closest() returns the selected element itself which is the image when you use $(image).closest(). Replace closest with find and you're good to go.
If u have to find all images inside "content-bubble div" no matter what div the image is inside of then use this :
$('.content-bubble img');
First of all it would be much easier to fully understand what you're trying to achieve if you have added a fiddle of it.
Nevertheless I'm guessing that you're checking whether an image is currently visible - which means that in this piece of code
(...)
if(isonscreen)
{
console.log($(this).closest('img').attr('id'));
}
(...)
$(this) actually refers to the image you're interested in - thus you might want to simply retrieve its id attribute with $(this).attr('id')
Since you want to limit it to images which are placed in divs with a specific class, you might just want to check if one of its parents has class '.content-bubble', by
$(this).parents('.content-bubble').length
You may also use closest, since it actually traverses up the DOM tree from the element you specified, and:
if($(this).closest('.content-bubble').length)
which in this case would return true when $(this) or any of its parent has class .content-bubble
I'm using the espy plugin for jquery
This is how you find the id of the nearest image inside a div tag
once the image is visible
$('.content-bubble-img').espy(function (entered, state) {
if (entered)
{
// element entered the viewport
// state === 'inside'
console.log('element entered viewport');
console.log($(this).closest('img').attr('id'));
}
else
{
// element left the viewport
if (state === 'up')
{
// element is now above the trigger area
console.log('element left the viewport');
}
else if (state === 'down')
{
// element is now below the trigger area
console.log('element below the trigger area');
}
}
});
I have a form which allows user to add elements(which might be a field set or a text box) dynamically. I'm able to assign a new ID to the elements when added but I'm not able to make it in a sequence as the user can add elements in between as well.
So for example, there is an Id named XXX1 and the user adds a new element after it which is xxx2. Now if the user adds a new element again after XXX1, it comes up as XXX3. So the order of the elements is XXX1, XXX3, XXX2. I'm not able to control the names when it is being added. So I'm trying to re-assign the names after add.
I'm trying to get all elements in an array and change the ID as follows
document.getElementById('xxx3').setAttribute('id', 'xxx2');
But this doesn't work as ID XXX2 already exists for another element. Please help me with a solution for this.
So why not change the ID of xxx2 first, to move it out of the way, then putting it back in place later?
document.getElementById('xxx2').setAttribute('id', 'temporaryId');
document.getElementById('xxx3').setAttribute('id', 'xxx2');
document.getElementById('temporaryId').setAttribute('id', 'xxx3');
Why not go from the last element to the first(the one's after the position you are inserting to) and add one to the ID?
for example:
var insertAt = 2; // for an element to be called xxx2
var els = [...]; // an array with all of the elements
if(els.length >= insertAt){
for(var i = els.length-1; i >= insertAt-1; --i){
els[i].setAttribute('id', 'xxx'+(i+2));
}
}
// Add the new element here which will be called xxx2