I have a slider that is almost working good enough. Left and right buttons work but I want it to have a .current-slide class on the visible. That is achieved onSlideChanged function and works when using next button but unfortunately when using prev button it's inaccurate?
Basic example: https://codepen.io/rKaiser/pen/KKdZxqv
Try as I might, I couldnt get it, it's something to do with the reversed indexes that I couldnt bind correctly when prev button is clicked, I think.
<div class="nav-example">
<div id="myslider" class="nav-slider">
<img class="current-slide" src="http://placekitten.com/g/612/612"/>
<img src="https://picsum.photos/612/612"/>
<img src="https://picsum.photos/612/612?random=1"/>
<img src="https://picsum.photos/612/612?random=2"/>
<img src="https://picsum.photos/612/612?random=3"/>
</div>
<a id="prev-button" href="#" class="slide-button"><</a>
<a id="next-button" href="#" class="slide-button">></a>
</div>
var container = document.getElementById('myslider');
var children = container.children;
function onSlideChanged(prev, next) {
children[prev].className = '';
children[next].className = 'current-slide';
}
var isNext = true;
var imgSlider = simpleslider.getSlider({
container: container,
children: children,
prop: 'left',
init: -612,
show: 0,
end: 612,
unit: 'px',
paused: true,
onChange: onSlideChanged
});
document.getElementById('prev-button').onclick = function(e) {
if (isNext) {
imgSlider.reverse();
isNext = false;
}
imgSlider.next();
e.preventDefault();
};
document.getElementById('next-button').onclick = function(e) {
if (!isNext) {
imgSlider.reverse();
isNext = true;
}
imgSlider.next();
e.preventDefault();
};
.nav-example { position: relative; width: 612px; height: 612px; }
.nav-slider { position: absolute; top: 0px; left: 0px; z-index: 1;}
#myslider { width:612px; height:612px; }
a.slide-button { position: absolute; padding: 300px 0px 0px 15px; top: 0px; left: 0px; z-index: 12; width: 30px; height: 612px; color: #FFF; background-color: rgba(0,0,0,0.4); text-decoration: none; font-weight: 600; box-sizing: border-box; }
#next-button { left: auto; right: 0px; }
/* ------------------------- */
.current-slide {
filter: invert(1);
border-radius: 50%;
}
Got it to work like this, feels a bit crude but atleast it works.
function onSlideChanged(prev, next) {
if (isNext) {
children[prev].className = '';
children[next].className = 'current-slide';
} else {
var currentSlide = $('#myslider img.current-slide');
if ( currentSlide.is(':first-child') ) {
console.log('first');
$('#myslider img').removeClass('current-slide');
$('#myslider img').last().addClass('current-slide');
} else {
console.log('not first');
currentSlide.prev().addClass('current-slide').next().removeClass('current-slide');
}
}
}
Related
When the top property of each div .js-player is between 10 and 100 the word #muteshould have the class .active added. The code below only executes the adding of .active on the last .js-active div. Where am I going wrong? Any pointer would be greatly appreciated.
const players = Array.from(document.querySelectorAll('.js-player')),
mute = document.querySelector('#mute');
window.addEventListener('scroll', function(e) {
players.forEach(function(player) {
let distance = player.getBoundingClientRect().top;
if (10 < distance && distance < 100) {
mute.classList.add('active');
} else {
mute.classList.remove('active');
}
})
});
.js-player {
height: 150px;
width: 200px;
background-color: red;
margin: 8em 2em;
}
#mute {
position: fixed;
top: 10px;
left: 10px;
}
.active {
color: green;
}
.filler {
height: 400px;
}
<div class="js-player"></div>
<div class="js-player"></div>
<div class="js-player"></div>
<div class="filler"></div>
<div id="mute">mute</div>
I think what you are wondering is why only the last .js-player determines whether or not the div has the active class?
If so, each time a scroll event happens, it loops over the players, and either add or removes the active class. So, when it gets to the last .js-player, if this last .js-player is not within the distance, it will remove the active class if another one set it, and add it if is, it will set it even if another one removed it.
What you need to do is stop checking once you have found a player within the distance required, something like:
const players = Array.from(document.querySelectorAll('.js-player')),
mute = document.querySelector('#mute');
window.addEventListener('scroll', function(e) {
var matched = false;
players.forEach(function(player) {
if (matched) return;
let distance = player.getBoundingClientRect().top;
if (10 < distance && distance < 100) {
mute.classList.add('active');
matched = true;
} else {
mute.classList.remove('active');
}
})
});
.js-player {
height: 150px;
width: 200px;
background-color: red;
margin: 8em 2em;
}
#mute {
position: fixed;
top: 10px;
left: 10px;
}
.active {
color: green;
}
.filler {
height: 400px;
}
<div class="js-player"></div>
<div class="js-player"></div>
<div class="js-player"></div>
<div class="filler"></div>
<div id="mute">mute</div>
You are setting active class on mute element on each iteration, which means that only the last element of array will matter.
Here's a working verions:
const players = Array.from(document.querySelectorAll('.js-player'));
const mute = document.querySelector('#mute');
window.addEventListener('scroll', function(e) {
var active = false;
players.forEach(function (player) {
let distance = player.getBoundingClientRect().top;
if (10 < distance && distance < 100) {
active = true;
}
});
active ? mute.classList.add('active') : mute.classList.remove('active');
});
.js-player {
height: 150px;
width: 200px;
background-color: red;
margin: 8em 2em;
}
#mute {
position: fixed;
top: 10px;
left: 10px;
}
.active {
color: green;
}
.filler {
height: 400px;
}
<div class="js-player"></div>
<div class="js-player"></div>
<div class="js-player"></div>
<div class="filler"></div>
<div id="mute">mute</div>
Cheers!
I'm creating an off-canvas nav that closes on three conditions:
The user toggles the nav button
the user clicks a link inside the nav
the user clicks anywhere but the nav when the nav is open.
I've got the first two conditions working but not the third. Below is my code. What I'm trying to accomplish is essentially the following:
check for a click on the body and if that click is the (in this case) .pageContainer run a second check to see if the nav has the class "showMenu" and the flag is == true
$(document).ready(function() {
var button = $('.button');
var ocn = $('.ocn');
var test = $('.test');
var flag = false;
//toggle menu using just the button
button.click(function() {
if ( flag == false ) {
ocn.addClass('showMenu');
flag = true;
} else {
ocn.removeClass('showMenu');
flag = false;
}
});
//close the menu clicking on a link
test.click(function() {
ocn.removeClass('showMenu');
flag = false;
});
//close menu when click off canvas
/*
$('body').on('click', '.pageContainer', function(e) {
if( ocn.hasClass('showMenu') && flag == true) {
ocn.removeClass('showMenu');
flag = false;
}
});
*/
});
* {
padding: 0;
margin: 0;
}
.ocn {
position: absolute;
left: -300px;
top: 0;
width: 300px;
height: 100vh;
background-color: #ccc;
transition: left .2s ease;
z-index: 2;
border: 1px solid;
}
.showMenu {
left: 0px;
}
.pageContainer {
height: 500px;
width: 1000px;
border: 1px solid;
display: block;
margin: 0 auto;
}
.button {
height: 40px;
width: 40px;
border: 1px dashed;
display: block;
position: relative;
left: 400px;
cursor: pointer;
}
.test {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ocn">
<p class="test">here is some text for the menu</p>
</div>
<div class="pageContainer">
<div class="button"></div>
</div>
You can use the e.target property to compare what was clicked. Similar to this:
if(e.target == pageContainer[0])
You can now apply the required logic when .pageContainer was clicked.
$(document).ready(function() {
var pageContainer = $('.pageContainer');
var button = $('.button');
var ocn = $('.ocn');
var test = $('.test');
var flag = false;
//toggle menu using just the button
button.click(function() {
if (flag == false) {
ocn.addClass('showMenu');
flag = true;
} else {
ocn.removeClass('showMenu');
flag = false;
}
});
//close the menu clicking on a link
test.click(function() {
ocn.removeClass('showMenu');
flag = false;
});
//close menu when click off canvas
$('body').on('click', '.pageContainer', function(e) {
if (e.target == pageContainer[0]) {
//console.log('pageContainer was clicked')
if (ocn.hasClass('showMenu') && flag == true) {
ocn.removeClass('showMenu');
flag = false;
}
};
});
});
* {
padding: 0;
margin: 0;
}
.ocn {
position: absolute;
left: -300px;
top: 0;
width: 300px;
height: 100vh;
background-color: #ccc;
transition: left .2s ease;
z-index: 2;
border: 1px solid;
}
.showMenu {
left: 0px;
}
.pageContainer {
height: 500px;
width: 1000px;
border: 1px solid;
display: block;
margin: 0 auto;
}
.button {
height: 40px;
width: 40px;
border: 1px dashed;
display: block;
position: relative;
left: 400px;
cursor: pointer;
}
.test {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ocn">
<p class="test">here is some text for the menu</p>
</div>
<div class="pageContainer">
<div class="button"></div>
</div>
Having a slider with images implementation from array, cant figure out why images dont want to be shown up from array, tryed to make a path but it didnt work.I want this code to reflect this image every time a push the button: fpoimg.com/100x100.
Im trying to fix it only with clean javascript.
Here is a sandbox
var slider = {
slides: ['100x100', '100x100', '100x100', '100x100'],
frame:0,
set:function(image){
path = path || 'http://fpoimg.com/';
document.getElementById('scr').style.backgroundImage ="url ("+path+ image+")";
},
init:function() {
this.set(this.slides[this.frame]);
},
left:function() {
this.frame--;
if(frame < 0) this.frame = this.slides.length - 1;
this.set(this.slides[this.frame]);
},
right:function() {
if(this.frame == this.slides.length) this.frame = 0;
this.set(this.slides[this.frame]);
}
};
window.onload = function() {
slider.init();
setInterval(function() {
slider.right();
},5000);
};
.scr {
margin:20px auto;
width: 600px;
height: 320px;
margin-top:20px;
background-color: white;
background-size:cover;
}
button {
position: absolute;
top: 150px;
width: 25px;
height: 150px;
font-size: 30px;
text-align: center;
background:none;
border:none;
}
.left {
left:25px;
}
.right {
right:25px;
}
<body>
<button class="left" onclick="slider.left();"><</button>
<div class="scr"></div>
<button class="right" onclick="slider.right();">></button>
</body>
On Line 6 of your Javascript, you have used getElementById('scr'). You have no element with an Id or scr, you needed to use getElementsByClassName('scr')
Your new code:
var slider = {
slides: ['100x100', '100x100', '100x100', '100x100'],
frame: 0,
set: function(image) {
path = path || 'http://fpoimg.com/';
document.getElementsByClassName('scr').style.backgroundImage = "url (" + path + image + ")";
},
init: function() {
this.set(this.slides[this.frame]);
},
left: function() {
this.frame--;
if (frame < 0) this.frame = this.slides.length - 1;
this.set(this.slides[this.frame]);
},
right: function() {
if (this.frame == this.slides.length) this.frame = 0;
this.set(this.slides[this.frame]);
}
};
window.onload = function() {
slider.init();
setInterval(function() {
slider.right();
}, 5000);
};
.scr {
margin: 20px auto;
width: 600px;
height: 320px;
margin-top: 20px;
background-color: white;
background-size: cover;
}
button {
position: absolute;
top: 150px;
width: 25px;
height: 150px;
font-size: 30px;
text-align: center;
background: none;
border: none;
}
.left {
left: 25px;
}
.right {
right: 25px;
}
<body>
<button class="left" onclick="slider.left();">
</button>
<div class="scr"></div>
<button class="right" onclick="slider.right();"></button>
</body>
It seems you've got getElementById() when you meant getElementsByClassName()
I have a function that creates a grid of divs that are generated and sent to a container div when the document loads (or when the user resets it). When one hovers over the divs, they highlight (change color). When the user clicks the highlighted div, it changes to black. For some reason, the div that was black reverts back to the original color when I hover over a different div. I'm puzzled as to why that is. Any help or guidance would be greatly appreciated. Here's my jsfiddle example: https://jsfiddle.net/psyonix/1g9p59bx/79/
var d = ("<div class='square'></div>");
function createGrid(numSquares) {
var area = $('#g_area');
var squareSize = Math.floor(area.innerWidth() / numSquares);
for (var i = 0, len = (numSquares * numSquares); i < len; i++) {
area.append(d);
}
$('.square')
.height(squareSize)
.width(squareSize)
.hover(
function () {
$(this).css({
'background-color': '#FFFFFF'
});
}, function () {
$(this).css({
'background-color': '#C8C8C8'
});
})
.click(
function () {
$(this).css({
'background-color': '#000000'
});
});
}
function resetGrid() {
$(".square").remove();
}
$(document).ready(function () {
createGrid(8);
$("#button").click(function () {
var numSquares = prompt("Please enter the size");
resetGrid(numSquares);
createGrid(numSquares);
});
});
Once you click on a DIV, you should maintain a flag that tells you hover function to stop changing colors
$('.square')
.height(squareSize)
.width(squareSize)
.hover(
function () {
if ($(this).data("clicked")) return; //ADDED LINE
$(this).css({
'background-color': '#FFFFFF'
});
}, function () {
if ($(this).data("clicked")) return; //ADDED LINE
$(this).css({
'background-color': '#C8C8C8'
});
})
.click(
function () {
$(this).data("clicked", true); //ADDED LINE
$(this).css({
'background-color': '#000000'
});
});
it changed because of hover function.
https://jsfiddle.net/1g9p59bx/82/
$('.square')
.height(squareSize)
.width(squareSize)
.hover(
function () {
if($(this).hasClass('active'))return;
$(this).css({
'background-color': '#FFFFFF'
});
}, function () {
if($(this).hasClass('active'))return;
$(this).css({
'background-color': '#C8C8C8'
});
})
.click(
function () {
$(this).addClass('active');
$(this).css({
'background-color': '#000000'
});
});
For some reason, the div that was black reverts back to the original color when I hover over a different div
Not quite. It reverts to the original colour when you leave the current div, because that's what you tell it in the second argument to $('.square').hover. You would need to remember that the square was clicked, and build extra logic into the "unhover" function.
Fortunately, there is an easier way: use CSS. Note the very bottom of the CSS definitions.
var d = ("<div class='square'></div>");
function createGrid(numSquares) {
var area = $('#g_area');
var squareSize = Math.floor(area.innerWidth() / numSquares);
for (var i = 0, len = (numSquares * numSquares); i < len; i++) {
area.append(d);
}
$('.square')
.height(squareSize)
.width(squareSize)
.click(function () {
$(this).addClass('clicked');
});
}
function resetGrid() {
$(".square").remove();
}
$(document).ready(function () {
createGrid(8);
$("#button").click(function () {
var numSquares = prompt("Please enter the size");
resetGrid(numSquares);
createGrid(numSquares);
});
});
.container {
background-color: #252525;
width: 600px;
height: 700px;
margin: 0 auto;
border-radius: 5px;
}
.inner {
background-color: #C8C8C8;
position: absolute;
width: 580px;
height: 600px;
margin-right: 10px;
margin-left: 10px;
margin-top: 10px;
border-radius: 5px;
}
.knob {
background-color: #575759;
width: 60px;
height: 60px;
border-radius: 60px;
}
#left_b {
position: absolute;
margin-left: 30px;
margin-top: 625px;
margin-bottom: 10px;
}
#button {
position: absolute;
margin-left: 265px;
margin-top: 640px;
margin-bottom: 10px;
}
#right_b {
position: absolute;
margin-left: 510px;
margin-top: 625px;
margin-bottom: 10px;
}
#g_area {
background-color: #C8C8C8;
position: relative;
width: 580px;
height: 600px;
margin-right: auto;
margin-left: auto;
margin-top: auto;
border-radius: 5px;
overflow: hidden;
}
.square {
display: inline-block;
position: relative;
margin: 0 auto;
}
.highlight {
background-color: #FFFFFF;
outline: #C8C8C8;
outline: 1px;
outline: solid;
margin: 0 auto;
}
.square {
background-color: #C8C8C8;
}
.square:hover {
background-color: #FFFFFF;
}
.square.clicked {
background-color: #000000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container">
<div class="outer">
<div class="inner">
<div id="g_area"></div>
</div>
<div class="knob" id="left_b"></div>
<div id="button">
<button>RESET</button>
</div>
<div class="knob" id="right_b"></div>
</div>
</div>
</body>
i did an example on jsFiddle ( http://jsfiddle.net/aRWhm/ ) , the idea is to know when i'm over lets say the intersection between the red and the blue circle.
but the problem is that every time i reach the intersection, the class "is-over" of the red circle is removed.
Html:
<div>
<span id="Div1"></span>
<span id="Div2"></span>
<span id="Div3"></span>
<span id="Div4"></span>
</div>
CSS:
div {
display: block;
margin: 0 auto;
overflow: hidden;
width: 950px;
}
span {
display: block;
position: absolute;
opacity: 0.5;
border-radius: 999px;
z-index: 1;
}
#Div1 {
background-color: #FF0000;
height: 200px;
left: 50px;
top: 80px;
width: 200px;
}
#Div2 {
background-color: #0000FF;
height: 150px;
left: 40px;
top: 230px;
width: 150px;
}
#Div3 {
background-color: #008000;
height: 250px;
left: 100px;
top: 190px;
width: 250px;
}
#Div4 {
background-color: #FFFF00;
height: 100px;
left: 200px;
top: 130px;
width: 100px;
}
JavaScript:
$(document).ready(function () {
$("#Div1").hover(
function () {
$(this).addClass("is-over");
},
function () {
$(this).removeClass("is-over");
}
);
$("#Div2").hover(
function () {
$(this).addClass("is-over");
},
function () {
$(this).removeClass("is-over");
}
);
$("#Div3").hover(
function () {
$(this).addClass("is-over");
},
function () {
$(this).removeClass("is-over");
}
);
$("#Div4").hover(
function () {
$(this).addClass("is-over");
},
function () {
$(this).removeClass("is-over");
}
);
});
Here you go.
First, the Code:
(function($){
$.mlp = {x:0,y:0}; // Mouse Last Position
function documentHandler(){
var $current = this === document ? $(this) : $(this).contents();
$current.mousemove(function(e){jQuery.mlp = {x:e.pageX,y:e.pageY}});
$current.find("iframe").load(documentHandler);
}
$(documentHandler);
$.fn.ismouseover = function(overThis) {
var result = false;
this.eq(0).each(function() {
var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
var offset = $current.offset();
result = offset.left<=$.mlp.x && offset.left + $current.outerWidth() > $.mlp.x &&
offset.top<=$.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
});
return result;
};
})(jQuery);
$(document).ready(function () {
$("#myDiv").mousemove(
function() {
$("#myDiv").children("span").each(function(){
if($(this).ismouseover())
$(this).addClass("is-over");
else
$(this).removeClass("is-over");
});
});
});
Now an explanation:
I stole the .ismouseover() code shamelessly from this answer by Ivan Castellanos and repurposed it to your needs. Form there I used a .mousemove() event to fire every time you're in the parent container, which you can see in this fiddle needed to be given height and width parameters to ensure that it had a bounding box.
Lastly I simply check to see which circles you're over, and add the is-over class to them. The Fiddle is based off Anton's work, although it provides intersection support instead of moving one to the top.
Hope this helps.