jQuery | Add/Remove Class on Click | Best Practise - javascript

today I had to set a number of images as a galery.
On the mobile version of this site I had to stack the images because it wasn´t possible to show them in a row of 4 or something.
Yet the images were quite high (350px) for a mobile view so I´ve decided to shrink them down to a height of 100px and make them clickable to extend to their full height.
I did this just by adding or removing a class called "extended" which would set the height to 350px again.
The JavaScript I used for this works but yet I´m not sure if this is what you would call best practise or if it could be done easier:
$('.galery__img--fragrance').on('click', function() {
if($(this).hasClass('extended')) {
$(this).removeClass('extended');
} else {
$(this).parent().find('.extended').removeClass('extended');
$(this).addClass('extended');
}
});
I hope this question isn´t to redundant but I´m quite new to JS/jQuery and I want to do it right :-)
Edit: Maybe I should´ve mentioned that I wanted to make images collapse to a height of 100px if they were clicked again or if another image was clicked

Use .toggleClass() function to add/remove class simultanuously:
$('.galery__img--fragrance').on('click', function() {
$(this).toggleClass('extended');
});

Related

toggling element with javascript is making the element appear too small until I resize the browser

edit
Since originally posting this question, I've gone down a couple more paths trying to solve the issue. It's still not solved, but now my questions are different. The original question is below, and then I'll add a section below that with updates.
original question
I'm working on a Rails 4 application and having some trouble with JavaScript and the Chartkick gem.
I have two JavaScript functions that make it so that a user can click an icon and an element will drop down below the icon/appear on the page, and the icon will switch from a right-pointing arrow to a down-pointing arrow. The code is this:
function ReverseDisplay(d)
{
if(document.getElementById(d).style.display == "none")
{
document.getElementById(d).style.display = "block";
}
else
{
document.getElementById(d).style.display = "none";
}
}
$(function() {
$('.toggle-icon').click(function() {
$(this).find('i').toggleClass('fa-arrow-circle-o-right fa-arrow-circle-o-down');
});
});
And the haml:
%a{href: "javascript:ReverseDisplay('toggle-stats#{item.id}')", class: 'toggle-icon'}
%i.fa.fa-arrow-circle-o-right
%div{id: "toggle-stats#{item.id}", style: "display: none;"}
= the items to be displayed
It works. However, I expect the items that drop down to take up the full width of the page, like so:
But instead, when I first click the toggle icon, they show up squished, like this:
If I then resize the browser just a tiny bit, the graph pops out to full-width, and it stays that way no matter what I do from there. I can't figure out how to get ahold of the generated mark-up, because this chart comes from Chartkick, as a gem. The generated html in the browser has this line:
<div dir="ltr" style="position: relative; width: 300px; height: 300px;">
Where the width: 300px is what's being changed to width: 1000px when I change the browser size. I don't have to change the browser size permanently or significantly. Once that width has changed to 1000px the first time it stays there - but the minute I refresh the page and click the icon to toggle the chart again, it's back to 300px. I don't know how to hook into this div, because it's generated by the gem and I don't know how to add a class to it. I've tried adding styling to a parent element that ensures all of that parent elements' children are width: 100%, but that doesn't do anything.
Anyway, I don't think that adding a class to it is the solution here. I just have no idea what is - I don't JavaScript incredibly well. I'm pretty much completely new to all front-end work as a whole. What's going on here, and how can I make these charts always be the full width of the page when they're toggled?
Notes: Am testing this in Chrome. I tested in Firefox and it does the same thing.
OK, I'm starting to wonder if this has something to do with the fact that I'm using a JavaScript function in order to capture dynamic item IDs - a page may have any number of these toggle-able charts, and so calling a jQuery function on each id seems impossible, because I don't know what ID is.
I removed the jQuery call, however, and the problem persists.
One of those times when rubber-ducking the Stack Overflow question box has not yet answered my question. So I guess I'll submit and hope for outside help here. :/
adjusted question
This question in the Github issues for Chartkick has lead me down a different path. The solution is not necessarily in attempting to restyle the charts at all. Instead, what I'm trying to do is trigger a resize event, because the chart automatically regenerates when the browser window is resized. This is both what's causing the problem and where the solution seems to lie.
My code:
.row
.col-sm-12
%h3.title-block.second-child
Stats by Video
.panel-groupd#faqList
- #claim.presenter.videos.each_with_index do |video, index|
.panel.panel-default
.panel-heading
%h4.panel-title
%a.chart{data: { toggle: "collapse", parent: "#faqList" }, href: "#video#{index}" }
= "'#{video.title}' at #{video.event.display_name} on #{display_date(video.recorded_at)}"
%div.panel-collapse.collapse{id: "#video#{index}"}
.panel-body
- if video.impressions.count > 0
%h4
Impressions by Hours (24 hours)
= line_chart video.impressions.group_by_day(:created_at, range: 1.day.ago...Time.now).count
...a couple more charts
:javascript
$(".chart").click(function() {
window.dispatchEvent(new Event('resize'));
});
So the intention here is that when I click the .panel-heading, this both drops down the .panel-body with the charts in it and resizes the window, which makes the charts resize correctly (or, rather, should).
It kind of works, in that, when I first click the .panel-heading trigger, it does not resize the charts, but when I click it again, the charts are resized perfectly for a split second... just before they become hidden from view again. :(
I've tried adding a time out to the javascript, like so:
:javascript
$(".chart").click(function() {
setTimeout(1000);
window.dispatchEvent(new Event('resize'));
});
But it doesn't appear to do anything at all.
So what I'm wondering here is how to get this resize event to work once the dropdown .panel-body is out so that the charts will resize appropriately on their own.
Here's a screen cast of the current problem, in case I didn't describe it clearly enough:
https://youtu.be/5quMGABoDs8
I don't know anything about Ruby or Chartkick, but in order to override that inline styling, you would have to use !importantin the css.
So, if you try that technique of giving all the children of the parent element width: 100% again, you might want to implement it something like this:
.importantRule { width: 100% !important; }
$( "parentElement > childElement" ).addClass('importantRule');
(First line goes in your CSS file, second line goes in JS)

Best approach in sliding image and appending some room for content

I'm working with a jquery and I have this image that is the main problem. I googled it but came up with nothing. Here is my content for example.
And when the guy(in the picture above) is being click I want it to slide to the left side and will looked like this. Please see image below.
So what I'm thinking is
1. using addClass and removeClass using jquery or
2. just use jquery .slide or toggle function?
If there's a solution as such how could it be done? Since I only know is using addClass tho. And also what I'm planning is when the image exceeds 800px then the girl(in the image) will be send to back of the guy image.
What you are trying to do is create a mask around the guy. The scope of this question is beyond masking. Most methods of masking don't have large browser support at this moment so posting more on this would be disingenuous. But worth googling otherwise you can use the transform property to move the picture to the left. But you won't get the results you are looking for..
But there is the option of masking the picture in Photoshop and saving it as a PNG. And then utilizing the translate CSS method to move the image to left. This is your best option. But the details of either of these methods are out of scope for this question.
Cut this guy from image and put in another div at needed position. Put blue box between those two images and use slide function. You can cut the guy from his head i think.
Basically you need to have an html structure like this:
<div id='container'>
<div id='couple'></div>
<div id='mask'></div>
</div>
Initially in your css:
#mask {
display: none;
}
And, of course, you have to align horizzontally this two div.
Your jquery will have a behavior like this:
$('#couple').on('click', slide);
var slide = function() {
$target = $('#container');
$mask = $('#mask');
$mask.fadeIn();
$target.animate({
left: "+=50"
}, 500, function() {
/* callback on end*/
});
}
For complete documentation of animate check api jquery.

Viewfinder split layout full page slider effect

I am trying to build a split layout gallery where the images will only be fully revealed when the user clicks on a button. I managed to split the screen in two and show the pictures at full size but I am struggling to find an effective way to actually reveal the other side of the image without resizing.
This is where I am at right now:
http://jsfiddle.net/Bb844/
I have already tried the jQuery slideToggle() method but it would not deliver the result I am looking for. The idea is not to overlap class="left" with class="right", but rather, to drag class="left" –and vice-versa– off the viewfinder with an animation effect similar to that of the slideToogle method.
The function should be activated through the class="square" element.
Is there any way to achieve this?
How does this look?
I changed your HTML a bit and made your CSS fit the new HTML setup. The only thing to note is the jQuery is set up to where you need to have the .side a .square is affecting directly after the .square. Then I used the following to do the sliding action you're looking for
$('.square').click(function() { // Fire when square is clicked
if(!$(this).hasClass("active")) { // If not fullscreen already
$(".active").removeClass("active"); // Remove other active class(es)
$(this).addClass("active"); // Make this have class active
$('.side').stop().animate({"width":"0%"}); // Shrink the other elements
// Make the nearest side full screen
$(this).nextAll(".side").stop().animate({ "width":"100%"});
} else { // If it's already open, put it back to the default
$(this).removeClass("active");
$(".side").stop().animate({"width":"50%"});
}
});

Only show DIV if on screen

I have a very long HTML page with 2000+ products. On old computers the page would freeze due to a lack on memory. If I change the CSS display to none to 50% of divs, the performance increases a lot.
So I wanted to have the display:block only when the div is onscreen.
I have tried to use the following script : http://www.teamdf.com/web/jquery-element-onscreen-visibility/194/
I have updated the on method to bind but it still doesn't work.
Would there be an elegant way to create a css class that only appear when on screen ?
You should try the onScreen Plugin.
This is how you would initialize it:
$('.product-item').onScreen({
doIn: function() {
// Do something to the matched elements as they come in
$(this).addClass('visible');
},
doOut: function() {
// Do something to the matched elements as they get off scren
$(this).removeClass('visible');
}
});
But I would definitely consider loading the products through ajax while the user scrolls.
This is called lazyloading and is a common technique.

SlideToggle imperfections

My slideToggle is a little jumpy at the bottom of the slide transition. Could that be because there is a button there or something. Any way to make it smoother. Tried using easing but not very successful. Any suggestions
click on video setup to see for yourself
The site
$(document).ready(function() {
$('.drop').click(function() {
$(this).parent().next('li.drop_down').slideToggle();
return false;
});
});
Give your li.drop_down a fixed width. This should clear it up. I don't remember the exact reason for this, but I just tested it on your site, and it works.
Right now the computed width is 217px so try that.
.drop_down {
width: 217px;
}
EDIT: Looks like you have a .drop_down2 and a .drop_down3 as well (maybe more). You would need to do the same for those. I'd suggest assigning a common class for each.
Try storing the height of each item before animating it, and then re-apply that height to the element just before starting the hiding animation.
Here's an article I wrote how with an example of doing this:
http://www.pewpewlaser.com/articles/jquery-smooth-animation
Fixed width didn't work for me, but what did was adding a clearfix class to the animated element, since I had some floated elements inside.

Categories

Resources