I have created this function but there are two things that are not working and, after a while trying to find why, I can't find the reason.
First, it should take the height from .bar-info, but is not. It gets -10, instead of 100px
Second, when the page loads (and on resize), it should run this function and get the height, but it doesn't. It works on resize, but not on ready
onResize = function() {
if($(window).width() < 1000) {
//Set height based in number of bars
$('.vert .bars').each(function(){
var length = $(this).find(".bar-info").length;
var info = $(this).find(".bar-info").height(); // 1. Not taking the correct height
var height = (info * length) + 1270 + "px";
$(this).parent().css({"height":height}); // 2. Wrong height just on load
});
} else {
$('.vert .bars').each(function(){
$(this).parent().css({"height":"1200px"});
});
}
}
$(document).ready(onResize); // Why it doesn't work?
$(window).resize(onResize); // This works
HTML:
<div class="container vertical flat vert">
<div class="bars">
<div class="bar-general">
<div class="bar-info">Content</div>
</div>
</div>
</div>
Related
I'm trying to make a simple static webpage to accompany my research paper. While looking for solutions I stumbled upon scrollama.js. On the surface it does everything I want, but I just can't figure out how to add multiple charts (a single chart for example works since I replace the contents of the chart div). So how would one insert several simple d3 graphs into the scrollama.js demo? I'm guessing it's a javascript solution and my javascript knowledge is severely limited.
I would be grateful for any suggestions.
Also a jsfiddle of the demo I found while searching for any related scrollama materials:
https://codepen.io/bclinkinbeard/pen/OOKXjz
html
<section id='intro'>
<p class='intro__overline'>
<a href='https://github.com/russellgoldenberg/scrollama'>scrollama.js</a>
</p>
<h1 class='intro__hed'>Demo: Sticky Graphic</h1>
<p class='intro__dek'>
Start scrolling to see how it works.
</p>
</section>
<section id='scroll'>
<div class='scroll__graphic'>
<div class='chart'>
<p>0</p>
</div>
</div>
<div class='scroll__text'>
<div class='step' data-step='1'>
<p>STEP 1</p>
</div>
<div class='step' data-step='2'>
<p>STEP 2</p>
</div>
<div class='step' data-step='3'>
<p>STEP 3</p>
</div>
<div class='step' data-step='4'>
<p>STEP 4</p>
</div>
</div>
</section>
<section id='outro'></section>
<div class='debug'></div>
And js
// using d3 for convenience
var container = d3.select("#scroll");
var graphic = container.select(".scroll__graphic");
var chart = graphic.select(".chart");
var text = container.select(".scroll__text");
var step = text.selectAll(".step");
// initialize the scrollama
var scroller = scrollama();
// generic window resize listener event
function handleResize() {
// 1. update height of step elements
var stepHeight = Math.floor(window.innerHeight * 0.75);
step.style("height", stepHeight + "px");
// 2. update width/height of graphic element
var bodyWidth = d3.select("body").node().offsetWidth;
graphic
.style("width", bodyWidth + "px")
.style("height", window.innerHeight + "px");
var chartMargin = 32;
var textWidth = text.node().offsetWidth;
var chartWidth = graphic.node().offsetWidth - textWidth - chartMargin;
chart
.style("width", chartWidth + "px")
.style("height", Math.floor(window.innerHeight / 2) + "px");
// 3. tell scrollama to update new element dimensions
scroller.resize();
}
// scrollama event handlers
function handleStepEnter(response) {
// response = { element, direction, index }
// add color to current step only
step.classed("is-active", function(d, i) {
return i === response.index;
});
// update graphic based on step
chart.select("p").text(response.index + 1);
}
function handleContainerEnter(response) {
// response = { direction }
// sticky the graphic (old school)
graphic.classed("is-fixed", true);
graphic.classed("is-bottom", false);
}
function handleContainerExit(response) {
// response = { direction }
// un-sticky the graphic, and pin to top/bottom of container
graphic.classed("is-fixed", false);
graphic.classed("is-bottom", response.direction === "down");
}
function init() {
// 1. force a resize on load to ensure proper dimensions are sent to scrollama
handleResize();
// 2. setup the scroller passing options
// this will also initialize trigger observations
// 3. bind scrollama event handlers (this can be chained like below)
scroller
.setup({
container: "#scroll",
graphic: ".scroll__graphic",
text: ".scroll__text",
step: ".scroll__text .step",
debug: true
})
.onStepEnter(handleStepEnter)
.onContainerEnter(handleContainerEnter)
.onContainerExit(handleContainerExit);
// setup resize event
window.addEventListener("resize", handleResize);
}
// kick things off
init();
I believe that the only way is instantiate scrollama more than once:
var scroller1 = scrollama();
var scroller2 = scrollama();
See example here:
https://github.com/russellgoldenberg/scrollama/blob/master/dev/multiple.html
I've rather roughly built this website which uses an effect similar to the iOS Safari tab view to look at various pages of a virtual book. Everything is working fine apart from the fact that I can't centre each page in the visible viewport. For example if you scroll down to the final 'page' and click on it, it jumps to the top of the document, instead of staying in the centre of the visible viewport.
I think this is to do with the fact that the scrollable div uses overflow-y:scroll, but I just can't figure out for the life of me how to fix the problem.
Any help would be greatly appreciated!!
Here's my jQuery:
jQuery(document.body).on('click', '.page', function() { //Change to touchstart
// Generate number between 1 + 2
var randomClass = 3;
var randomNumber = Math.round(Math.random() * (randomClass - 1)) + 1;
// Initialise & Random Number
jQuery(this).addClass("activated").addClass('scaled-' + randomNumber);
// Exiting - Reset All
jQuery(document.body).on('click', '.activated', function() { //Change to Touchstart
jQuery(this).removeClass("activated scaled-1 scaled-2 scaled-3");
});
});
And here is a jsfiddle with all my code in it so you can get a better idea of what I'm trying to achieve.
https://jsfiddle.net/ontu1ngq/
Thanks!
You need to get the amount that #wrapper has been scrolled, so that you can use that to set the top of the .page accordingly. Then, when you remove the .activated class, you will just need to remove the inline top style.
jQuery(document.body).on('click', '.page', function() {
var randomClass = 3;
var randomNumber = Math.round(Math.random() * (randomClass - 1)) + 1;
jQuery(this).addClass("activated").addClass('scaled-' + randomNumber);
var wrapper_scrollTop = $("#wrapper").scrollTop(); //gets amount scrolled
var half_wrapper = $("#wrapper").height()*(0.5); //50% of wrapper height
jQuery(this).css("top",half_wrapper+wrapper_scrollTop);
jQuery(document.body).on('click', '.activated', function() {
jQuery(this).removeClass("activated scaled-1 scaled-2 scaled-3");
jQuery(this).css("top","") //returns top to original value specified in css
});
});
Check out this working fiddle: https://jsfiddle.net/tardhepc/1/
I am using equalHeightColumns.js to provide a cross browser equal height, which works fine until I need to have 2 sets of equal height.
So at the moment I have:
$(".row").each(function(){
$(this).find(".equalHeight").equalHeightColumns();
});
<div class="row">
<section class="equalHeight"></section>
<section class="equalHeight"></section>
</div>
<div class="row">
<section class="equalHeight"></section>
<section class="equalHeight"></section>
</div>
As you can see I dont want everything with the equalHeight to have the same height only inside the same row.
The problem is that now I need to change the mark up and dont have the row to reference. Is it possible to make this work like the lightbox rel='group2' plugin so that I can group the equalHeight elements via attribute.
E.g: this would be
<section class="equalHeight" rel="group1"></section>
<section class="equalHeight" rel="group1"></section>
<section class="equalHeight" rel="group2"></section>
<section class="equalHeight" rel="group2"></section>
equalHeightColumns.js
/*!
* equalHeightColumns.js 1.0
*
* Copyright 2013, Paul Sprangers http://paulsprangers.com
* Released under the WTFPL license
* http://www.wtfpl.net
*
* Date: Thu Feb 21 20:11:00 2013 +0100
*/
(function($) {
$.fn.equalHeightColumns = function(options) {
defaults = {
minWidth: -1, // Won't resize unless window is wider than this value
maxWidth: 99999, // Won't resize unless window is narrower than this value
setHeightOn: 'min-height', // The CSS attribute on which the equal height is set. Usually height or min-height
heightMethod: 'outerHeight',// Height calculation method: height, innerHeight or outerHeight
delay: false,
delayCount: 100
};
var $this = $(this); // store the object
options = $.extend({}, defaults, options); // merge options
// Recalculate the distance to the top of the element to keep it centered
var resizeHeight = function(){
// Get window width
var windowWidth = $(window).width();
// Check to see if the current browser width falls within the set minWidth and maxWidth
if(options.minWidth < windowWidth && options.maxWidth > windowWidth){
var height = 0;
var highest = 0;
// Reset heights
$this.css( options.setHeightOn, 0 );
// Figure out the highest element
$this.each( function(){
height = $(this)[options.heightMethod]();
if( height > highest ){
highest = height;
}
} );
// Set that height on the element
$this.css( options.setHeightOn, highest );
} else {
// Add check so this doesn't have to happen everytime
$this.css( options.setHeightOn, 0 );
}
};
// Call once to set initially
if (options.delay){
setTimeout(resizeHeight, options.delayCount);
} else {
resizeHeight();
}
// Call on resize. Opera debounces their resize by default.
$(window).resize(resizeHeight);
};
})(jQuery);
If you want an automatic script, you need to do a recursive function like that :
var $all = $('.equalHeight'),
arrEqualH = [];
recursiveFilter()
function recursiveFilter(){
var attr = $all.first().attr('rel');
arrEqualH.push($('[rel='+attr+']'));
$all = $all.not('[rel='+attr+']');
if($all.length) recursiveFilter()
}
$.each(arrEqualH, function(){
this.equalHeightColumns();
})
Fiddle : http://jsfiddle.net/2w9tq/
You could try that:
$(".row").each(function(){
$(this).find(".equalHeight[rel='group1']").equalHeightColumns();
$(this).find(".equalHeight[rel='group2']").equalHeightColumns();
});
function jsiBoxAdjustTop()
{
var top
if ( jsiBox.preloadImg.height <= 699){
top = 216;
}
else{
top = 17;
}
jsiBox.boxNode.style.top = (top) + 'px';
}
I'm using that function to adjust a div's top position depending on the image that is in it's height. It's on a light box sort of script so every time I click the next button, a new image which could either be taller or smaller appears. It's working alright and it adjusts its position when the image is taller but my problem is it just jumps to that position. I'm really new to javascript so can anyone help me out to make this as if it's travelling/animating to it's position? I tried using setTimeOut but I think I was doing it wrong. I'd really love to know what I'm doing wrong.
Here's the full script if that helps. Link
you can use jQuery or YUI to do animate, such as
jQuery(jsiBox.boxNode).animate({'top': top}, 3000);
or you can write some simple code with setTimeout just for this case;
following code assume the begin top is 0.
var boxStyle = jsiBox.boxNode.style;
function animateTop(to) {
boxStyle.top = parseInt(boxStyle.top, 10) + 1 + 'px';
if (parseInt(boxStyle.top, 10) != to) {
setTimeout(function() {
animate(to);
}, 50);
}
}
animateTop(top);
I want to know what's the best technique to slide an element just like in these examples:
http://demos.flesler.com/jquery/localScroll/#section1c
But with Pure Javascript so NOT jQuery or any library.
Example structure
<div id="holder">
<div id="bridge" onclick="slide('content')">Click to slide</div>
<div id="content" style="display:block;">The content</div>
</div>
So if I click on id=bridge the id=content will slide up and sets it's display to none and If I click on it again then sets it's display to block and slides down;
The sliding animation itself, like all animation in javascript, is done using timer functions: setTimeout or setInterval. For simple effects like this I always prefer setTimeout since it's easier to end the animation sequence compared to setInterval. How it works is to change CSS attribute values using setTimeout:
// move the content div down 200 pixels:
var content = document.getElementById('content');
function moveDown () {
var top = parseInt(content.style.marginTop); // get the top margin
// we'll be using this to
// push the div down
if (!top) {
top = 0; // if the margin is undefined, default it to zero
}
top += 20; // add 20 pixels to the current margin
content.style.marginTop = top + 'px'; // push div down
if (top < 200) {
// If it's not yet 200 pixels then call this function
// again in another 100 milliseconds (100 ms gives us
// roughly 10 fps which should be good enough):
setTimeout(moveDown,100);
}
}
That's essentially the basics of animation in javascript. The idea is very simple. You can use any CSS style attribute for animation: top and left for absolutely or relatively positioned elements, margins like my example, width, height, transparency etc.
Now, as for what to use in your specific case depends on exactly what your intentions are. For example, the simplest thing to do what you describe would be to change the div height until it becomes zero. Something like:
function collapseContent () {
var height = parseInt(content.style.height);
if (!height) {
height = content.offsetHeight; // if height attribute is undefined then
// use the actual height of the div
}
height -= 10; // reduce height 10 pixels at a time
if (height < 0) height = 0;
content.style.height = height + 'px';
if (height > 0) {
// keep doing this until height is zero:
setTimeout(collapseContent,100);
}
}
But that's not how the example jQuery plugin does it. It looke like it moves the element by shifting its top and left style attribute and hides content off screen by using a container div with overflow:hidden.
My solution uses a css transition:
<style type="text/css">
#slider {
box-sizing: border-box;
transition: height 1s ease;
overflow: hidden;
}
</style>
<div id="slider" style="height: 0">
line 1<br>
line 2<br>
line 3
</div>
<script>
function slideDown(){
var ele = document.getElementById('slider');
ele.style.height = "3.3em";
// avoid scrollbar during slide down
setTimeout( function(){
ele.style.overflow = "auto";
}.bind(ele), 1000 ); // according to height animation
}
function slideUp(){
var ele = document.getElementById('slider');
ele.style.overflow = "hidden";
ele.style.height = "0";
}
</script>