i have 1 class html with various elements i want add a class new class in first element that scroll top reach the top ofos this elements, then when the scroll reach the second add in second too and so on. i tried this
var element = $(".element");
$(window).scroll(function () {
var scroll = $(window).scrollTop();
for(var i = 0; i < element.length;i++){
if(scroll > element.eq(i)){
element.eq(i).addClass("newClass");
}
}
})
html piece
<div>
<div class="element">
<img src="img/image1" />
</div>
<div class="element">
<img src="img/image2" />
</div>
<div class="element">
<img src="img/image3" />
</div>
</div>
but this line element.eq(i).addClass("newClass") dont work :) how i should to do
try to use
if(scroll > element.eq(i).offset().top - ($(window).height() / 2) ){
element.eq(i).addClass("newClass");
}
DEMO
Related
I am trying to make an image change when I click on a piece of text on a website that I am building.
At this moment I have created a class called device with one of them being device active as shown below:
<div class="col-md-3">
<div class="device active">
<img src="app/assets/images/mockup.png" alt="">
</div>
<div class="device">
<img src="app/assets/images/mockup.png" alt="">
</div>
<div class="device">
<img src="app/assets/images/mockup.png" alt="">
</div>
</div>
And then what i am currently trying to do is remove the class of active when I click on some text with the i.d of #search2. This is my whole jquery script so far:
$("#search2").click(function() {
var currentImage = $('.device.active');
var nextImage = currentImage.next();
currentImage.removeClass('active');
});
However this does not seem to remove the class of active and the image is still displayed? any ideas?
Your selection is done right and it is working for me (the active class is removed from that item). The problem must be somewhere else in your code.
Here is an alternative:
var activeDeviceIndex = 0;
$("#search2").click(function() {
var devicesContainer = $('.device');
$(devicesContainer[activeDeviceIndex]).removeClass('active');
activeDeviceIndex === devicesContainer.length - 1 ? activeDeviceIndex = 0 : activeDeviceIndex++;
$(devicesContainer[activeDeviceIndex]).addClass('active');
});
.device {
display: none;
}
.device.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-3">
<div class="device active">
<p>Device 1</p>
</div>
<div class="device">
<p>Device 2</p>
</div>
<div class="device">
<p>Device 3</p>
</div>
</div>
<button id="search2">click</button>
Check on the following, the id on the button to click should be search2 and not #search2, may be just typo stuffs.
after that update your code as follows
/**
*#description - gets the next image to slide, if the last image is the current image, it will loop the sliding
*#param {Element} current - the currently active image
*#param {Boolean} islooped - boolean value indicating if a looping just started
*/
var nextImage = function(current, islooped) {
var next = islooped? current : current.nextSibling;
while(next && next.nodeName.toLowerCase() !== 'div') {
next = next.nextSibling;
}
next = next? next : nextImage(current.parentNode.firstChild, true);
return next;
};
$('#search2').bind('click', function(event) {
var current = $('.device.active').removeClass('active').get(0);
var next = nextImage(current, false);
$(next).addClass('active');
});
In my application I have 4 links with different IDs and 4 DIV with same ID as each link (I use them for anchor-jumping).
My current code:
One
Two
Three
Four
<div class="col-md-12 each-img" id="1">
<img src="img/album-img.png">
</div>
<div class="col-md-12 each-img" id="2">
<img src="img/album-img.png">
</div>
<div class="col-md-12 each-img" id="3">
<img src="img/album-img.png">
</div>
<div class="col-md-12 each-img" id="4">
<img src="img/album-img.png">
</div>
Sometime users just scroll to second div id="2" first before they click on buttons and when they do so, they are sent to top id="1" first instead of continue to next ID id="3".
Only one button is visible at a time with use of CSS and when link is clicked, I remove that link.
CSS
a.btn{display: none}
a.btn a:first-child{display: block !important;}
jQuery
$(document).ready(function(){
$('a.btn').click(function () {
$(this).remove(); // remove element which is being clicked
});
});
How can I achieve so if user scroll down, each link that has same ID as the DIV get removed.
For instance: If user scroll down to <div class="col-md-12" id="1">, One gets removed and Next link would be Two to click on.
PS: This is for a dynamic page and IDs will change, so we need another selector maybe
This is what I have tried until now, but problem is that it removes all the links and not first one only
$(function() {
var div = $('.each-img').offset().top;
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
$('.each-img').each(function(){
if (scrollTop >= div) {
$("a.btn:eq(0)").remove();
//$("a.btn:first-child").remove();
}
});
});
});
PS: The way HTML & CSS is setup doesn't need to like this and I can change it to whatever that will be better for the function
It's no problem to make it dynamic:
JSFiddle: https://jsfiddle.net/rc0v2zrw/
var links = $('.btn');
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
links.each(function() {
var href = $(this).attr('href');
var content = $(href);
if (scrollTop > content.offset().top) {
$(this).hide();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:fixed; top:0; left:0; right:0">
One
Two
Three
Four
</div>
<div class="col-md-12" id="1">
<img src="http://lorempixel.com/400/500/">
</div>
<div class="col-md-12" id="2">
<img src="http://lorempixel.com/450/500/">
</div>
<div class="col-md-12" id="3">
<img src="http://lorempixel.com/480/500/">
</div>
<div class="col-md-12" id="4">
<img src="http://lorempixel.com/500/500/">
</div>
I think this is more or less what you're after:
JSFiddle
https://jsfiddle.net/wc0cdfhv/
It's good to cache the position of your elements outside the scroll function, this way it doesn't need to be calculated every time.
You should also keep in mind this won't scale too well if you have dynamic content but if you're just working with 4 static links it will do fine.
Code
$(function() {
var scroll1 = $('#1').offset().top;
var scroll2 = $('#2').offset().top;
var scroll3 = $('#3').offset().top;
var scroll4 = $('#4').offset().top;
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
if (scrollTop >= scroll4) {
$("#go1, #go2, #go3, #go4").hide();
}
else if (scrollTop >= scroll3) {
$("#go1, #go2, #go3").hide();
$("#go4").show();
}
else if (scrollTop >= scroll2) {
$("#go1, #go2").hide();
$("#go3, #go4").show();
}
else if (scrollTop >= scroll1) {
$("#go1").hide();
$("#go2, #go3, #go4").show();
}
else {
$("#go1, #go2, #go3, #go4").show();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:fixed; top:0; left:0; right:0; background:#CCC">
One
Two
Three
Four
</div>
<div class="col-md-12" id="1">
<img src="https://www.myoodle.com/images/easyblog/616/2014042_Therapy_Dog_003.jpg">
</div>
<div class="col-md-12" id="2">
<img src="https://www.myoodle.com/images/easyblog/616/2014042_Therapy_Dog_003.jpg">
</div>
<div class="col-md-12" id="3">
<img src="https://www.myoodle.com/images/easyblog/616/2014042_Therapy_Dog_003.jpg">
</div>
<div class="col-md-12" id="4">
<img src="https://www.myoodle.com/images/easyblog/616/2014042_Therapy_Dog_003.jpg">
</div>
use scrollEvent listener
$(window).scroll(function(e){
if($(this)).scrollTop >= $('div#1').offset().top){
$("a#1").hide();
}
});
Use Something like that and it will work .. Hope this helps
On Cloned menu (.original / .cloned ) i have problem getting 1 of the 2 toggle functions to work correctly.
Part #1 Cloned Menu Toggle
$('.mobile-nav-toggle').click(function(e) {
e.preventDefault();
var $this = $('a');
if ($this.hasClass('open')) {
$this.trigger('mobilenav:close', [$this, 'close']);
} else {
$this.trigger('mobilenav:close', [$this, 'open']);
}
// Guess this one get executed twice
$this.trigger('mobilenav:toggle', [$this]);
});
Part #2 Cloned Menu Toggle
$(document).on('mobilenav:toggle', function(e, $obj) {
$('.original>div>nav').toggleClass('open').slideToggle(300);
$('.cloned>div>nav').toggleClass('open').slideToggle(300);
$obj.toggleClass('close');
});
I understand the issue is that am using $('a') as my selector make mobilenav:toggle trigger twice and then it will loop around opening and closing the two menus.
On the other hand the mobile-nav-toggle icon don't loop and syncs correctly, menu drawer is in sync but looping.
If i change
$this = $('a');
// To
$this = $(this);
Everything will work except toggle icon that will not be in sync.
Have given this a couple of hours now and my macro level of Javascript / jQuery is just to weak as probably can be seen on my half ass solution on Part #2.
Watch my masterpiece in action!
Help me do this as a pro !
Edit: Adding rest of code from Sticky / cloning function after request
$('.menu').addClass('original').clone().insertAfter('.menu').addClass('cloned').css('position', 'fixed').css('top', '0').css('margin-top', '0').css('z-index', '100').removeClass('original').hide();
scrollIntervalID = setInterval(stickIt, 10);
function stickMenu() {
var orgElementPos = $('.original').offset();
orgElementTop = orgElementPos.top;
if ($(window).scrollTop() >= (orgElementTop)) {
orgElement = $('.original');
coordsOrgElement = orgElement.offset();
leftOrgElement = coordsOrgElement.left;
widthOrgElement = orgElement.css('width');
$('.cloned').css('left', leftOrgElement + 'px').css('top', 0).css('width', widthOrgElement).show();
$('.original').css('visibility', 'hidden');
$('.original>div>nav').removeAttr("id", "off-nav");
} else {
$('.cloned').hide();
$('.original>div>nav').attr("id", "off-nav");
$('.original').css('visibility', 'visible');
}
}
Edit: Added Markup
<header class="menu" id="main-header-wrap"">
<div class="" id="main-header">
<div class="toptop"></div>
<div class="container">
<div class="row">
<div id="logotype">
</div>
<div id="menu-container" class="clearfix">
<a class="mobile-nav-toggle lines-button x skiplink">
<span class="lines"></span>
</a>
<nav>
</nav>
</div>
</div>
</div>
<nav id="off-nav">
<ul><li class=""></li></ul>
</nav>
</div>
</header>
I have a list of items that are organized in an alphabetical order on a page. I would like to create a fixed element at the side of the page that shows, which letter section you are currently scrolling by.
For example, if you are scrolling past items starting with the letter 'D', the fixed div will show 'D'. I have been trying to create this with jQuery, but have been finding it tricky.
Each section has the class 'card-container' and an 'id' corresponding to the current letter.
ie.
<div id="a" class="card-container">
...
</div>
<div id="b" class="card-container">
...
</div>
<div id="c" class="card-container">
...
</div>
...
Any idea how I can accomplish this?
EDIT
So far I have this:
$(window).scroll(function() {
var winTop = $(this).scrollTop();
var letters = $('.card-container');
letters.each(function(section) {
if($(this).position().top <= winTop) {
console.log($(this).context.id);
$('.letter-show h3').text($(this).context.id);
}
});
});
So this seems to work, but I feel like it's not very performant. Any suggestions to improve on this?
As I said in the comment: There's not much you can do to improve your code - a few millisecond gain at most. Stuff like minimizing the DOM lookups and breaking the loop when the right element is found, dropping jQuery, etc... But I doubt you'd notice a difference even on the slowest machine you can find around.
var letters = $('.card-container');
var letterShow = $('.letter-show h3');
$(window).scroll(function() {
var winTop = $(this).scrollTop();
letters.each(function(section) {
if($(this).position().top <= winTop) {
letterShow.text($(this).context.id);
}
});
});
.card-container {height: 300px;border-top: 1px solid}
.letter-show {position: fixed}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="letter-show"><h3></h3></div>
<div id="a" class="card-container">
...
</div>
<div id="b" class="card-container">
...
</div>
<div id="c" class="card-container">
...
</div>
<div id="d" class="card-container">
...
</div>
<div id="e" class="card-container">
...
</div>
This is what did the trick:
$(window).scroll(function() {
var winTop = $(this).scrollTop();
var letters = $('.card-container');
letters.each(function(section) {
if($(this).position().top <= winTop) {
$('.letter-show h3').text($(this).context.id);
}
});
});
I have some divs with same class. Inside this divs i added another div to put an ad.
Now i am trying to hide the ad div if the width of the div that holds my ad div is equal to 366px;
I tried the code bellow but it hides only my first ad div..
Example:
<div class="masterdiv">
<div id="myaddiv"></div>
</div>
<div class="masterdiv">
<div id="myaddiv"></div>
</div>
<div class="masterdiv">
<div id="myaddiv"></div>
</div>
and my jquery code is:
var adwidth = $(".masterdiv").width();
if (adwidth == 366){
$('#myaddiv').hide();
}
Thank you!
Because var adwidth = $(".masterdiv").width(); only returns the first value. The answer is in your title, you need to use each. Another issue is ids are SINGULAR, so you need to use a class
Using each:
$(".masterdiv").each( function() {
var elem = $(this);
var width = elem.width();
if (width == 366){
elem.find('.myaddiv').hide(); //use a class since only one element can have an id
}
});
Using filter:
$(".masterdiv").filter( function() {
return ($(this).width() == 366);
}).find('.myaddiv').hide();
The updated HTML:
<div class="masterdiv">
<div class="myaddiv"></div>
</div>
you should not use duplicate ids.use:
$('div .masterdiv').each(function(){
if($(this).width()==366){
$(this).find('div').hide();
}});
Try:
$('.masterdiv').each(function(){
if($(this).width()==386){
$(this).hide();
}
});
This is only doing the first div because you are using id's instead of classes. Since there can only be one id per page javascript stops after matching the first one. change to classes and you should be fine.
you are using same id's for different divs
Instead of id, give class name
<div class="masterdiv">
<div class="myaddiv">
</div>
</div>
<div class="masterdiv">
<div class="myaddiv">
</div>
</div>
<div class="masterdiv">
<div class="myaddiv">
</div>
</div>
$(document).ready(function () {
var adwidth = $(".masterdiv");
for (i = 0; i < adwidth.length; i++) {
if ($(adwidth[0]).attr("width") == 366) {
$(this).find('.myaddiv').hide()
}
}
});
$(".masterdiv").each(function(){
var current = $(this);
if(current.width() == 366) {
current.hide();
}
});
You have to change in this way:
$('#myaddiv', '.masterdiv').each(function() {
var width = $(this).width();
(width > 366) ? $(this).hide() : 0;
});
You can try on this live DEMO