How to select element thats between ranges? - javascript

I have side bullets that are menu scrolling to section of onepage, i did a scroll animation but i would like to change class="active" between bullets when scrolling. I know it can be easly achieved by jQuery(body,window).scroll() with $('#scrollspymenu li').each() but its really bad way. I can break out of each() function but this way i still need to get from first li element to (for example) 5th li. I thought about getting all data-target elements to some array with save offsetTop and offsetTop+height and in scroll event i will check which element is on middle of the screen. ( i mean window scroll top position + 1/2 window height)
I have no idea how to make like some kind of timeline with sections with calculated range AND what function can select (based on input) element that is attached to 2 range values.
I'm also using scrollMagic, maybe it does it better? Still would like to use pure js or jquery for future use.
I'm sorry i couldnt form a good specific question but i tried my best.
my comment
(..) I want fastest possible way to get from scrolll event to proper element. Best possible performance of the page. It's stupid when u scroll, 1 scroll tick is 100x on scroll function, and every function goes every element. For 4 elements its checks elements 400 times...
JS
var page = $("html, body");
$('#scrollspymenu a, .go-to, .go-to2').click(function(event) {
event.preventDefault();
var target = $(this).attr('data-target');
if(target){
page.on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function(){
page.stop();
});
page.animate({ scrollTop: $(target).offset().top-50 }, 700, function(){
page.off("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove");
});
}
})
Html Side menu
<nav id="scrollspymenu">
<ul>
<li class="active"><span>Knauf Group</span></li>
<li><span>History</span></li>
<li><span>Values</span></li>
()...)
<li><span>Automobile industry</span></li>
<li><span>Solutions</span></li>
</ul>

First off, I am not 100% sure this resolves your issue, as the intent is not totally clear to me.
What THIS does is if you click on a menu, it scrolls to that associated target.
Also if you tab, shift-tab it scrolls to that associated target.
If you mouse over a menu, then scroll, it scrolls the target. I think you get the idea and if not a 100% solution perhaps you can build from this.
The console.logstuff should be removed eventually but will illustrate what is firing at what point for you.
var page = $("html,body");
$('#scrollspymenu').on('click scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove', 'a', function(event) {
// event.preventDefault();
event.stopImmediatePropagation();
var elem = $(this);
var target = elem.data('target');
$('.active').removeClass('active');
if (!!target) {
$(target).addClass('active');
elem.addClass('active');
console.log('in here');
page.off("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function() {
console.log('in stop');
page.stop(); // stop any animation
});
page.animate({
scrollTop: ($(target).offset().top - 50)
}, {duration:700, start:function() {
console.log('in callback', $(target).offset().top - 50);
page.on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove");
}});
}
})
#pagethings {
margin-left: 200px;
}
#contentbody {
float: right;
width: 100%;
background-color: #F0F0F0;
}
#scrollspymenu {
float: left;
width: 200px;
margin-left: -200px;
background-color: #CCCCCC;
/* fix to top */
position: fixed;
/* force scroll bars */
overflow: scroll;
}
.section {
margin: 1em;
padding-bottom: 4em;
}
#clearingdiv {
clear: both;
}
.active{ background-color: #EECCAA;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="pagethings">
<nav id="scrollspymenu">
<ul>
<li class="active"><span>Knauf Group</span></li>
<li><span>History</span></li>
<li><span>Values</span></li>
<li><span>Automobile industry</span></li>
<li><span>Solutions</span></li>
</ul>
</nav>
<div id="contentbody">
<div class="section sec-company-home sec-home-knaufgroup">My Home of my grand thing</div>
<div class="section sec-company-history">History of my grand thing</div>
<div class="section sec-company-values">Values of my grand thing</div>
<div class="section sec-company-automobile">My great car of my grand thing. I might put something bigger in here, pictures etc so I fake this with some text to make it bigger. The brown cow jumped over the crazy blue moon but why is that moon blue and how can that cow breathe when jumping over
a moon and why is it "over" the moon not "around" the moon for a literal quotation?</div>
<div class="section sec-company-solutions">Solution of my grand thing, drive my great car fast</div>
</div>
</div>

Related

Run Jquery only when an element is in the viewport

I'm trying to perform the Jquery function below when the element becomes visible in the viewport rather than on the page load. What would I need to change to allow that to happen? I'm using an external JS file to perform the Jquery, so keep that in mind.
Here's a piece of the HTML that is associated with the Jquery function -
<div class="skillbar clearfix " data-percent="70%">
<div class="skillbar-title" style="background: #FF704D;">
<span>Illustrator</span></div>
<div class="skillbar-bar" style="background: #FF704D;"></div>
<div class="skill-bar-percent">70%</div>
</div>
jQuery(document).ready(function(){
jQuery('.skillbar').each(function(){
jQuery(this).find('.skillbar-bar').animate({
width:jQuery(this).attr('data-percent')
},4000);
});
});
I once came across such problem and what I used is waypoints small library.
all you need is to include this library and do:
var waypoint = new Waypoint({
element: document.getElementById('waypoint'),
handler: function(direction) {
console.log('Element is in viewport');
}
})
Using CSS3 transitions instead of jQuery animations might be more performant and simpler. a cheap and nasty way of pushing it out of screen to demonstarate the effect.
There's a couple of things you'll need to do - firstly if you only want the animation to trigger when it's in the viewport then you'll need to check if anything is in the viewport on scroll. Then only update the bars width when it comes into view. If you want the effect to repeat every time it comes into viewport you'll need to set .skillbar-bar's width back to 0 if it's out of the viewport (just add an else statement to the viewport checking if)
I've added a 1000px margin-top and 400px margin-bottom in my example to .skillbar as a cheap and nasty way of demonstrating the effect
(function($){
$(document).ready(function(){
var $els = $('.skillbar'); // Note this must be moved to within event handler if dynamically adding elements - I've placed it for performance reasons
var $window = $(window);
$window.on('scroll', function(){
$els.each(function(){ // Iterate over all skillbars
var $this = $(this);
if($window.scrollTop() > $this.offset().top - $window.height()){ // Check if it's in viewport
$this.find('.skillbar-bar').css({'width' : $this.attr('data-percent')}); // Update the view with percentage
}
});
});
});
}(jQuery));
.skillbar{
margin-top: 1000px;
margin-bottom: 400px;
position: relative
}
.skillbar-bar{
transition: width 4s;
position: absolute;
height: 20px;
}
.skill-bar-percent{
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Scroll down 1000px :)
<div class="skillbar clearfix " data-percent="70%">
<div class="skillbar-title">
<span>Illustrator</span></div>
<div class="skillbar-bar" style="background: #FF704D; width: 20%"></div>
<div class="skill-bar-percent">70%</div>
</div>
This might work for you.
var el = $('.yourElement'),
offset = el.offset(),
scrollTop = $(window).scrollTop();
//Check for scroll position
if ((scrollTop > offset.top)) {
// Code..
}

Click Propagation failing in Jquery

For part of the site I'm working on, I have a set of sidebars that can pull out. To have them hide when the users are done with them, I've set up a div with a click event (see below) so that whenever the user clicks somewhere outside of the sidebar, the sidebar closes. The problem that I'm running into, however, is that the click event handler is grabbing the event, running its method, and then the click event seems to stop. I've tried using return true and a few other things I've found around here and the internet, but the click event just seems to die.
$('.clickaway').click(function() {
$('body').removeClass(drawerClasses.join(' '));
return true;
});
EDIT: Here is a fiddle with an example: https://jsfiddle.net/2g7zehtn/1/
The goal is to have the drawer out and still be able to click the button to change the color of the text.
The issue is your .clickaway layer is sitting above everything that's interactive, such as your button. So clicking the button, you're actually clicking the layer.
One thing you could do is apply a higher stacking order for elements you want to interact with, above the .clickaway layer. For example, if we apply position: relative, like this:
.show-drawerHotkey .ColorButton {
position: relative;
}
The element will now be in a higher stacking order (since it comes after the clickaway, and we've applied no z-index to clickaway)
Here's a fiddle that demonstrates: https://jsfiddle.net/2g7zehtn/5/
Using this somewhat famous SO answer as a guide, you can bind to the $(document).mouseup(); event and determine whether certain "toggling" conditions apply:
[EDIT] - Example updated to illustrate clicking a link outside of the containing div.
// Resource: https://stackoverflow.com/questions/1403615/use-jquery-to-hide-a-div-when-the-user-clicks-outside-of-it
var m = $('#menu');
var c = $('#menuContainer');
var i = $('#menuIcon');
i.click(function() {
m.toggle("slow");
});
$(document).mouseup(function(e) {
console.log(e.target); // <-- see what the target is...
if (!c.is(e.target) && c.has(e.target).length === 0) {
m.hide("slow");
}
});
#menuIcon {
height: 15px;
width: 15px;
background-color: steelblue;
cursor: pointer;
}
#menuContainer {
height: 600px;
width: 250px;
}
#menu {
display: none;
height: 600px;
width: 250px;
border: dashed 2px teal;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I'm a link outside of the container
<div id="menuContainer">
<div id="menuIcon"></div>
<div id="menu"></div>
</div>

Simple jquery slide element

I'm totally new in js and jq. I'am trying force my #cont div to change height on hover with animation and back to previous height without hover, but I dont know how to achieve that. In my test it should make an alert (or make other function), right?
http://jsfiddle.net/JJh9z/1773/
<div id='cont'>
<ul>
<li>an item</li>
<li>an item</li>
<li>an item</li>
<li>an item</li>
<li>an item</li>
</ul>
<div id='ruch'>HOVER</div>
</div>
#cont {
border: 1px solid #000;
height: 200px;
overflow:hidden;
position:relative;
}
#ruch {
position:absolute;
bottom:0px;
}
var result = $("#cont").height();
$('#ruch').hover(function(){
$('#cont').animate({height:'300px'}, 500);
});
if (result == 300) {
alert(result)
}
Your if statement only runs once when the script is first loaded, so no it won't alert each time someone hovers. it is not an event listener.
You need to add another event listener for when the mouse leaves the element (mouseout). See this modified code:
$('#ruch').hover(function(){
$('#cont').animate({height:'300px'}, 500);
});
$('#ruch').mouseout(function(){
$('#cont').animate({height:'200px'}, 500);
});
http://jsfiddle.net/JJh9z/1775/
http://api.jquery.com/hover/
You can specify a handleout event handler, in which you'd restore the element to its previous height.
You also should select not the 'HOVER' div (it's small) but a bigger element (like cont):
$('#cont').hover(
function () {
$('#cont').animate({
height: '300px'
}, 500);
},
function () {
$('#cont').animate({
height: '200px'
}, 500);
});
Here, I've specified a hover-out handler, and focused on 'cont' instead of 'ruch'
http://jsfiddle.net/JJh9z/1773/
There are several ways of doing this. One is to call the 'after animation completes function'. which takes another function as option.. the below example alerts 'Hii' after animating the height to 300px.
$( "#ruch").hover(function() {
$( "#cont" ).animate({
height: "300px"
}, {
duration: 500,
complete: function() {
alert('Hii');
}
});
});
To prevent multiple animations for one hover event since #ruch moves from under the mouse pointer during hover animation, use the following and a current version of jQuery:
var result = $("#cont").height();
$('#ruch').on( 'mouseenter', function(){
$('#cont').animate({height:'300px'}, 500, function() {
alert( result );
});
});
$('#cont').on( 'mouseleave', function(){
if( $(this).height() != result ) {
$(this).animate({height:result}, 500);
}
});
Once the #cont expands the mouse is no longer over #ruch and any slight movement would fire mouseleave and the #cont collapses. To prevent that, attach the mouseleave event to #cont as above.
You could play around with some webkit transitions as well, which is pretty easy.
The problem with adding an event listener for when the mouse leaves the even and queuing up an animation is that you can end up with a queue of many animations if you move your mouse crazily over the div, while this method will only do one animation.
#cont {
border: 1px solid #000;
height: 200px;
overflow:hidden;
position:relative;
-webkit-transition: 0.5s;
}
#ruch {
position:absolute;
bottom:0px;
}
$(document).on('mouseover', '#cont', function() {
document.getElementById('cont').style.height = 300;
});
$(document).on('mouseleave', '#cont', function() {
document.getElementById('cont').style.height = 200;
});

Set limit to div in scrollable table

Ok lets see if I can describe my problem in an understandable way.
Im building a schedule with an user column to the left and a timeline to the right.
The timeline holds schedule events. Each event holds a title. The timeline is scrollable in both directions.
When I scroll horizontally the events is slided underneath the user column, which they are supposed to do.
But, I would like to have the event title floating and still shown until the whole event is completely slided under. In other words, I want the user to always be able to se the event title regardless of how long the event is (as long as the event is visible).
I cant fix the title div on an specific position due to the both X and Y scroll feature?
I just want it to slide inside the event div with a margin left that is as long as the user column. Don't know how though. Maybe not a good solution?
I would attached some code but I have no idea how to approach this problem yet.
I did a "illustration" of the problem, hopefully that brings some clarity.
The first two rows is describing what it looks like now, the last two rows is describing what I want to achieve.
Using in this project:
jQuery,
JQuery DataTables,
AngularJS
I think this is what you need http://jsfiddle.net/fDyE2/3/
HTML
<div class="user">
<p>User</p>
</div>
<div class="timeline">
<div class="event">
<p class="title">Event 1</p>
</div>
</div>
CSS
div {
display:block;
position:relative;
}
.user, .timeline {
border:#000 dashed 1px;
float:left;
}
.user {
padding:17px 25px;
margin-right:10px;
}
.timeline {
padding:5px;
width:400px;
overflow:auto;
height:76px;
}
.event {
padding:5px;
background:orange;
width:800px;
height:51px;
}
Jquery
$(ducument).ready(function(){
var title = $(".title"),
target = $(".event").offset().left;
setInterval(function () {
if ($(".timeline").scrollLeft() > target) {
title.css({
"position": "fixed",
"top": (title.closest(".event").offset().top + 5) +"px",
"left": title.closest(".event").offset().right + "px"
});
} else {
title.css({
"position": "static",
"top": "auto",
"left": "auto"
});
}
}, 100);
});

How to make div stick near parent DIV

I saw on my local news website a feature like this:
Where the left div is sticked to main div, AND on scroll AND on windows resize it stays sticked there, and on scroll it moves up/down also sticked to main div
Sorry for bad english / explanation ( but I think you understood ).
You can see what I want to get in this link:
http://rus.delfi.lv/news/daily/abroad/papa-rimskij-obratilsya-s-tradicionnym-rozhdestvenskim-poslaniem-k-pastve.d?id=43988560 if you are not using any Adblock :)
Is there any special jquery plugin or it is achieved with simple CSS?
From my website, on the left is Facebook image that scrolls with page and on mouseover (jquery) it expands and shows the plugin box:
HTML
<div id="fbwindow">
<div class="fb-like-box" data-href="http://www.facebook.com/.../" data-width="292" data-show-faces="false" data-stream="true" data-show-border="true" data-header="true"></div>
</div>
CSS
#fbwindow { position: fixed;top:50%;margin-top:-200px;left:-292px;width:323px;height: 265px;z-index: 1000;text-align: left; }
#fbwindow div.fb-like-box { background: #FFF; }
#fbwindow > a { display: block;float: right;width: 31px;height: 187px;background: url('/layout/fb-window.png') no-repeat; }
(optional / not needed rollover effect) jQuery
$('#fbwindow_a').mouseenter(function() {
$("#fbwindow").stop().animate({
left: '0'
}, 100, function() {
//$(this).removeClass("left").addClass("right");
});
});
$('#fbwindow').mouseleave(function() {
$("#fbwindow").stop().animate({
left: '-292px'
}, 50, function() {
//$(this).removeClass("right").addClass("left");
});
});

Categories

Resources