Trying to create an accordion which remains readable - javascript

I'm trying to create an accordion with a huge amount of text inside that remains readable.
I found this useful function, but it has a problem - if the user reloads the page it doesn't work anymore.
jQuery(document).ready(function($) {
$('.eael-accordion-header').click(function() {
var pane = $(this);
setTimeout(function() {
var $panel = pane.closest('.eael-accordion-list');
$('html,body').animate({
scrollTop: $panel.offset().top - 100
}, 500);
}, 300);
});
});
I have tried changing:
jQuery(document).ready(function($) { ... })
by
jQuery(window).on("load", function($) { ... })
But if I do that, the code doesn't works anymore and it says that $ is not a function.
I really hate jQuery, because I don't understand it at all. How can I translate this function into plain JavaScript, please?

Related

Bind function blocking click function from working?

I have a few click functions in my code that aren't working since I added the .bind() function. I don't know if that's actually the problem, but I can't think of anything else it would be.
The way the code is supposed to work is:
load data from xlsx file
load content from a different html file
runData()
proceed as normal (click functions as needed)
Here's the JS:
oReq.onload = function(e)
{
// doing something... //
$(document).trigger('complete');
}
jQuery(document).ready(function()
{
$('#videoButton').click(function()
{
$('html, body').animate(
{
scrollTop: $("#video").offset().top - 225
}, 1000);
});
// BACK TO TOP
$('#toTop').click(function()
{
$('html, body').animate(
{
scrollTop: $("#about").offset().top
}, 1000);
});
});
$(document).bind('complete', function()
{
console.log(jobs); //global variable
console.log(sponsors); //global variable
setTimeout(function()
{
runData(jobs);
}, 0);
});
The .bind() was not the issue, it was because the button was added dynamically. I was able to fix it by changing
$('#videoButton').click(function()
to:
$(document).on('click', '#videoButton', function()

smoothState.js conflicting with other plugins

I have managed to implement the smoothState.js plugin on my website and it works nicely, but my other very simple jQuery plugin will not work, wich starts with:
$(document).ready()
I need to refresh the page in order for it to work again.
I've read the smoothState documentation and it says I should wrap your plugin initializations in a function that we call on both $.fn.ready() and onAfter — but I'm farely new to programming, so I'm asking for your help.
How can I make my jQuery plugins work with smoothState?
You need to wrap scripts that are initiated with $(document).ready() in a function, and then call that function when you need it.
For example, let’s say this is your current script:
$(document).ready(function() {
$('.btn--homepage').click(function(e) {
e.preventDefault();
var goTo = $(this).attr('href');
$('#page').addClass('is-exiting');
$(this).addClass('exit-btn');
setTimeout(function() {
window.location = goTo;
}, 260);
});
});
It’ll work fine when the page loads as it’s wrapped in $(document).ready(function()), but as the page won’t be reloading when using Smoothstate, we need a way to call the snippet both when the page originally loads and when smoothstate loads content. To do this we’ll turn the above snippet in to a function like this:
(function($) {
$.fn.onPageLoad = function() {
$('.btn--homepage').click(function(e) {
e.preventDefault();
var goTo = $(this).attr('href');
$('#page').addClass('is-exiting');
$(this).addClass('exit-btn');
setTimeout(function() {
window.location = goTo;
}, 260);
});
};
}(jQuery));
As you can see, we’ve swapped $(document).ready(function()) with the function wrapper, everything else stays the same.
So now we’ve got a function all we need to do is call it when the page loads and in Smoothstate.
To call it when a page loads all we need to do is this:
$(document).ready(function() {
$('body').onPageLoad();
});
And to trigger it in Smoothstate we need to call it in the InAfter callback like this:
onAfter: function($container) {
$container.onPageLoad();
}
And here's an example Smoothstate script showing where to put the onAfter callback:
$(function() {
var $page = $('#main');
var options = {
prefetch : true,
pageCacheSize: 4,
forms: 'form',
scroll: false,
onStart: {
duration: 1200,
render: function($container) {
$container.addClass('is-exiting');
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 0,
render: function($container, $newContent) {
$container.removeClass('is-exiting');
$container.html($newContent);
$('html, body').scrollTop(0);
}
},
onAfter: function($container) {
$container.onPageLoad();
}
};
var smoothState = $('#main').smoothState(options).data('smoothState');
});
Happy to provide further assistance if needed.

How to adjust div location on animate

In a webapplication I'm working on, when you click on a listitem, a div pops out.
You can find an example here.
How can I adjust the top of the div to the listitem?
The div (#home in the example) has to pop out with the top next to the list item.
$(function () {
$("#home_link").click(function () {
$("#home").animate({width: 'toggle'}, 500);
});
});
$(function () {
$("#edit_link").click(function () {
$("#home").animate({width: 'toggle'}, 500);
});
});
So, I cleaned up some of it and reorganized it. Basically, I marked a container element (which holds both the navs and the content), and use that to determine the desired offset. I made everything more generic so you can just add more hyperlinks as you need! Hopefully this is helpful, let me know if you have any questions about why I did things this way, or how something works.
jsFiddle
$(function () {
$("#list a").click(function () {
var $this = $(this);
var $container = $this.closest('[data-id="container"]');
var $target = $($this.attr('href'));
$target.css('margin-top', $this.offset().top - $container.offset().top);
$target.animate({width: 'toggle'}, 500);
});
});

faking a Gif with javascript/jquery

I have a function that hides and shows divs on scroll based on pageY position, but I also need the ability to have it automatically hide and show divs in order(only the ones with children), sort of like a fake animated Gif, looping forever.
I tried this:
function autoPlay() {
$('.conP').each(function(){
if ($(this).children().length > 0) {
setInterval(function(){
$(this).show().delay('100').hide();
},300);
}
});
}
which is not returning any errors, but it's not hiding or showing any of the divs with class="conP".
Any suggestions as to what I'm doing wrong/how I could improve this?
try this -
function autoPlay() {
$('.conP').each(function(){
if ($(this).children().length > 0) {
var $that = $(this);
setInterval(function(){
$that.show().delay('100').hide();
},300);
}
});
}
You have an incorrect reference to this in your setInterval closure. Refer to "How this works" in JavaScript Garden.
In your case you should save the reference to this in a variable:
$('.conP').each(function() {
var $element = $(this);
setInterval(function () {
$(element).show().delay('100').hide();
}, 300);
});
Or, better use the first argument passed to each, which is equal to $(this) in this case.
Not sure it's a great idea to run intervals inside loops, but I'm guessing the issue is scope inside the interval function :
function autoPlay() {
$('.conP').each(function(i, elem){
if ( $(elem).children().length ) {
setInterval(function(){
$(elem).show().delay(100).hide();
},300);
}
});
}
I really appreciate all the help guys, I seem to have figured out the animation part:
setInterval( function() {
autoPlay();
},120);
function autoPlay() {
var backImg = $('#outterLax div:first');
backImg.hide();
backImg.remove();
$('#outterLax').append(backImg);
backImg.show();
}
By hiding whichever div is first, and removing it from-then appending it back into-the containing div, and showing the new first div, it animates quite nicely!

Scrolling and .addClass(); issues

I am working on a "one page" website with a fixed navigation and about 5 different pages inside the one document.
UPDATED WORKING LINK
http://www.coco-works.com/Archive/ LIVE VERSION
I'm having trouble with the active class addition. When you click Keep in Touch or Home, the class is not applied. As you can see from the live version, it's not function properly.
The page works something like this;
And here is the JavaScript;
$(document).ready(function() {
$('body').click(function(event) {
if (event.target.nodeName.toLowerCase() == 'a') {
var op = $(event.target);
var id = op.attr('href');
if (id.indexOf('#') == 0) {
$.scrollTo(id, 1000, {
offset: {
top: 75
},
axis: 'y',
onAfter: function() {
window.location.hash = id.split('#')[1];
}
});
}
return false;
}
});
$.fn.waypoint.defaults.offset = 75;
$('.section h1.page_name').waypoint(function() {
var id = this.id;
var op = $('#navigation a[href = "#' + id + '"]');
if (op.length) {
$("#navigation a").removeClass("active");
op.addClass('active');
}
});
});
I'm not a strong programmer. I've tried to edit it as best as I can and I'm just stuck. Any insight to fixing this would highly be appreciated.
Still looking for an answer, below couldn't fix the problem.
I'm not sure what the waypoints plugin was doing, but I've refactored your code and it is working for me. Note that I took out the call to .waypoints, and changed your $('body').click() handler to be a more specific handler on the navigation link elements. This handler will scroll to each element and then will perform the removal and addition of the class correctly when the scrolling is done:
$(document).ready(function()
{
function highlightNav(navElement){
$("#navigation a").removeClass('active');
navElement.addClass('active');
}
$('#navigation a').click(function(event){
var nav = $(this);
var id = nav.attr('href');
$.scrollTo(id, 1000, {
offset: { top: -75 },
axis: 'y',
onAfter: function(){
highlightNav(nav);
}
});
return false;
});
$(window).scroll(function(){
if($(this).scrollTop() == 0){
highlightNav($("#navigation a[href*='home']"));
}
});
$.fn.waypoint.defaults.offset = 75;
$('.section h1.page_name').waypoint(function() {
var id = this.id;
var op = $('#navigation a[href = "#' + id + '"]');
if (op.length) {
highlightNav(op);
}
});
// Fancybox
$("a.zoom").fancybox({
'overlayShow' : false,
'transitionIn' : 'elastic',
'transitionOut' : 'elastic'
});
$("a.outside_shade").fancybox({
'titlePosition' : 'outside',
'overlayColor' : '#000',
'overlayOpacity' : 0.9
});
$("a.inside_white").fancybox({
'titlePosition' : 'inside'
});
$("a.inside_shade").fancybox({
'titlePosition' : 'over'
});
// validation
$("form").validate();
// nivo slider
$('#slider').nivoSlider();
});
In the html I added a default active class to the first link:
<div id="navigation">
<ul>
<li>Home</li>
<li>Portfolio</li>
<li>Who Are We?</li>
<li>Our Services</li>
<li>Features</li>
<li>Keep in Touch</li>
</ul>
</div>
Also I noticed on the page you have your css defined before the reset.css is called in. That's usually bad practice you might want to make sure reset.css is always the very first css file pulled in. It doesn't appear to have affected the page much but sometimes you'll get weird results doing that.
I made a jsfiddle of the results here: http://jsfiddle.net/RNsFw/2/
the waypoints plugin isn't needed anymore I think. I didn't change the fancybox or validation stuff because i'm not sure what those are doing and it wasn't really part of your issue.
I tested it in firefox and Chrome. Let me know if you have questions :)
http://jsfiddle.net/vCgy8/9/
This removes the dependency on scrollTo, and the waypoints plugin.
$('body').click(function(event)
{
if(event.target.nodeName.toLowerCase() == 'a')
{
var op = $(event.target);
var id = op.attr('href');
if(id.indexOf('#') == 0)
{
destination = $(id).offset().top;
$("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination}, 1000, function() {
var hash = id.split('#')[1];
window.location.hash = hash;
});
}
return false;
}
});
$(window).scroll(function (event){
makeActive();
});
function makeActive(){
var y = $(this).scrollTop();
if(y!==0){
$('.page_name').each(function(){
var curPos = parseInt($(this).offset().top - y);
if(curPos <= 0){
var op = $('#navigation a[href = "#'+$(this).attr('id')+'"]');
$("#navigation a").removeClass("active");
op.addClass('active');
}
});
}else{
$("#navigation a").removeClass("active");
$("#navigation a:first").addClass('active');
}
}
makeActive();
This may be completely unrelated, but I had a similar problem yesterday - where, in the callback of an event handler, jQuery operations weren't being performed in that scope but if you threw the code into something like:
setTimeout(function() {
$(selector).addClass('foo');
}, 0);
it would work - similar to how $.animate() functions (ish) if you call $(selector).stop().animate() without the queue param being false, eg:
$(selector).stop();
$(selector).animate({ foo }, { no queue:false here });
// ^ fail
$(selector).stop();
setTimeout(function() {
$(selector).animate({ foo }, { no queue:false here either });
}, 0);
// ^ success
The problem, completely unrelated to the above example though similar in behavior/functional hack, turned out to be the method of binding - in my case I had been using $.bind() - but then I refactored this to use $.delegate() ($.live() would work also) and it functioned as expected.
Again, not sure if this related, but figured I'd pass that along just in case. Unsure if it's a bug or just me not properly understanding some of the subtler parts of jQuery.
The problem is not in your js code, but in your css/page layout.
Or maybe the problem is that you are using the waypoint plugin and you might not want to for this particular page. (As you will see you also have trouble hitting the "Home" waypoint again once you have left it, because of the offset you use.)
The thing is, the waypoint plugin won't trigger until the target element you are scrolling to is in the very top of the browser window, with respect to the offset that is. "Keep in touch" will never get to the top unless your browser window is small enough that the "keep in touch" section takes up the entire browser window (minus the offset).
You can see it visualized here:

Categories