Why closest() find first itself element before travesing tree - javascript

I looking for why closest() find first itself element before traversing tree.
For example: I would like fadeOut the parent div element when i click on children element, but the children element is too a div and so is the children who fadeOut
$(document).on("click", ".close", function() {
$(this).closest("div").fadeOut();
});
.feed {
width: 200px;
height: 200px;
background: red;
position: relative;
}
.close {
position: absolute;
top: 0;
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="feed">
<div class="close">
X
</div>
</div>
Why is itself element who fadeOut and no the parent div element?
I know parent() get the parent element, but closest() is supposed traversing elements tree.
Have you a concrete cases, where get itself is useful?

It's because the .closest() method traverses the DOM beginning with the current element. You may want the .parents() method instead since it will begin with the parent element.
$(this).parents("div").fadeOut();
It's worth noting that the .parents() method returns zero or more elements whereas .closest() will return zero or one element. Therefore you might want to chain .first() after the .parents() method in order to get the first match:
$(this).parents("div").first().fadeOut();
$(document).on("click", ".close", function() {
$(this).parents("div").first().fadeOut();
});
.feed {
width: 200px;
height: 200px;
background: red;
position: relative;
}
.close {
position: absolute;
top: 0;
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="feed">
<div class="close">
X
</div>
</div>
Alternatively, you could also just exclude the parent by selecting the parent element and then using .closest() like:
$(this).parent().closest("div").fadeOut();
However, it would be much better just to select the closest .feed element rather than any div:
$(this).closest(".feed").fadeOut();
$(document).on("click", ".close", function() {
$(this).closest(".feed").fadeOut();
});
.feed {
width: 200px;
height: 200px;
background: red;
position: relative;
}
.close {
position: absolute;
top: 0;
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="feed">
<div class="close">
X
</div>
</div>

As has been said, closest() begins with the current element. Your selector is vague enough that it stops there.
It may be safer (and more widely useful) to target a specific container class rather than the immediate ancestor div.
$(this).closest(".feed").fadeOut()

You must be more specific, closest() is used when you are not sure what element exactly will receive click (div itself, label inside, image or smth. else) but you want have always same action, so closest can point exactly same element (contrary to parent approach)
$(document).on("click",".close",function(){
$(this).closest(".feed").fadeOut()
});
.feed{
width:200px;
height:200px;
background:red;
position:relative;
}
.close{
position:absolute;
top:0;
right:0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="feed">
<div class="close">
X
</div>
1
</div>
<br>
<div class="feed close">
<div class="close">
X
</div>
2
</div>

Related

How to select (text) inspect element chrome [duplicate]

I'm having a little trouble with CSS and can't seem to find a solution. I have this HTML
<div id="closelink">
Close
Click to close
</div>
Now I want to hide the text «Click to close» only, without hiding neither the div, nor the link within it.
Can this be done?
The visibility attribute can be overriden on children elements, so you are able to do this:
#closelink {
visibility: collapse;
}
#closelink a {
visibility: visible;
}
<div id="closelink">
Close Click to close
</div>
.closelink {
font-size: 0px;
}
.close-link a {
font-size: 12px;
}
Try
#closelink {
position: relative;
left: -9999px;
}
#closelink a {
position: relative;
left: 9999px;
}
<div id="closelink">
Close Click to close
</div>
It works but you can use visibility:hidden instead of visibility:collapse
To avoid the child element breaking to a new line (as happens with just using visibility: hidden/collapse and visibility: visible), and to avoid drawing a 9999px block in the browser (generally frowned upon as it is unnecessary overhead), try this:
#closelink {
position: relative;
visibility: hidden;
}
#closelink a {
position: absolute;
left: 0;
top: 0;
visibility: visible;
}
<div id="closelink">
Close Click to close
</div>
You can adjust your left: 0 value to provide some padding.
There are three methods I could think of:
One
#parent {
opacity: 1;
}
.child {
opacity: 0;
}
<div id="parent">
dkjfdkf
<span class="child">Annoying text</span>
</div>
Two
.child {
visibility: hidden;
}
<div id="parent">
dkjfdkf
<span class="child">Annoying text</span>
</div>
Three
.child {
display: none;
}
<div id="parent">
dkjfdkf
<span class="child">Annoying text</span>
</div>
Opacity is best if you want the image to always be on the page to keep the structure but, you don't want it to be visible.
Hope this was helpful.

JQuery how to append on the same place

so in a project i need to append a few elements with jquery. I am using the .append() function, an it works fine, but what i need to really do is append the elements in the same place every time, and not one after the other.
as you can see i need the secon element (yellow one) - and the next ones - to be appended but every time on the same place, not dependent on the before elements positions.
sorry for bad english.
As #darklightcode mentioned, you should solve this by using CSS.
Add position: relative rule to the Parent element. Then, add position: absolute to Child elements, that you are appending to. The easiest way would be to give each element, that you are adding the same class, that has this rule: position: absolute.
You won't need to specify z-index for each added element, because by default the last added will be visible on top of all other elements.
It can look like this:
HTML:
<div class="parent">
<div class="child green"></div>
<div class="child yellow"></div>
<div class="child red"></div>
</div>
CSS:
.parent {
position: relative;
}
.child {
width: 100px;
height: 100px;
position: absolute;
}
.green {
background: green;
}
.yellow {
background: yellow;
}
.red {
background: red;
}

Only target parent with event.target?

HTML:
<div onclick="doSomething()" id="parent">
<div id="child"></div>
</div>
CSS:
#parent {
background-color: blue;
width: 100%;
height: 100px;
}
#child {
background-color: green;
width: 50%;
height: inherit;
}
.myClass {
background-color: red !important;
}
JS:
function doSomething() {
event.target.className = ('myClass');
}
As you can see in this JSFIDDLE, upon clicking the child, instead of applying the class to the parent which triggers the function, it applies it to the child. I want to know how to avoid this and apply it to the parent no matter where I click inside of it. I am trying to avoid using the document.getElement(s)ByClass/Id method.Any help?
You can refer to the element that handles the event with currentTarget.
Identifies the current target for the event, as the event traverses the DOM. It always refers to the element the event handler has been attached to as opposed to event.target which identifies the element on which the event occurred.
However, instead of relying on the browser to provide a global event object, I would pass it to the function:
onclick="doSomething(event)"
You can also refer to the element the handler is bound to with this:
onclick="doSomething(event, this)"
Of course please consider to not use inline event handlers.
Just reference the target in your javascript call:
function doSomething(target) {
target.className = ('myClass');
}
#parent {
background-color: blue;
width: 100%;
height: 100px;
}
#child {
background-color: green;
width: 50%;
height: inherit;
}
.myClass {
background-color: red !important;
}
<div onclick="doSomething(this)" id="parent">
<div id="child"></div>
</div>
To get the immediate parent element of the clicked element you can use the 'path' array of the event. Path provides an array which includes every element in ascending order from the element you clicked to the top of the DOM.
Having trouble working out the exact browser support for this though.
var children = document.querySelectorAll('[id^="child-"]'),
clickEvent = function(event) {
console.log(event.path[0]); //prints clicked child element
console.log(event.path[1]); //prints parent
event.path[1].classList.toggle('row'); //toggles row or column mode of parent
event.path[0].classList.toggle('selected'); //toggles color of child
};
children.forEach(function(child) {
child.addEventListener('click', clickEvent);
});
<div id="parent">
<div id="child-1">Child One</div>
<div id="child-2">Child Two</div>
<div id="child-3">Child Three</div>
<div id="child-4">Child Four</div>
<div id="child-5">Child Five</div>
</div>

How to get top level object under the mouse function?

Title says it all. I've got child div's with absolute positions inside a relative parent div, and would like to know whether the mouse is over a child or a parent div at a "random" point in time.
Hypothetically, I'd like to call the .mouseover method and perform a .hasclass test on the highest level object to see if it has the child class or not. However, .mouseover is an event handler, thus not something I could just call to get the relevant information.
Example HTML below:
$(document).ready(function() {
$(".child").draggable();
setTimeout(doSomething, 31415);
});
var doSomething = function() {
// Edit content based on what is underneath the mouse
}
.parent {
width: 100%;
height: 1000px;
position: relative;
background: #f0f0f0;
}
.child {
width: 300px;
height: 100px;
position: absolute;
background: #cccccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css">
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
Getting an element from a position is what the document.elementFromPoint function was designed to do:
document.elementFromPoint(mousePosition.x, mousePosition.y);
To get the current mouse position, attach a listener to mousemove (as far as I know there is no native method to extract mouse coordinates without a mouse event). Here's an example fiddle showing this: https://jsfiddle.net/xsLwt8Ld/
If I understood correctly, you want to know if at any given time, the mouse is over the child or directly over the parent. You could achieve it by using the :hover pseudoclass
Create a function that checks if there is any .child that has the :hover class:
If there is, that means that the mouse is over a .child (and you have the element) and there's no need to check the parent.
If there isn't, then check if there is any .parent element that also has the class that you created:
If there is: the mouse is over a .parent but not over a .child;
If there is not: the mouse i not over a .parent or a .child.
The code to achieve this is simple:
function checkMouseOver() {
if ($(".child:hover").length) {
// mouse over a .child
} else if ($(".parent:hover").length) {
// mouse over a .parent (but not over .child)
} else {
// mouse not over a .parent or .child;
}
}
A simple working demo:
$(".child").draggable();
// Edit content based on what is underneath the mouse
function checkMouseOver() {
if ($(".child:hover").length) {
alert("You were over " + $(".child:hover").text());
} else if ($(".parent:hover").length) {
alert("You were over " + $(".parent:hover").attr("id"));
} else {
alert("You are not over a .parent or .child");
}
}
.parent {
width: 100%;
height: 1000px;
position: relative;
background: #f0f0f0;
}
.child {
width: 300px;
height: 100px;
position: absolute;
background: #cccccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css">
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<button onclick="checkMouseOver()">Check where the mouse is</button>
<div class="parent" id="parent1">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
<div class="parent" id="parent2">
<div class="child">Child 3</div>
<div class="child">Child 4</div>
</div>
(Click on the page and press tab until you get into the button, then mouse over the different elements and press Enter to trigger the funtion)

Toggle display:none with div in front of another div?

I'm trying to make a div that I have on top of another div show up when you click on something.
This is the code for the two divs, without all the stuff that's within each:
<div id="randomarticle_enlarge">
<h1></h1>
<h4></h4>
<p></p>
<p></p>
</div>
<div class="bodybag">
<h1></h1>
<h4></h4>
<p></p>
<p></p>
</div>
Then I have css for each, of course:
.bodybag {
width:960px;
}
#randomarticle_englarge {
height:750px;
width:960px;
position:absolute;
z-index:2;
margin-top:1px;
padding-left:20px;
padding-right:20px;
display: none;
}
Am I supposed to have the bodybag class have a z-index and a position:relative? Because even though I don't it's working (at this point).
Anyway, I have this script written that's doing exactly what I want it to do:
$(document).ready(function() {
$('.popular').click(function() {
$('#textmask').fadeTo( 'fast', 0.1);
$('#backgroundmask').css('background-color', 'white');
});
});
And all I want to happen next is that as the textmask and the backgroundmask fade in/change as they should and do, is for the randomarticle_enlarge div to show up.
I've tried using .toggle and .toggleClass and .slideToggle and .show but nothing is working.
Absolute positioning must be relative to a container. In order to absolutely position something you need to indicate what it's absolutely positioned to. Something along these lines.
<div id="randomarticle_englargeContainer">
<div id="randomarticle_englarge">
</div>
<div class="bodybag">
</div>
</div>
#randomarticle_englargeContainer {
position: relative;
}
.bodybag {
position: absolute;
left: 0;
top: 0;
}
When copying everything from above I have no issues using $('#randomarticle_englarge').toggle();. Check your browser's console for errors; you might find the answers there.
I'm not exactly sure about what would you like to do with the divs, but I created an example for you, maybe this is what you want:
LIVE DEMO
So there is two divs. The 2nd div covers the 1st one. Clicking on a 'button' hides the 2nd div, so the 1st one reveals. Clicking again the 'button', the 2nd div appears and covers the 1st one again.
HTML:
<div class="popular">Click me!</div>
<div class="container">
<div id="randomarticle_enlarge">
<h1>A</h1>
<h4>B</h4>
<p>C</p>
<p>D</p>
</div>
<div class="bodybag">
<h1>E</h1>
<h4>F</h4>
<p>G</p>
<p>H</p>
</div>
</div>
CSS:
.container {
position: relative;
}
.bodybag {
width: 100px;
height: 200px;
background-color: red;
}
#randomarticle_enlarge {
width: 100px;
height: 200px;
background-color: green;
position: absolute;
top: 0;
left: 0;
}
.hide {
display: none;
}
jQuery:
$(document).ready(function() {
$('.popular').click(function() {
$('#randomarticle_enlarge').toggleClass('hide');
});
});

Categories

Resources