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
Related
I'm quite rusty with my (basic) javascript so hopefully I'm not misunderstanding the problem entirely, but essentially what I'm trying to do is return the 'alt' field of an image as a caption appended to the title for each image, and while I'm getting essentially that, it's returning the list for the entire sequence of images to each instead of their own in a sequence. Code is super simple, which is probably why it's not working. Any help is appreciated
$('#projectThumbs img').each(function(){
$('.project-title').append("<div>" + $(this).attr('alt') + "</div>");
});
For example, if the images have a caption sequence of '1','2','3', each image is now being appended with '1,2,3' instead of '1' to 1, '2' to 2, etc.
Images structure from the html (in Squarespace so I don't have access to source code, only injection). This is in a grid of images.
ETA: noticed a few hiding divs in the code, maybe the project-item-count can be useful in some way?
<a class='project'>
<div>
<div class='project-image'>
<div class='intrinsic'>
<div class = 'content-fill'>
<img alt='example'>
</div>
</div>
<div class='project-item-count'>
</div>
</div>
<div class='project-title'>
Title
</div>
</div>
</a>
image of what's happening to help clarify
$('.project-image img').each(function(){
$(this).parents('.project-image').next().append("<div>" + $(this).attr('alt') + "</div>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class='project'>
<div>
<div class='project-image'>
<div class='intrinsic'>
<div class = 'content-fill'>
<img src="https://picsum.photos/200" alt='example1'>
</div>
</div>
<div class='project-item-count'>
</div>
</div>
<div class='project-title'>
Title
</div>
</div>
</a>
<a class='project'>
<div>
<div class='project-image'>
<div class='intrinsic'>
<div class = 'content-fill'>
<img src="https://picsum.photos/200" alt='example2'>
</div>
</div>
<div class='project-item-count'>
</div>
</div>
<div class='project-title'>
Title
</div>
</div>
</a>
Assuming the HTML contains valid #projectThumbs element, the problem is that you're not targeting the .project-title element(s) correctly.
You need to do that using parent() (to find the parent of the element), and then use siblings() to find the correct sibling (which has project-title class assigned).
See the demo below:
$('#projectThumbs img').each(function() {
$(this).parent().siblings('.project-title').append("<div>" + $(this).attr('alt') + "</div>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="projectThumbs">
<a class='project'>
<div>
<div class='project-image'>
<img alt='example'>
</div>
<div class='project-title'>
Title
</div>
</div>
</a>
</div>
The id attribute cannot be duplicated in DOM elements so each function is not run on all the same id elements if you use the class attribute with the same name and use each function then your problem solved.i hope it helps you.
$('#projectThumbs img').each(function(){
$('.project-title').append("<p>" + $(this).attr('alt') + "</p>");
});
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<div id="projectThumbs">
<img alt="myimae"
src="http://psdandcode.com/themes/psd2code/images/logo.png">
<img alt="mimage"
src="http://psdandcode.com/themes/psd2code/images/logo.png">
<img alt="myimae"
src="http://psdandcode.com/themes/psd2code/images/logo.png">
<img alt="myimag"
src="http://psdandcode.com/themes/psd2code/images/logo.png">
</div>
<div class="project-title"></div>
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>
I wish to display certain divs inside a main div dependent on which image is clicked. With out any decent knoweldge of Js or Jquery, I fail to do this without some assistance.
<form>
<input type="hidden" name="prod">
<div id="images">
<img id="one" src="http://lorempixel.com/200/200/">
<img id="two" src="http://lorempixel.com/201/200/ ">
<img id="three" src="http://lorempixel.com/203/200/ ">
<img id="four" src="http://lorempixel.com/204/200/ ">
</div>
</form>
<div id="description">
</div>
<div class="one">Brilliant</div>
<div class="two">Super</div>
<div class="tree">Amazing</div>
<div class="four">Excellent</div>
If the image which has id="one" is clicked, then display <div class="one">Brilliant</div> inside of the description div. Then ofcause if the second image is clicked, then display the the 'super' div inside the description div. I'd like to not have the descriptions visible until clicked, and only one div at a time to be shown.
The images are apart of a form because I need to forward the value of the id on the images to a variable.
Here is the script that does that.
$('#images').delegate('img', 'click', function () {
var $this = $(this);
// Clear formatting
$('#images img').removeClass('border-highlight');
// Highlight with coloured border
$this.addClass('border-highlight');
// Changes the value of the form field prod to the file name shown in the image.
$('[name="prod"]').val($this.attr('id').substring($this.attr('id').lastIndexOf('-') + 1));
//Alert for debugging simplicity
alert($('[name="prod"]').val());
});
Perhaps a function can be implemented into the current script?
Here is a fiddle, and it will all make sense of what I have as a whole currently.
Check out this fidde
You just need to add:
$('#description').html($('.' + $this.attr('id')).html());
At the bottom of your onclick function.
** You have a typo on the 3rd div with text(tree instead of three).
You can make it bit simple by adding the divs for description in div as I see no need to put the divs for description outside the description div and later adding it. You will need to hide all the divs we have in description div and show the one that is related to img being clicked.
Live Demo
Html
<input type="hidden" name="prod">
<div id="images">
<img id="imgone" src="http://lorempixel.com/200/200" />
<img id="imgtwo" src="http://lorempixel.com/201/200" />
<img id="imgthree" src="http://lorempixel.com/203/200" />
<img id="imgfour" src="http://lorempixel.com/204/200" />
</div>
<div id="description">
<div id="one">Brilliant</div>
<div id="two">Super</div>
<div id="three">Amazing</div>
<div id="four">Excellent</div>
</div>
Javascript
$('#images').delegate('img', 'click', function () {
$('#description div').hide();
$('#' + this.id.replace('img', '')).show();
});
I have a simple JS Junction that stop working when the break point of my responsive website is activated (The nav var toggle/collapse at 768px, here is when the JS function stop working)
The HTML is:
<div class="mainFoto">
<img id="bigImage" src="/fotosArticulos/12578.jpg">
</div>
<div class="misProductosFotos">
<div class="foto" onclick="callImage('12578.jpg');"><img src="/Thumbs/12578.jpg"></div>
<div class="foto" onclick="callImage('30643.jpg');"><img src="/Thumbs/30643.jpg"></div>
<div class="foto" onclick="callImage('12656.jpg');"><img src="/Thumb/12656.jpg"></div>
</div>
and the JS function is
function callImage(idImage) {
var imageUrl = '/fotosArticulos/'+idImage;
$('#bigImage').attr('src', imageUrl);
}
This simple does that when click on one thumb the JS change the SRC of id="bigImage"
Why this Function stop working and how fix it?
May be this will help you.
HTML
<div class="mainFoto">
<img id="bigImage" src="/fotosArticulos/12578.jpg" />
</div>
<div class="misProductosFotos">
<div class="foto">
<img src="/Thumbs/12578.jpg" />
</div>
<div class="foto">
<img src="/Thumbs/30643.jpg" />
</div>
<div class="foto">
<img src="/Thumbs/12656.jpg" />
</div>
</div>
Script
$('.foto').click(function() {
$('#bigImage').attr('src', $(this).find('img').prop('src').replace('/Thumbs/', '/fotosArticulos/'));
})
fiddle
Thanks Guys for all your support. The issue was that when the website collapsed and get responsive there was an invisible element that overlap the Thumbs icons, that is why they did not respond, I think I blend bootstrap too soon. Thanks again :)
#anilkumar, do you think storing $(this).find('img').prop('src').replace('/Thumbs/', '/fotosArticulos/') in a variable might make things a little more human readable? Like so:
$('.foto').on('click', function() {
var changeSrc = $(this).find('img').prop('src').replace('/Thumbs/', '/fotosArticulos/');
$('#bigImage').attr('src', changeSrc);
})
#saymon, do you reckon you might be removing the #bigImage id from .mainFoto > img at the breakpoint? Or perhaps Bootstrap might be renaming the element id?
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());
});