target mutiple classes above (this) in jQuery? - javascript

I've built a simple dropdown menu to replace some html select menus like so:
$('html, .currentPage').click(function() {
$('.currentMenu').slideUp('fast');
});
$('.currentPage').click(function(e){
if(!$(this).next().is(":visible")) {
$(this).next().stop().slideDown('fast');
}
e.stopPropagation();
});
$(".currentMenu li").click(function(e){
e.preventDefault();
$(".currentPage").html($(this).text());
});
However, if I were to have more than one menu, the final part:
$(".currentMenu li").click(function(e){
e.preventDefault();
$(".currentPage").html($(this).text());
});
will occur on both menus. How can I target the ".currentPage" class for that specific menu only?
HTML:
<div class="menuWrap font">
<div class="currentPage">Trebuchet MS</div>
<div class="currentMenu">
<ul>
<li>Arial</li>
<li>Helvetica</li>
<li>Droid Sans</li>
<li>Trebuchet MS</li>
<li>Georgia</li>
<li>Droid Serif</li>
</ul>
</div>
</div>
<div class="menuWrap fontSize">
<div class="currentPage">12pt</div>
<div class="currentMenu">
<ul>
<li>9pt</li>
<li>10pt</li>
<li>11pt</li>
<li>12pt</li>
<li>13pt</li>
</ul>
</div>
</div>

You have two options. The first is to traverse the DOM to find the nearest .currentPage element from .currentMenu li. Given your HTML structure, this should work:
$(".currentMenu li").click(function(e){
e.preventDefault();
$(this).closest(".currentMenu").prev().html($(this).text());
});
The second option is to put this code into a plugin which you apply to an element, so you always know the context in which to select elements in.

OK, based on your updated question. .currentMenu and .currentPage are siblings. So you can navigate to the parent element, then drill down to the currentPage. Here's a fiddle: http://jsfiddle.net/DuPuJ/

Related

Child div affects parent div in css and triggers jquery method

I have parent div with class a "very-big-div" that nests another "container-div" that by its turn also nests another child divs. The very big div's made to act like a button and the div that come right after it is a container that appears when I click the very big div.
<div class="very-big">
<div class="container">
<!-- Some other more nested divs that has anchors and buttons -->
<div class="friend-request">
<div class="button-div">
<button class="accept">Trigger</button>
<button class="refuse">Trigger</button>
</div>
</div>
</div>
</div>
The problem is 2 things first: the css problem has not yet been solved
I assigned a hover pseudo class for the "very-big-div", and whenever I hover the "container-div" the hover properties(background-color) is applied to the "very-big-div". This is not what I intend to make, I want to only hover "very-big" div for the hover to apply.
.very-big{
background-color:green;
}
The second problem is : I have a jquery that deals with the container so it is toggled on/off by the "very-big-div"
$(document).ready(function(){
$("#container-div").hide();
$("#very-big-div").click(function(){
$("#container-div").toggle();
});
});
the container has both anchor and button tags whenever I click the an anchor or a button inside the container it is toggled to close itself, and that is not what I want, what I want is just when I only press the "very-big-div" the toggle is activated.
Same as #Jhecht has given the answer, I have just inherited his to mine.
You can stop propagation of the click of child element that trigger toggle by using target and excluding all the child elements of your .very-big container as:
$(".very-big").click(function(e) {
var target = $(e.target);
if (!target.is('.very-big *')) {
$(".container").toggle();
}
});
Code Snippet:
$(document).ready(function() {
$(".container").hide();
$(".very-big").click(function(e) {
var target = $(e.target);
if (!target.is('.very-big *')) {
$(".container").toggle();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="very-big">
Other Text
<div class="container">
This is text to fill stuff out so I can click on it.
</div>
</div>
This works for me, but I am not sure if it is what you need.
Please add in the minimum HTML, CSS, and Javascript needed to fully recreate the error you are seeing.
$(document).ready(function() {
$(".container").hide();
$(".very-big").click(function(e) {
console.log(e);
var current = $(e.toElement);
if (current.is('.container')) {
e.stopPropagation();
return false;
}
$('.container').toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="very-big">
Other Text
<div class="container">
This is text to fill stuff out so I can click on it.
</div>
</div>

Show content only from the clicked link and hide all siblings

as stated in the name, i have a menu with links, and i have a list of sections which i want to show/hide on the click of the menu.
What i want here is to be dynamic in a sense that if i add more menus and sections I don't have to change the code that does it, or to add new tags or names.
I tried doing something myself but I'm probably missing something..
Any assistance would be appriciated
I have a simple example on this jfiddle: https://jsfiddle.net/s07ysx6w/6/
HTML:
<div id="header">
<div id="menuBlock">
<ul id="menu">
<li>Novosti</li>
<li>Program Mladi</li>
<li>Program Odrasli</li>
<li>Program Upisi</li>
<li>Galerija</li>
<li>Kontakt</li>
</ul>
</div>
</div>
<body>
<div id="main">
<div id="novosti" name="sekcija1" class="sekcija">
aaaa
</div>
<div id="programMladi" name="sekcija2" class="sekcija">
aaaa
</div>
<div id="programOdrasli" name="sekcija3" class="sekcija">
aaaa
</div>
<div id="programUpisi" name="sekcija4" class="sekcija">
aaa
</div>
<div id="galerija" name="sekcija5" class="sekcija">
aaaa
</div>
<div id="kontakt" name="sekcija6" class="sekcija">
aaa
</div>
</div>
</body>
Javascript:
$(document).ready(function() {
$("#menu").click(function(e) {
var selected = this.attr('href');
$('#main' + selected).show('slow').siblings().hide('slow');
});
});
EDITED:
Copy/pasting made me careless so now there are only unique id's. Also replaced the fiddle with a working one (solution).
UPDATE:
In case anyone uses slicknav as a plugin on his/her's page, to get to the element you have in your menu you need to find how exactly slicknav injected it into your page. For instance, in my case, since i prepend it to my #menuBlock div tag. In order to find the element #novosti i had to dig in deep, since slicknav creates tags on its own in order to work the way it does.
In that case my javascript looked like this.
$(document).ready(function(){
$("#menuBlock div ul li a").click(function (e){
e.preventDefault();
var selected = $(this).attr('href');
$( selected ).fadeIn('slow').siblings().hide();
});
});
There should a space between 2 selectors if they have a parent child relationship, so change this line
$('#main' + selected).show('slow').siblings().hide('slow');
to
$('#main ' + selected).show('slow').siblings().hide('slow');
or simply the selected one (since it is already pointing to a specific element)
$(selected).show('slow').siblings().hide('slow');
check this updated fiddle
$(document).ready(function(){
$("#menu li a").click(function (e){ //bind the event on `a` rather than ul
var selected = $(this).attr('href'); //use $(this) instead of this
$( selected ).show('slow').siblings().hide('slow'); //explained above
});
});
There are more than one errors found in your code,
set a Jquery library
Id should be unique throughout the DOM
Replace this.attr with $(this).attr()
Descendant selector would be #menu #something not #menu#something
Should .stop() an animation before beginning the new one.
Try,
$(document).ready(function() {
$("#menu li a").click(function(e) {
e.preventDefault()
var selected = $(this).attr('href');
$('#main ' + selected).stop().show('slow').siblings().hide('slow');
});
});
DEMO
Try this method
$(document).ready(function() {
$("#menu a").click(function(e) {
debugger;
var selected = $(this).attr('name');
$('#main div').hide();
$('#main div[name="'+selected+'"]').show('slow');
});
});
You are not supposed to have more than one element with the same ID on a page, so change the id on the page to something more specific. Or I'm I mistaken? From your question, you wanted something more extensible, here is an approach
$(document).ready(function(){
$("#menu").click(function (e){
var element = $(e.target).attr('href');
$('#main-divs > ' + element).show('slow').siblings().hide('slow');
});
});

JQuery getting the second parent not working

I have this HTML:
<li class="chatbox-item">
<div class="item">
<div class="item-header">
X
</div>
</div>
</li>
When a.close-chatbox is clicked, the .item element has to be hidden. However, I just can't seem to go up two levels to hide the .item element.
I have this JS:
$(".close-chatbox").click(function() {
// not working
$(this).parent().parent().hide();
// not working, hides `.chatbox-item` element, and eq(1) doesn't do anything either
//$(this).parents().eq(2).hide();
});
How can I get the .item element to be hidden when the .close-chatbox element is clicked?
Don't assign your action to a var, just use it:
$(function () {
$(".close-chatbox").click(function () {
$(this).parent().parent().hide();
});
});
JSFiddle: http://jsfiddle.net/ghorg12110/tkocx8ng/
You can either use,
$(this).parent().parent().hide();
or you can use .closest("element"),
$(this).closest(".item")
Use .closest() in jquery
$(this).closest('.item').hide();
Fiddle

Working on DOM elements, finding next class

I have problem with working on DOM elements.
This is my HTML:
<div class="movie__feature">
▲
</div>
<div class="movie__images">
<span class="similarity_points">9</span>
<a href="http://www.filmypodobnedo.pl/Top-Gun/" title="Filmy podobne do Top Gun">
<img alt="Filmy podobne do Top Gun" src="http://www.filmypodobnedo.pl/photos/Top-Gun.jpg"/>
</a>
</div>
<div class="movie__feature">
▼
</div>
</div>
When I click on .plus class, I need to go to .similarity.
This is my jQuery:
$('.plus').click(function(e){
e.preventDefault();
var self = $(this);
self.closest('div').find('.similarity_points').text('10');
}
How my num should look?
The closest div doesn't contain .similarity_points as a descendent. You could use this:
self.closest('div').parent().find('.similarity_points').text('10');
But, be aware that code which is highly dependant on the structure of the DOM is also fragile.
In your code you are going up to .movie__feature, and then you are looking for children with the .similarity_points class.
You need to go up one more level and then look for the child element:
$('.plus').click(function () {
$(this).closest('div').parent().find('.similarity_points').text('10');
return false;
});

How do I make this code work for each click?

I have h3 block's and on click of each of the block I am showing the section associated with it. It is actually something like accordion(hide and collapse). I have also given a drop icon to the h3 tags, means that when the block is opened the h3 should have a dropicon pointing downwards while others h3 should have there dropocons towards right. I am controlling this behaviour using backgroundPosition. I am using the jQuery visible condition to see if the particular block is visible then give its drop icon one background position and to the rest other. It works fine but only for first click. It doesn't work for second click; can somebody explain why? Here is my code:
if($(this).next().is(':visible')) {
$(this).css({'backgroundPosition':'0px 14px'});
}
else {
$("h3").css({'backgroundPosition':'0px -11px'});
}
UPDATED CODE:
$("h3").click(function() {
$(".tabs").hide();
$(this).next().show();
if($(this).next().is(':visible')) {
$(this).css({'backgroundPosition':'0px 14px'});
} else {
$("h3").css({'backgroundPosition':'0px -11px'});
}
})
If you wrap the whole block in a div it might make traversing easier.
Html:
<div class="drop-block">
<h3>Click this</h3>
<ul>
<li>Drop</li>
<li>it</li>
<li>like</li>
<li>it's</li>
<li>hot</li>
</ul>
</div>​
Jquery:
var dropper = $('.drop-block');
$(dropper).find('h3').click(function(){
$(this).toggleClass('active');
$(dropper).find('ul').toggle();
});​
Example
I Belive that you are looking for live
So it will be something like this:
$(element).live('click', function(){
if($(this).next().is(':visible')) {
$(this).css({'backgroundPosition':'0px 14px'});
}
else {
$("h3").css({'backgroundPosition':'0px -11px'});
}
}
Instead of editing the css of them, make a css class "open" (or similar), and then add / remove the class on the click to open / close.
It is much easier to debug by checking for the existence of a class than it is to check the css properties of something in JS.
Better make a class name for each situation and easly handle the action
$('h3').on('click', function(){
if($(this).hasClass('opened')) {
$(this).removeClass('opened');
}
else {
$(this).addClass('opened');
}
}
$(document).on('click', 'h3', function(e) {
$(".tabs").hide('slow');
$(this).css({'backgroundPosition':'0px 14px'});
if(!$(this).next().is(':visible'))
{
$("h3").css({'backgroundPosition':'0px -11px'});
$(this).next().show('slow');
}
});
You can remove 'slow' from show/hide if animation is not required
Here is an example.
It sounds like you need to bind click events to the h3 elements and toggle the visibility of the child elements:
$(function(){
$("h3").click(function(){
$(this).next(".tabs").toggle();
});
});
Example markup:
<h3>Item 1</h3>
<div class="tabs">
<h4>Option 1</h4>
<h4>Option 2</h4>
</div>
<h3>Item 2</h3>
<div class="tabs">
<h4>Option 1</h4>
<h4>Option 2</h4>
</div>
Here's a jsFiddle to demonstrate.

Categories

Resources