how to use the closest function using specific div - javascript

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');
}
}
});

Related

Element still child of previous parent after moving it

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());
});
}

How to say jQuery to do .blur() function in newly appended object?

This question is connected with that
This code hides div when user type data to inputs and focus on another div
$(".Q,.A").blur(function(e) {
if ($(this).val().length > 0 && $(this).siblings("input").val().length > 0) {
$(this).parent().fadeOut(1000);
getData("ajaxPHP/insertNewWords.php?q='" + $(this).siblings('input').val() + "'&a='" + $(this).val() + "'&zestawID="+zestawID, "console");
$(".main").append("<div><input type='text' class='Q'></input><input type='text' class='A'></input></div><br>");
}
});
And when user enter data, this div hides and script creates new div (so user can enter infinite amount of data).
The problem is: new created divs don't hide.
So what should I do, if I want to involve new created divs into "$(".Q,.A")"?
The problem is (as I understand it), that you have a behaviour attached to a set of nodes on your page, and new nodes added to the page do not pick up this behaviour.
This is because of the way JQuery works. When you define a selector like $(".Q,.A") this selector evaluates to a set of known nodes on your page. The code that follows only applies to those found elements. This selector is never evaluated again, so any new nodes never get a chance to gain your desired behaviour.
The solution is to get JQuery to re-evaluate the selector every time the event occurs. So you need to listen for the event globally, then filter to only handle the elements that match your selector.
The correct way to do this is on
$(document).on("blur", ".Q,.A", function(){ ... });
See: http://jsfiddle.net/sAT6L/
Live has some discussion on how it used to be done in each version of JQuery.
Note: You should be able to restrict the scope to something more local than $(document).
You can use jquery's .on method on the parent container, because events "bubble" to the parent container. The on function also allows you to specify a selector to filter the children elements, which gets applied dynamically, so you can use your ".Q,.A" selector there:
$(document).ready(function(){
$("#container").on("blur", ".Q,.A", function(e){
if($(this).val().length>0 && $(this).siblings("input").val().length>0){
$(this).parent().fadeOut(1000);
$("#container").append('<div><input type="text" class="Q"><input type="text" class="A"></div>');
}
});
});
Fiddle: http://jsfiddle.net/rK3HS/1/

How do I get the element containing clicked text in Javascript/Jquery?

I would like to replace the text on pages when I click on the text or even just replace the single word clicked on. I have tried a top down approach selecting all elements in the DOM, filtering out the textNodes, wrapping each with tags and adding a click event handler to each tag. But this is far too slow and inefficient particularly on very large and dynamic sites.
I only need to replace the text that was clicked. Is there a bottom up way of doing this starting from the event.target? How do I find the closest textNode to the event.target, for example?
In the example you gave, you can just do the following; for more info see How do I select text nodes with jQuery?
$(document).click(function(event) {
textNodes = $(event.target).contents().filter(function() {
return this.nodeType == 3;
});
textNodes.each( function() {
$(this).replaceWith("New Text");
});
})
Have you tried Jquery's .closest() ?
Description: 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.

Fadeout all nested divs

On my page I'm trying to do smth like that: Lets say, when we click on some link with id min_reg it animates div with idftr_form_cntr, and shows another div tcr_form_cntr within.
There are 3-4 links that does same function but shows another div within ftr_form_cntr. Well if user clicked one of this links for the first time then there is no problem. But if user already clicked (I mean if ftr_form_cntr already opened) I want to just fadeOut all existing divs nested to ftr_form_cntr and fade in one another div (or swap existing div with another one).
Take a look at this line tcr_form_cntr.fadeIn(1000). What do I need to do before this line to fadeOut all nested divs?
My function look like this:
$(min_reg).click(function () {
if($(ftr_form_cntr).hasClass('opened')){
$(ftr_form_cntr)...<fadeOut all nested divs>
tcr_form_cntr.fadeIn(1000);
return;
}
ftr_form_cntr.show().stop(true, true).animate({
height:"170"
},1000).addClass('opened');
tcr_form_cntr.fadeIn(1000);
});
Assuming that ftr_form_cntr is a string variable holding the jQuery selector for your container element, you can select all the div elements inside and fade them like this:
$(ftr_form_cntr + " div").fadeOut();
Have a look at the jQuery doco on selectors, specifically the "descendant selector".
If ftr_form_cntr is not a string variable but is actually, say, a reference to a DOM element or something then another way to select certain nested elements is using the .find() method, which gets descendants of the elements in your existing jQuery object according to another selector you provide:
$(ftr_form_cntr).find("div").fadeOut();
Your function could look like this:
$(min_reg).click(function () {
var animated_div = $(ftr_form_cntr);
if(animated_div.hasClass('opened')){
animated_div.find('div').fadeOut();
tcr_form_cntr.fadeIn(1000);
return;
}
animated_div.show().stop(true, true).animate({
height:"170"
},1000).addClass('opened');
tcr_form_cntr.fadeIn(1000);
});
What I did is:
I cached the element you work on ($(ftr_form_cntr)),
used .find() jQuery method to get all the divs you want to fade out,
Did it help? Please make sure that both ftr_form_cntr and tcr_form_cntr are defined and first is eg. selector, but the second must be jQuery object.

jQuery ways to dynamically .append a div to the dom, and then find it later without setting an ID, class, or anyway to indentify it

Update: Everyone that contributed, it's well appreciated, you all are very kind and generous and all of you deserve my dear respect. Cheers.
Note: I'm making a simple jQuery tooltip plugin, the tooltip will fire on mouseover. The mouseover will create an instance of the div tool-tip that will be specific to each anchor that launched the div tool-tip. So each anchor with the class .c_tool will have its own created div that will erase after mouseout. Anyway all those details are irrelevant. What is important is how to create a div with .append() or .add() on and then find a way to call it and apply actions to that div without setting an identifier (id), class, or any means to identify it.
I know theres a way you could find the div by counting, so if you gave every created div the same class and then counted them to find that one, however I don't know if this is the most efficient method that is why I'm asking for help.
I'm not going to post the whole plugin script thats unnecessary, so I'll paste a simplified version.
hover me
hover me
$(document).ready(function() {
obj = $('a.c_tool');
obj.mouseover(function() {
/// append div to body it will be specific to each item with class c_tool, however I don't want to set an ID, or CLASS to the appended div
}).mouseout(function() {
/// remove added div without setting ID or class to it.
});
});
Working example:
http://jsfiddle.net/xzL6F/
$(document).ready(function() {
var tooltip;
obj = $('a.c_tool');
obj.mouseover(function() {
var element = $('<div>', {
html: "I'm a tooltip"
});
tooltip = element.appendTo($("body"));
/// append div to body it will be specific to each item with class c_tool, however I don't want to set an ID, or CLASS to the appended div
}).mouseout(function() {
tooltip.remove();
/// remove added div without setting ID or class to it.
});
});
To create a new DOM node you can use the jQuery constructor, like
$(document).ready(function() {
obj = $('a.c_tool');
obj.mouseover(function() {
if(!$.data(this, 'ref')) {
$.data(this, 'ref', $ref = $('<div>', {
html: 'Hello World!'
}).appendTo(document.body));
}
}).mouseout(function() {
$.data(this, 'ref').remove();
});
});
.appendTo() returns the DOM node of invocation (in this case, the newly created DIV) as jQuery object. That way you can store the reference in a variable for instance and access it later.
Referring your comment:
To remove all stored references, you should do this:
$('a.c_tool').each(function(index, node) {
$.removeData(node, 'ref');
});
you can use $.append(
);
http://api.jquery.com/append/
and to find the DOM created dynamically u can use
$("#dynamicallyCreatedDOMid").live("yourCustomTrigger",function(){
});
http://api.jquery.com/live/

Categories

Resources