jQuery Toggle one element at time with closing/hiding - javascript

I'm a Js beginner, and here's my code (the pics are not the same, but it's exactly what I want) :
$('#img-expand').click(function () {
$("#work-info").slideToggle("slow");
});
$('#img-expand_2').click(function () {
$("#work-info_2").slideToggle("slow");
});
Look at this : http://jsfiddle.net/vk7AE/1/
I would like that when I click on an image, the text associated with this one appears, and that if I click on the other image, the preceding text disappears, and that the new text associated with the clicked image appears in its place.
In fact, I would like that people can open only one text at the same time.
I hope that you will include/understand my problem, and that you will be able to help me.
Regards.

DEMO
$('#img-expand').click(function () {
$('[id^="work-info"]').hide();
$("#work-info").slideToggle("slow");
});
$('#img-expand_2').click(function () {
$('[id^="work-info"]').hide();
$("#work-info_2").slideToggle("slow");
});
attribute-equals-selector
^ attribute-starts-with-selector
Description: Selects elements that have the specified attribute with
a value beginning exactly with a given string.
$('[id^="work-info"]'); select all elements with id starting with work-info
updated after OP's comment
DEMO
$('#img-expand').click(function () {
$('[id^="work-info"]').not('#work-info').hide();
$("#work-info").slideToggle("slow");
});
$('#img-expand_2').click(function () {
$('[id^="work-info"]').not('#work-info_2').hide();
$("#work-info_2").slideToggle("slow");
});
.not()

$('#img-expand').click(function () {
var slide = $("#work-info").is(":visible");
$(".part-body-opacity p").slideUp();
if(!slide)
$("#work-info").slideToggle("slow");
});
$('#img-expand_2').click(function () {
var slide = $("#work-info_2").is(":visible");
$(".part-body-opacity p").slideUp();
if(!slide)
$("#work-info_2").slideToggle("slow");
});
http://jsfiddle.net/vk7AE/5/

Related

On hover: higlight all identical links to Wikipedia in one colour, highlight all identical links elswhere in a different color

I am trying to highlight all identical links to Wikipedia blue on hover, whereas all identical links elsewhere would be higlighted green on hover.
The Wikipedia-part, I have managed using the following jQuery code:
$(function () {
function getKey(element) {
return element.href;}
function sameGroupAs(element) {
var key = getKey(element);
return function () {
return getKey(this) === key;}}
$(document)
.on("mouseenter", "a[href*=wikipedia]", function () {
$("a").filter(sameGroupAs(this)).addClass("wikipedia");})
.on("mouseleave", "a", function () {
$("a").filter(sameGroupAs(this)).removeClass("wikipedia");});});
a.wikipedia{background-color: #A8c5ff}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Wikipedia: experiential learning. And all <b>identical</b> links get higlighted at the same time. E.g.: the next occurence experiential learning gets highlighted simultaneously.
As for the green higlight on hover for non-Wikipedia-pages, I am still struggling.
What I've tried so far:
You might have a good laugh, since I am under-experienced, but I'll try to show where I got stuck:
I tried to duplicate the code again, to now specify an extra condition... E.g., trying to use the jQuery :not()-selector
For example, checking to see if the negation of the Wikipedia-class applies,
$( "a[href]:not(:contains('wikipedia'))" ).css( "color", "green" );
or I have tried things similar to:
"a:not([href*=wikipedia])"...
Or by adding an ifWikipedia?->{nothing}else{green}-statement.
if(!$(this).hasClass("wikipedia")){;nothing} else{addClass("green");}
Another option I have tried (also without success, since the Wikipedia-part then gets overruled, whereas I would like just to let the Wikipedia-part prioritize):
Copy the code, and replace "a[href*=wikipedia]" by "a" and add a class for green. Then, the desired result would be achieved if only the Wikipedia-part could impose itself over the general "a"'s.
Any help would be greatly appreciated (from this beginner, as you can notice).
You can achieve this with a combination of CSS attribute selectors and re-using your existing functions, but making them more generic.
DEMO
JavaScript:
function getKey(element) {
return element.href;
}
function sameGroupAs(element) {
var key = getKey(element);
return function () {
return getKey(this) === key;
}
}
$(document).on("mouseenter", "a", function () {
$("a").filter(sameGroupAs(this)).addClass("active");
}).on("mouseleave", "a", function () {
$("a").filter(sameGroupAs(this)).removeClass("active");
});
Then the CSS:
a[href*="wikipedia"].active {
background:red;
}
a:not([href*="wikipedia"]).active {
background:green;
}

Add class on div mouse enter mouse leave and click

What i am trying to achieve is, i want to make it work like star rating. When you enter mouse star becomes yellow, when you leave mouse it turns gray and then if you click it again becomes yellow.
Not getting how to achieve it, I have added code to show you what i have tried so far.
JSfiddle
$(".na").hover(
function () {
$(this).addClass("clickstar");
},
function () {
$(this).removeClass("clickstar");
}
);
$(".na").on("click",function(){
$(this).toggleClass("clickstar");
});
.clickstar{
background: #00A1EF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="na" style="border:1px solid #c0c0c0;border-radius:50%;width:115px;height:115px;display:inline-table;margin-right:5px;"></div>
You should consider using 2 different classes, .hoverstar and .clickstar, then :
http://jsfiddle.net/xLxbw216/1/
You would have one class for each case, which seems more logical ?
You can also make it simpler by removing .hover() method, and do it with CSS :
http://jsfiddle.net/xLxbw216/8/
I probably choose the second one, even if the first solution seems to be more "readable".
You can do it like this:
$(".na").on("click",function(){
$(this).toggleClass("clickstar");
});
Fiddle Example
You should use a different class for permanent start and hover star
I have created a working example in JSfiddle
$(".na").hover(
function () {
var $this = $(this);
if (!$this.hasClass("permstar")) {
$this.addClass("clickstar");
}
},
function () {
var $this = $(this);
if (!$this.hasClass("permstar")) {
$(this).removeClass("clickstar");
}
}
);
$(".na").on("click",function(){
$(this).toggleClass("permstar");
});
add/remove class on hover events was conflicting with on click event, so i have moved the hover functionality to css
css:
.clickstar{
background: #00A1EF;
}
.na:hover{
background: #00A1EF;
}
live demo:
http://jsfiddle.net/dreamweiver/xLxbw216/7/
Happy Coding :)

how to repeat same Javascript code over multiple html elements

Note: Changed code so that images and texts are links.
Basically, I have 3 pictures all with the same class, different ID. I have a javascript code which I want to apply to all three pictures, except, the code needs to be SLIGHTLY different depending on the picture. Here is the html:
<div class=column1of4>
<img src="images/actual.jpg" id="first">
<div id="firsttext" class="spanlink"><p>lots of text</p></div>
</div>
<div class=column1of4>
<img src="images/fake.jpg" id="second">
<div id="moretext" class="spanlink"><p>more text</p></div>
</div>
<div class=column1of4>
<img src="images/real.jpg" id="eighth">
<div id="evenmoretext" class="spanlink"><p>even more text</p></div>
</div>
Here is the Javascript for the id="firsttext":
$('#firstextt').hide();
$('#first, #firsttext').hover(function(){
//in
$('#firsttext').show();
},function(){
//out
$('#firsttext').hide();
});
So when a user hovers over #first, #firsttext will appear. Then, I want it so that when a user hovers over #second, #moretext should appear, etc.
I've done programming in Python, I created a sudo code and basically it is this.
text = [#firsttext, #moretext, #evenmoretext]
picture = [#first, #second, #eighth]
for number in range.len(text) //over here, basically find out how many elements are in text
$('text[number]').hide();
$('text[number], picture[number]').hover(function(){
//in
$('text[number]').show();
},function(){
//out
$('text[number]').hide();
});
The syntax is probably way off, but that's just the sudo code. Can anyone help me make the actual Javascript code for it?
try this
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink").show();
});
Why not
$('.spanlink').hide();
$('.column1of4').hover(
function() {
// in
$(this).children('.spanlink').show();
},
function() {
// out
$(this).children('.spanlink').hide();
}
);
It doesn't even need the ids.
You can do it :
$('.column1of4').click(function(){
$(this); // the current object
$(this).children('img'); // img in the current object
});
or a loop :
$('.column1of4').each(function(){
...
});
Dont use Id as $('#id') for multiple events, use a .class or an [attribute] do this.
If you're using jQuery, this is quite easy to accomplish:
$('.column1of4 .spanlink').hide();
$('.column1of4 img').mouseenter(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').show();
});
$('.column1of4 img').mouseleave(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').hide();
});
Depending on your markup structure, you could use DOM traversing functions like .filter(), .find(), .next() to get to your selected node.
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink, img").show();
});
So, the way you would do this, given your html would look like:
$('.column1of4').on('mouseenter mouseleave', 'img, .spanlink', function(ev) {
$(ev.delegateTarget).find('.spanlink').toggle(ev.type === 'mouseenter');
}).find('.spanlink').hide();
But building on what you have:
var text = ['#firsttext', '#moretext', '#evenmoretext'];
var picture = ['#first', '#second', '#third'];
This is a traditional loop using a closure (it's better to define the function outside of the loop, but I'm going to leave it there for this):
// You could also do var length = text.length and replace the "3"
for ( var i = 0; i < 3; ++i ) {
// create a closure so that i isn't incremented when the event happens.
(function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(',')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
})(i);
}
And the following is using $.each to iterate over the group.
$.each(text, function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(', ')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
});
Here's a fiddle with all three versions. Just uncomment the one you want to test and give it a go.
I moved the image inside the div and used this code, a working example:
$('.column1of4').each(function(){
$('div', $(this)).each(function(){
$(this).hover(
function(){
//in
$('img', $(this)).show();
},
function(){
//out
$('img', $(this)).hide();
});
});
});
The general idea is 1) use a selector that isn't an ID so I can iterate over several elements without worrying if future elements will be added later 2) locate the div to hide/show based on location relational to $(this) (will only work if you repeat this structure in your markup) 3) move the image tag inside the div (if you don't, then the hover gets a little spazzy because the positioned is changed when the image is shown, therefore affecting whether the cursor is inside the div or not.
EDIT
Updated fiddle for additional requirements (see comments).

Close accordion alike div using jQuery?

I have this simple code which shows 3 items
When I press the header ($(".fileHeader")) , it should open then next element which is the next element (hidden div) ($(".LST_Documents"))
sketch :
JSBIN : it does work.
Most important :
When I press on a $(".fileHeader")- i need to close all other $(".LST_Documents") and then ( that why i used promise) open the relevant $(".LST_Documents").
The problem is (look at the pic) if i press again on the first $(".fileHeader").
what is happening is that it closing and then re opening. and I want it to stay CLOSED.
P.S.
I could solve it with class ( .rowOpen or something like that) but I want to do it via JS/JQ only.
How can I enhance my code to work as expected ?
Just hold the header's content visibility state before sliding it up. And slide down the content only when it was not visible.
Here is the fiddle.
$(".fileHeader").on('click', function () {
var content$ = $(this).next(),
isContentVisible = content$.is(':visible');
$(".LST_Documents:visible").slideUp().promise().done(function () {
if ( ! isContentVisible ) {
content$.slideDown();
}
});
});
How 'bout a simple condition:
$(".fileheader").on('click', function() {
var next = $(this).next();
if(next.is(':visible'))
{
next.slideUp();
}
else
{
$(".LST_Documents:visible").slideUp().promise().done(function() {
next.slideDown();
});
}
});

Simplify my menu animation code

I've got a bunch of 'project' divs that I want to expand when they're clicked on. If there's already a project open, I want to hide it before I slide out the new one. I also want to stop clicks on an already open project from closing and then opening it again.
Here's an example of what I mean (warning - wrote the code in the browser):
$('.projects').click(function() {
var clicked_project = $(this);
if (clicked_project.is(':visible')) {
clicked_project.height(10).slideUp();
return;
}
var visible_projects = $('.projects:visible');
if (visible_projects.size() > 0) {
visible_projects.height(10).slideUp(function() {
clicked_project.slideDown();
});
} else {
clicked_project.slideDown();
}
});
Really, my big issue is with the second part - it sucks that I have to use that if/else - I should just be able to make the callback run instantly if there aren't any visible_projects.
I would think this would be a pretty common task, and I'm sure there's a simplification I'm missing. Any suggestions appreciated!
slideToggle?
$('.projects').click(function() {
var siblings = $(this).siblings('.projects:visible');
siblings.slideUp(400);
$(this).delay(siblings.length ? 400 : 0).slideToggle();
});
Used a delay rather than a callback because the callback is called once per matched item. This would lead to multiple toggles if multiple items were visible.
Like this?
$(".projects")
.click(function () {
var a = $(this);
if (a.is(":visible")) return a.height(10)
.slideUp(), void 0;
var b = $(".projects:visible");
b.size() > 0 ? b.height(10)
.slideUp(function () {
a.slideDown()
}) : a.slideDown()
})

Categories

Resources