I am trying to toggle visibility on a div by clicking a button in a neighboring div. I'm using a class .expand to fire the onClick and another class .target as the target, but the problem is that every div with the .target class fires onClick, instead of just the one I want. Logically, I understand why that's happening, but I don't know how to get around it... Here is a bootply: http://www.bootply.com/oSGM0jOG6q#.
$('.expand').on('click', function(e){
$(".target").toggleClass("hidden");
$(".target").toggleClass("visible");
});
HTML
<!-- Thumbnail -->
<div class="col-sm-4">
<div class="thumbnail">
<img src="//placehold.it/400x300&text=Photo1">
<div class="caption">
<h3>Thumbnail label</h3>
<p>Expand</p>
</div>
</div>
</div>
<!-- Big-Image -->
<div class="col-xs-12 target hidden">
<div class="thumbnail">
<img src="//placehold.it/1200x900&text=Photo1">
<div class="caption">
<h3>HighRes</h3>
<p>Close</p>
</div>
</div>
</div>
PS - I prefer to use bootstrap's hidden/visible classes for clean markup, but am not totally stuck on it.
You can use .closest() to find parent div with class col-sm-4 then use .next() to find target
$('.expand').on('click', function(e){
$(this).closest('.col-sm-4').next(".target").toggleClass("hidden visible");
});
Try to use .closest() to get the static parent, i just meant static parent as .thumbnail, since col-sm-4 this class would get change depends upon the layout, i assume. So grab the closest .thumbnail and get its parent then target the next sibling to it.
$('.expand').on('click', function(e){
$(this).closest('.thumbnail').parent().next('.target').toggleClass("hidden visible");
});
DEMO
Here is your bootply http://www.bootply.com/gk8gtlaH1L
Add a div with a new Expand wrapping both the divs. It would be easy for you :)
JS CODE
$('.newExpand').on('click', function(e){
$(this).find(".target").toggleClass("hidden");
$(this).find(".target").toggleClass("visible");
});
HTML CODE
<div class="newExpand">
<!-- Thumbnail -->
<div class="col-sm-4">
<div class="thumbnail">
<img src="//placehold.it/400x300&text=Photo1">
<div class="caption">
<h3>Thumbnail label</h3>
<p>Expand</p>
</div>
</div>
</div>
<!-- Big-Image -->
<div class="col-xs-12 target hidden"><!-- use js to add/remove class"hidden" on button click -->
<div class="thumbnail">
<img src="//placehold.it/1200x900&text=Photo1">
<div class="caption">
<h3>HighRes</h3>
<p>Close</p>
</div>
</div>
</div>
</div>
To use a declarative approach that doesn't tie the JavaScript too heavily to the DOM structure, you could set data-target on each button element to specify the target element to be toggled when the button is clicked, and update the click handler to find the element(s) identified.
For example:
$('.expand').on('click', function(e){
var sel = $(e.target).data("target");
if (sel) {
$(sel).toggleClass("hidden");
$(sel).toggleClass("visible");
}
});
And in the HTML:
<!-- Thumbnail -->
<div class="col-sm-4">
Expand
</div>
<!-- Big-Image -->
<div id="bigImage" class="hidden">
This div will be hidden/shown when the button is clicked
</div>
Related
<div class="item text-center">
<div class="class1"> <p> Something </p> </div>
</div>
<div class="item text-center">
<div class="class1"> <p> Something </p> </div>
</div>
$(".class1").hide();
$(".item").click(function () {
$(".class1").show();
})
I want that when the user click div of item, its own class1 should be show();
But in my codes, when the user click item of div, all class1 shows.
How can i do that just own class can be shown?
To fix this you need to use DOM traversal to access the .class1 element(s) within the clicked .item. To do that you can use the this keyword within the event handler to access the element which raised the event. Try this:
$(".item").click(function() {
$(this).find(".class1").show();
})
.class1 { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item text-center">
Foo
<div class="class1">
<p> Something </p>
</div>
</div>
<div class="item text-center">
Bar
<div class="class1">
<p> Something </p>
</div>
</div>
Note in the example that I used CSS to hide the .class1 elements instead of JS. This is because JS runs after the DOM has loaded, so can result in elements being visible for a short time before they are hidden. CSS runs before this, so avoids that occurrence.
$(".class1").hide();
$(".item").click(function () {
$(this).find(".class1").show();
});
<!--The parent divs should not be empty, otherwise when later in the code you call the .hide () method on their respective child divs, there would be nothing left to click on-->
<div class="item text-center">
item1
<div class="class1">
<p> Something </p>
</div>
</div>
<div class="item text-center">
item2
<div class="class1">
<p> Something </p>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You can use the find () method, the find () method returns the descendant elements of the selected element. Like the code above
I'm using jQuery to create a simple addClass on hover. Hovering over a #science-panel-number div triggers a class of .active to be added to an #iphone-screen-number div.
Here is my jQuery:
$('#science-panel-1').hover(function(){
$('#iphone-screen-1').addClass('active');
},function(){
$('#iphone-screen-1').removeClass('active');
});
$('#science-panel-2').hover(function(){
$('#iphone-screen-2').addClass('active');
},function(){
$('#iphone-screen-2').removeClass('active');
});
$('#science-panel-3').hover(function(){
$('#iphone-screen-3').addClass('active');
},function(){
$('#iphone-screen-3').removeClass('active');
});
My HTML:
<div class="col-md-4">
<div id="science-panel-1" class="science-panel__item">
Content goes in here!
</div>
<div id="science-panel-2" class="science-panel__item">
Content goes in here!
</div>
<div id="science-panel-3" class="science-panel__item">
Content goes in here!
</div>
</div>
<div class="col-md-4">
div id="iphone-screen-1" class="iphone-screen-item">
<img src="IMG-url-here.jpg" alt="" />
</div>
div id="iphone-screen-2" class="iphone-screen-item">
<img src="IMG-url-here.jpg" alt="" />
</div>
<div id="iphone-screen-3" class="iphone-screen-item">
<img src="IMG-url-here.jpg" alt="" />
</div>
<div id="iphone-screen-4" class="iphone-screen-item">
<img src="IMG-url-here.jpg" alt="" />
</div>
<div id="iphone-screen-5" class="iphone-screen-item">
<img src="IMG-url-here.jpg" alt="" />
</div>
<div id="iphone-screen-6" class="iphone-screen-item">
<img src="IMG-url-here.jpg" alt="" />
</div>
</div>
<div class="col-md-4">
<div id="science-panel-4" class="science-panel__item">
Content goes in here!
</div>
<div id="science-panel-5" class="science-panel__item">
Content goes in here!
</div>
<div id="science-panel-6" class="science-panel__item">
Content goes in here!
</div>
</div>
This feels like a lot of code to do the same script. Is there a way to have one piece of script that can add the numbers it self? As #science-panel-1 will always link to to #iphone-screen-1 and so on.
This will do what you need. Just apply the handlers to elements whose ID begins with science-panel-, which should cover all of them...
$("[id^=science-panel-]").hover(function() {
// get the corresponding iphone-screen element id
var iphoneScreen = "#" + this.id.replace("science-panel-", "iphone-screen-");
$(iphoneScreen).addClass("active");
},function() {
var iphoneScreen = "#" + this.id.replace("science-panel-", "iphone-screen-");
$(iphoneScreen).removeClass("active");
});
I recommend changing the markup to include the data you need to drive the script:
<div data-target="#iphone-screen-1" id="science-panel-1" class="science-panel__item">...</div>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This allows you to select all the science panel items at once:
$('.science-panel__item')
and perform the exact same script on each of them:
$('.science-panel__item').hover(function () {
$($(this).data('target')).addClass('active');
// ^^^^^^^^^^^^^^^^^^^^^^
// use the data-target attribute as a selector
}, function () {
$($(this).data('target')).removeClass('active');
});
If you change the attribute and the selector, you'll have a reusable feature you can apply to any element:
$('[data-hover-target]').hover(function () {
$($(this).data('hoverTarget')).addClass('active');
}, function () {
$($(this).data('hoverTarget')).removeClass('active');
});
I'd firstly ask if the active class is strictly necessary? Can what you want be achieved with CSS if it is for styling only by using the :hover pseudoclass?
If you do need the .active class for some reason, I would change the markup to be a little more generic so that all the science panels had a CSS class of .science-panel and all the iphone screens had a class of .iphone-screen. Then you could simplify the JS to look like
$('.science-panel').on('mouseenter mouseleave', function(e) {
$(this).find('.iphone-screen').toggleClass('active', e.type === 'mouseenter');
});
This will find the .iphone-screen inside of the .science-panel that you hover over and toggle the class to on if the mouse enters and off when the mouse leaves it.
edit: I see you've updated your answer to include your markup, this answer was assuming that your iphone-screens were nested in the science-panels so this won't necessarily work for you if you don't/can't nest your markup
I'm quite new to jQuery and I have come up with script which affects the HTML below. The script works perfectly and I have gotten it to whether I would like. The problem I am having
is when I'm duplicating the HTML and the script, once clicked, only shows the last project-info and project-images within the document. I've tried quite a few different methods just as
$(this).children()
but I can't seem to get any to work. Any help would be much appreciated.
Thank you
jQuery
$(document).ready(function() {
$('.apple').click(function() {
$('#darken').addClass('dark');
$('.project-info').delay('1000').slideDown('slow');
$('.project-images').delay('1000').fadeIn('slow');
});
});
$(document).ready(function() {
$('.close').click(function() {
$(".project-info, .project-images").fadeOut('slow');
});
});
HTML
<div class="apple">
<img src="http://mybroadband.co.za/photos/data/500/apple-logo.jpg"/>
</div>
<div class="project-info" style="display:none;">
<div class="project-title">
<h1>hello world</h1>
</div>
<div class="details">
<p>dkusdufhu suskueh sukh suefhuksdfnkuesnfukneukf nseuknfukenfuk nukefnuksn fukfuksukfnuksenf unseukfunfukfunufen u u u ef euhfuehfeufu g gfd gerjkg rjgrjg j js grg rgsg dkusdufhu suskueh sukh</p>
<div class="links">
link
</div>
<div class="close"></div>
</div><!-- end of project info -->
</div>
<div class="project-images" style="display:none;">
<div class="-images">
<img src="http://cdn4.spiegel.de/images/image-499233-galleryV9-grcy.jpg" />
<img src="http://cdn4.spiegel.de/images/image-499233-galleryV9-grcy.jpg" />
</div>
<div class="close end"></div>
</div> <!-- Project Images -->
</div> <!-- # Darken -- >
You're nearly there. Children wouldn't work in the above example because the divs with class 'apple' don't have any children. You need to move that first closing tag to the bottom of the portfolio item so that your html for each portfolio item is structured like this:
<!--PORTFOLIO ITEM-->
<div class="apple">
<!-- ICON GOES HERE-->
<img src="http://mybroadband.co.za/photos/data/500/apple-logo.jpg"/>
<!-- PROJECT INFO GOES HERE-->
<div class="project-info" style="display:none;">
</div>
<!-- PROJECT IMAGES GOES HERE-->
<div class="project-images" style="display:none;">
</div>
</div>
I.e. the divs with classes 'project-info' and 'project-images' are inside the 'apple' div. Then change this:
$('.project-info').delay('1000').slideDown('slow');
$('.project-images').delay('1000').fadeIn('slow');
to this:
$(this).children('.project-info').delay('1000').slideDown('slow');
$(this).children('.project-images',this).delay('1000').fadeIn('slow');
If you've updated your html correctly, $(this) will be pointing to a div element that does indeed have children with classes 'project-info' and 'project-images'. Here's an updated JSFiddle that should do you what you want: http://jsfiddle.net/8k3Ms/1/
I have a problem with my jQuery code, I want the page to slideToggle one div ones the other is clicked, the problem is that I don't want to write all the code again and again so I tried to create a code that works all the time, but I'm stuck. Box is the div which should be clicked and it should contain a class that's also used on the div that's gonna slideToggle. It should pull the class from the tab and then use it to slideToggle the right object. Please help :S (the elements are not placed close to each other which makes next or children not possible). If you have any questions - ASK!
The jQuery code of mine:
$(".box").click(function() {
var Klassen = $(this).attr("class");
$("Klassen").slideToggle(300);
});
HTML:
<!-- These should be clicked -->
<div data-toggle-target="open1" class="box ft col-lg-3">
<div class="mer">
Läs mer
</div>
<div class="bild"><img src="images/sakerhet.jpg"></div>
<h4>HöstlovsLAN</h4>
</div>
</a>
<div data-toggle-target="open2" class="box st col-lg-3">
<div class="mer">
Läs mer
</div>
<div class="bild"><img src="images/sakerhet.jpg"></div>
<h4>NyårsLAN</h4>
</div>
<div data-toggle-target="open3" class="box tt col-lg-3">
<div class="mer">
Läs mer
</div>
<div class="bild"><img src="images/sakerhet.jpg"></div>
<h4>Säkerhet</h4>
</div>
<!-- These should be toggled -->
<div class="infobox" id="open1">
<h1>HöstlovsLAN</h1>
</div>
<div class="infobox" id="open2">
<h1>NyårsLAN</h1>
</div>
<div class="infobox" id="open3">
<h1>Säkerhet</h1>
</div>
EDIT - NEW PROBLEM - STILL AIN'T WORKING!
The code didn't work in my situation and would like you to take a look at the JS-fiddle I created:
http://jsfiddle.net/Qqe89/
undefined has presented the solution.
I would warn you about using this approach, if you add any classes to the .box div then your code will break.
Instead consider using data attributes to target the div to be toggled:
<div data-toggle-target="open1" class="box green"></div>
<div id="open1">
Opens
</div>
Which can then target with
$('.box').click(function (e) {
$( '#' + $(this).data('toggleTarget') ).slideToggle(300);
});
jsFiddle with example using your html - crudely formatted sorry!
$(".box").click(function() {
var Klassen = $(this).attr("class");
$("."+Klassen).slideToggle(300);
});
class attribute may contain several classes ($(this).attr("class") OR this.className)
$("."+Klassen) will not work if there are several classes
"Klassen" does not correspond to any DOM element as there is no such tag in HTML.
I have a bit of a problem I cant figure out.
I have a slideshow on my page using jquery.
<div id="carousel">
<div id="round">
<div class="box box-sec">
<img class="carousel-image" alt="Image Caption" src="_includes/images/carousel/sample1.jpg">
<div class="carousel-caption">
<p>
Peace of Mind <span>at the best rate possible...</span>
Click here for more
</p>
</div>
</div>
<div class="box box-easy">
<img class="carousel-image" alt="Image Caption" src="_includes/images/carousel/sample1.jpg">
<div class="carousel-caption">
<p>
Peace of Mind <span>at the best rate possible...</span>
Click here for more
</p>
</div>
</div>
<div class="box competitive">
<img class="carousel-image" alt="Image Caption" src="_includes/images/carousel/sample1.jpg">
<div class="carousel-caption">
<p>
Peace of Mind <span>at the best rate possible...</span>
Click here for more
</p>
</div>
</div>
<div class="box personal">
<img class="carousel-image" alt="Image Caption" src="_includes/images/carousel/sample1.jpg">
<div class="carousel-caption">
<p>
Peace of Mind <span>at the best rate possible...</span>
Click here for more
</p>
</div>
</div>
<div class="box business">
<img class="carousel-image" alt="Image Caption" src="_includes/images/carousel/sample1.jpg">
<div class="carousel-caption">
<p>
Peace of Mind <span>at the best rate possible...</span>
Click here for more
</p>
</div>
</div>
<div class="box affiliate">
<img class="carousel-image" alt="Image Caption" src="_includes/images/carousel/sample1.jpg">
<div class="carousel-caption">
<p>
Peace of Mind <span>at the best rate possible...</span>
Click here for more
</p>
</div>
</div>
<div class="arrows">
<div class="next"><span>Test</span><img src="_includes/images/icons/rarr.png" /></div>
<div class="prev"><span>Test</span><img src="_includes/images/icons/larr.png" /></div>
</div>
</div>
</div>
</div>
only 1 slide is active at a time, I want to somehow find the name of the next div, and write that into the "Test" span tags so that it shows up on hover and if clicked the span tag will then get the name of the next div and update itself, does this make sense? thanks
ADDED FIDDLE
http://jsfiddle.net/TNRMk/
Ive tried this with no luck
$('.arrows').click(function() {
$(".next span").html($('.roundabout-in-focus').next().attr('name'));
$(".prev span").html($('.roundabout-in-focus').prev().attr('name'));
});
Here is a good start for you:
$("div.arrows div").bind("mouseover", function() {
$("div.arrows div.next").children("span").text($("div.roundabout-in-focus").next("div").attr("class"));
$("div.arrows div.prev").children("span").text($("div.roundabout-in-focus").prev("div").attr("class"));
});
A number of points to be made:
This will not work for the prev arrow when the first item is selected.
I wasn't sure which part of the class name you wanted so you will need to do some modification
It needs to be on hover, or in the plugin itself as there are other ways to control the carousel. So setting on click won't work all the time.
The plugin provides callbacks btnNextCallback and btnPrevCallback that are executed after clicking the "next"/"prev" buttons are clicked.
The current focused item has the class .roundabout-in-focus.
I have made this jsfiddle for you to see (all you div have the same content so I've replaced it for the sake of the example).
Here's the (commented) code:
$(document).ready(function() {
function updatePrevNextTitle() {
// as this function is used as a callback for the plugin
// 'this' is the roundabout wrapper div
var $wrapper= $(this),
// get the currently focused div
$frontDiv = $wrapper.find('.roundabout-in-focus'),
// get the next/prev div content relative to the focused div
// also handle the circular roundabout by checking if
// .next() and .prev() return something, otherwise
// get .first() and .last()
nextContent = $frontDiv.next().length
? $frontDiv.next().find('.carousel-caption').html()
: $frontDiv.first().find('.carousel-caption').html(),
prevContent = $frontDiv.prev().length
? $frontDiv.prev().find('.carousel-caption').html()
: $frontDiv.last().find('.carousel-caption').html();
$wrapper.find('.next span').html(nextContent);
$wrapper.find('.prev span').html(prevContent);
};
$('#round').roundabout({
childSelector: 'div.box',
btnNext: ".next",
btnPrev: ".prev",
// set the method updatePrevNextTitle as the callback handler
btnNextCallback: updatePrevNextTitle,
btnPrevCallback: updatePrevNextTitle
}
// set it also as the 'initialized' callback for the
// initial setting of the prev/next span text
,updatePrevNextTitle);
});
One way is to add an active class in your selected div:
//e.g. after the selection event occurs:
$('div').click(function() {
$(this).addClass('active'); //keep track which div is clicked with the active class
//read the class name of the next sibling and store it in test (if i got it right)
$(".Test").html($('.active').next().attr('class'));
});
Maybe not 100% right but can give you a headstart!
According to your jsfiddle the name attribute is missing on your roundabouts,
try this instead:
$('.arrows').click(function() {
$(".next span").html($('.roundabout-in-focus').next().find('.carousel-caption').html());
$(".prev span").html($('.roundabout-in-focus').prev().find('.carousel-caption').html());
});