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>
Related
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');
}
}
}
I'm trying to get the progress bar animation to run when I click the .trigger. I'm getting the data-percentage value in the logs but the animation isn't running. It works without using $(this).closest() but I cannot figure out why the animation isn't running with my current JS code.
$(".list").on("click", ".trigger", function() {
var e = $(this).closest(".item");
$(".progressbar").attr("data-percentage", e.find("#percent").text());
var t = e.find("#percent").text();
return (
$(".progressbar").each(function() {
var n = e,
r = t;
console.log(t),
parseInt(n.data("percentage"), 10) < 2 && (r = 2),
n.children(".bar").animate({
width: r + "%"
}, 500);
}), !1
);
});
.item {
width: 50px;
height: 50px;
border: 1px solid;
}
.trigger {
height: 30px;
width: 30px;
border: 3px solid blue;
cursor: pointer;
}
.progressbar {
position: relative;
display: block;
height: 10px;
background: #f5f5f5;
}
.bar.money-green {
background: #3cd3ad;
}
.bar {
position: absolute;
display: block;
height: 100%;
background: #fcb31c;
width: 0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list">
<div class="item">
<div class="trigger">
<p id="percent">22</p>
</div>
</div>
</div>
<div class="progressbar" data-percentage="">
<div class="money-green bar"><span></span></div>
</div>
I updated the code for you. Clean and clear way
You don't need to return in onclick function. And you should use $(this) inside .each to get current index element
$(".list").on("click", ".trigger", function() {
var e = $(this).closest(".item");
var t = e.find("#percent").text();
$(".progressbar").attr("data-percentage", t);
$(".progressbar").each(function() {
$(this).find(".bar").animate({
width: t + "%"
}, 500);
});
});
See the codepen
I've been trying to alter the size of my ".square" divs that are created using JS/JQuery. I've successfully changed the size of the container div, but using the exact same code does not work for the dynamically created .square divs, despite being able to apply events the .square divs in other ways.
I've been trying to understand the problem for the last two days, and have been writing and rewriting solutions, but I think my current skills are overlooking a very simple answer.
The aim was to have the .square divs' size be determined by how many squares will be in the container. The more squares, the smaller the .square div css.
Thanks for any help anyone can give.
$(document).ready(function() {
var create = function(king) {
return $("#container").prepend("<div class='square' id=king></div>");
}
var sLoad = function() {
for (i = 0; i < 16; i++) {
$("#16").click(function() {
$("#container").prepend("<div class='square'></div>");
});
};
};
sLoad();
$("#clear").on("click", function() {
$(".square").remove();
num = prompt("How many squares would you like?");
// var containerSize = function(){
// var siz = 112 * num;
// $("#container").css({"height": siz+15+"px" , "width": siz+"px"});
// }
// containerSize()
$(".square").css({
"height": "50px",
"width": "50px"
});
var make = function(num) {
return num * num;
};
//var squareSize = function(){
// var sqr = 600 / make(num);
// $(".square").css({"height":sqr+"px" , "width":sqr+"px"});
//};
//squareSize();
for (i = 0; i < make(num); i++) {
$("#container").prepend("<div class='square'></div>");
};
});
// $(".button").click(function(){
//
//making the square dis and reappear
$("#container").on("mouseenter", function() {
$(".square").mouseenter(function() {
$(this).fadeTo("fast", 0);
}),
$(".square").mouseleave(function() {
$(this).fadeTo("fast", 1);
});
});
});
#menuContainer {
height: 45px;
width: 50%;
margin: auto;
}
#container {
width: 600px;
height: 600px;
border: 1px blue dotted;
border-radius: 2%;
margin: auto;
padding: 0px;
}
#controlDiv {
height: 30px;
width: 30px;
border: 1px dashed red;
margin: auto;
margin-top: 50%;
background-color: black;
}
.square {
width: 100px;
height: 100px;
background-color: grey;
border: 1px black dashed;
border-radius: 3%;
margin: 5px 5px 5px 5px;
display: inline-block;
}
.button {
height: 27px;
width: 70px;
background-color: gold;
border: solid 1px yellow;
text-decoration-color: blue;
border-radius: 5%;
text-align: center;
padding-top: 7px;
/*margin: auto;*/
margin-bottom: 4px;
display: inline-block;
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div id="menuContainer">
<div class="button" id="16">Click</div>
<div class="button" id="clear">Clear</div>
</div>
<div id="container">
<!-- <div id="controlDiv"></div> -->
</div>
<!--<div class="square"></div>-->
</body>
</html>
This fiddle should work : https://jsfiddle.net/x0x9rv30/2/
You applied the CSS on removed elements, you need to create the elements first, then you can apply CSS on it.
I just swapped two code blocks :
Before
$(".square").remove();
$(".square").css({"height":"50px" , "width": "50px"});
for (i = 0; i < make(num); i++){
$("#container").prepend("<div class='square'></div>");
};
After
$(".square").remove();
for (i = 0; i < make(num); i++){
$("#container").prepend("<div class='square'></div>");
};
$(".square").css({"height":"50px" , "width": "50px"});
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 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.