Mini/maximize effect on "dialogs" - javascript

Im trying to get a FB messaging system now i can append the dialogs next to eachother but how can i position the minimized dialog on bottom of the div ?
On the demo open 2 or more dialogs by clicking create button than click on titlebar it will minimize/maximize the dialog. What i want is a FB messaging effect $(this) titlebar must go down
Private = {
count: 0,
windowsOpen: [],
closeDialog: function(evt){
evt.parent().parent().remove()
Private.removeFromArray(evt.parent().text())
},
createDialog: function(nickname) {
var dialog = $("#private-dialog"),
dialogCloseButton = $("<span />", {
class: "ct icon-cancel close-private-dialog"
}),
dialogHeader = $("<div />", {
class: "private-section"
}),
dialogInit = $("<div />", {
class: "private-init",
html: "Here will come the messages"
}),
dialogTitle = $("<div />", {
class: "private-title",
html: nickname
});
dialogTitle.append(dialogCloseButton)
dialogHeader.append(dialogTitle, dialogInit)
dialog.append(dialogHeader)
},
dialogChecker: function(nickname){
if(Private.windowsOpen.indexOf(nickname) === -1){
Private.windowsOpen.push(nickname)
Private.createDialog(nickname)
} else {
console.log("this dialog is already open")
}
},
dialogHandler: function(nickname){
Private.dialogChecker(nickname)
},
dialogSize: function(evt){
evt.next().toggle()
},
events: function() {
$("#create").on("click", function(){
Private.openDialog()
})
$(document).on("click", ".close-private-dialog", function(){
Private.closeDialog($(this))
})
$(document).on("click", ".private-title", function(){
Private.dialogSize($(this))
})
},
init: function() {
Private.events()
},
openDialog: function(){
var nick = "test" + Private.count;
Private.dialogChecker(nick)
Private.count++;
},
removeFromArray: function(nickname){
if(Private.windowsOpen.indexOf(nickname) !== -1){
var index = Private.windowsOpen.indexOf(nickname);
Private.windowsOpen.splice(index, 1)
}
}
}
Private.init()
#main-container {
position: absolute;
border: 1px solid red;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
#private-dialog {
position: absolute;
bottom: 0;
right: 0;
}
.private-section {
float: right;
width: 7em;
margin-left: 2px;
}
.private-title {
background-color: #e01859;
color: #FFF;
padding: .5rem;
border-radius: .3rem .3rem 0 0;
box-shadow: 0px -2px 1px rgba(16, 13, 14, 0.39);
cursor: pointer;
}
.private-init {
background-color: #FFF;
height: 5em;
padding: 1em;
}
.private-section > .icon-cancel:before {
float: right;
margin-top: 2px;
}
.close-private-dialog {
float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main-container">
Click couple times on "create" button
<button id="create">
create
</button>
<div id="private-dialog">
</div>
</div>

Replace float: right with display: inline-block in .private-section and use prepend() rather than append() if you want to keep the same order when adding new popups.
There's a area at the bottom that still needs handling when all of them are collapsed, but that's the basic idea.
Private = {
count: 0,
windowsOpen: [],
closeDialog: function(evt){
evt.parent().parent().remove()
Private.removeFromArray(evt.parent().text())
},
createDialog: function(nickname) {
var dialog = $("#private-dialog"),
dialogCloseButton = $("<span />", {
class: "ct icon-cancel close-private-dialog"
}),
dialogHeader = $("<div />", {
class: "private-section"
}),
dialogInit = $("<div />", {
class: "private-init",
html: "Here will come the messages"
}),
dialogTitle = $("<div />", {
class: "private-title",
html: nickname
});
dialogTitle.append(dialogCloseButton)
dialogHeader.append(dialogTitle, dialogInit)
dialog.prepend(dialogHeader)
},
dialogChecker: function(nickname){
if(Private.windowsOpen.indexOf(nickname) === -1){
Private.windowsOpen.push(nickname)
Private.createDialog(nickname)
} else {
console.log("this dialog is already open")
}
},
dialogHandler: function(nickname){
Private.dialogChecker(nickname)
},
dialogSize: function(evt){
evt.next().toggle()
},
events: function() {
$("#create").on("click", function(){
Private.openDialog()
})
$(document).on("click", ".close-private-dialog", function(){
Private.closeDialog($(this))
})
$(document).on("click", ".private-title", function(){
Private.dialogSize($(this))
})
},
init: function() {
Private.events()
},
openDialog: function(){
var nick = "test" + Private.count;
Private.dialogChecker(nick)
Private.count++;
},
removeFromArray: function(nickname){
if(Private.windowsOpen.indexOf(nickname) !== -1){
var index = Private.windowsOpen.indexOf(nickname);
Private.windowsOpen.splice(index, 1)
}
}
}
Private.init()
#main-container {
position: absolute;
border: 1px solid red;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
#private-dialog {
position: absolute;
bottom: 0;
right: 0;
}
.private-section {
display: inline-block;
width: 7em;
margin-left: 2px;
}
.private-title {
background-color: #e01859;
color: #FFF;
padding: .5rem;
border-radius: .3rem .3rem 0 0;
box-shadow: 0px -2px 1px rgba(16, 13, 14, 0.39);
cursor: pointer;
}
.private-init {
background-color: #FFF;
height: 5em;
padding: 1em;
}
.private-section > .icon-cancel:before {
float: right;
margin-top: 2px;
}
.close-private-dialog {
float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main-container">
Click couple times on "create" button
<button id="create">
create
</button>
<div id="private-dialog">
</div>
</div>

Related

Simple-slider add class correctly when reversed

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');
}
}
}

How can I deactivate parent's title on child hover?

Here is my code:
$.fn.right = function() {
return $(document).width() - (this.offset().left + this.outerWidth());
}
$(document).ready(function(){
$('a').bind('mouseenter', function() {
var self = $(this);
this.iid = setTimeout(function() {
var tag_name = self.text(),
top = self.position().top + self.outerHeight(true),
right = self.right();
$('body').append("<div class='tag_info'>Some explanations about "+tag_name+"</div>");
$(".tag_info").css({top: top + "px", right: right + "px"}).fadeIn(200);
}, 525);
}).bind('mouseleave', function(){
if(this.iid){
clearTimeout(this.iid)
$('.tag_info').remove();
}
});
});
body{
padding: 20px;
direction: rtl;
}
div {
padding: 20px;
border: 1px solid gray;
}
a {
color: #3e6d8e !important;
background-color: #E1ECF4;
padding: 2px 5px;
}
.tag_info{
position: absolute;
width: 130px;
height: 100px;
display:none;
background-color: black;
color: white;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div title='a title'>
<a>long-length-tag</a>
<a>tag</a>
</div>
As you see, there is a dark popup on tags hover. Also div's title will be appear when that popup shows. How can I disable the title? (on tags hover)
The title hover is a per browser thing.
A better option would be to remove the title property when you add the hover over option.
/// somewhere in your hover in function
element.oldTitle = element.title;
element.title = '';
/// somewhere in your hover out function
element.title = element.oldTitle;
This should do the trick. When your mouse enters the tag, the current title will be set in the oldTitle attribute. When mouse leaves the tag, the current title will take its old value from the oldTitle attribute.
$.fn.right = function() {
return $(document).width() - (this.offset().left + this.outerWidth());
}
$(document).ready(function(){
$('a').bind('mouseenter', function() {
var self = $(this);
//get title and set it in a new attribute of the div
var container = $(this).closest('div');
container.attr('oldTitle', container.attr('title'));
container.attr('title', '');
this.iid = setTimeout(function() {
var tag_name = self.text(),
top = self.position().top + self.outerHeight(true),
right = self.right();
$('body').append("<div class='tag_info'>Some explanations about "+tag_name+"</div>");
$(".tag_info").css({top: top + "px", right: right + "px"}).fadeIn(200);
}, 525);
}).bind('mouseleave', function(){
if(this.iid){
clearTimeout(this.iid)
$('.tag_info').remove();
//reactivate the title
var container = $(this).closest('div');
container.attr('title', container.attr('oldTitle'));
}
});
});
<!-- begin snippet: js hide: false console: true babel: false -->
body{
padding: 20px;
direction: rtl;
}
div {
padding: 20px;
border: 1px solid gray;
}
a {
color: #3e6d8e !important;
background-color: #E1ECF4;
padding: 2px 5px;
}
.tag_info{
position: absolute;
width: 130px;
height: 100px;
display:none;
background-color: black;
color: white;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div title='a title'>
<a>long-length-tag</a>
<a>tag</a>
</div>
Add the following code on the mouseenter event:
$(this).parent().data('title', $(this).parent().attr('title'));
$(this).parent().attr('title', '');
.. and this on the mouseleave:
$(this).parent().attr('title', $(this).parent().data('title') );
$.fn.right = function() {
return $(document).width() - (this.offset().left + this.outerWidth());
}
$(document).ready(function(){
$('a').bind('mouseenter', function() {
var self = $(this);
$(this).parent().data('title', $(this).parent().attr('title'));
$(this).parent().attr('title', '');
this.iid = setTimeout(function() {
var tag_name = self.text(),
top = self.position().top + self.outerHeight(true),
right = self.right();
$('body').append("<div class='tag_info'>Some explanations about "+tag_name+"</div>");
$(".tag_info").css({top: top + "px", right: right + "px"}).fadeIn(200);
}, 525);
}).bind('mouseleave', function(){
$(this).parent().attr('title', $(this).parent().data('title') );
if(this.iid){
clearTimeout(this.iid)
$('.tag_info').remove();
}
});
});
body{
padding: 20px;
direction: rtl;
}
div {
padding: 20px;
border: 1px solid gray;
}
a {
color: #3e6d8e !important;
background-color: #E1ECF4;
padding: 2px 5px;
}
.tag_info{
position: absolute;
width: 130px;
height: 100px;
display:none;
background-color: black;
color: white;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div title='a title'>
<a>long-length-tag</a>
<a>tag</a>
</div>
Add an empty title attribute on the child element.
You can add an empty title attribute to your a elements to resolve this issue. The empty tag on the children will prevent the parent title from showing...
See the changed code example below.
$.fn.right = function() {
return $(document).width() - (this.offset().left + this.outerWidth());
}
$(document).ready(function(){
$('a').bind('mouseenter', function() {
var self = $(this);
this.iid = setTimeout(function() {
var tag_name = self.text(),
top = self.position().top + self.outerHeight(true),
right = self.right();
$('body').append("<div class='tag_info'>Some explanations about "+tag_name+"</div>");
$(".tag_info").css({top: top + "px", right: right + "px"}).fadeIn(200);
}, 525);
}).bind('mouseleave', function(){
if(this.iid){
clearTimeout(this.iid)
$('.tag_info').remove();
}
});
});
body{
padding: 20px;
direction: rtl;
}
div {
padding: 20px;
border: 1px solid gray;
}
a {
color: #3e6d8e !important;
background-color: #E1ECF4;
padding: 2px 5px;
}
.tag_info{
position: absolute;
width: 130px;
height: 100px;
display:none;
background-color: black;
color: white;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div title='a title'>
<a title="">long-length-tag</a>
<a title="">tag</a>
</div>

Remove Entire Modal with Jquery

I've been looking at previously posted StackOverflow questions, and still could not find my answer. So, I've been trying to simply delete the entire modal when I click on the close button. I can't get it to work, unfortunately. This is my code, so far.
var jQueryLoaded = 0;
function Modal(title, contents) {
if (jQueryLoaded === 1) {
var modal = document.createElement('div'),
modal_box = document.createElement('div'),
modal_head = document.createElement('div'),
modal_title = document.createElement('div'),
close_btn = document.createElement('div'),
modal_content = document.createElement('div');
modal.className = 'modal';
modal_box.className = 'modal_box';
modal_head.className = 'modal_head';
modal_title.className = 'modal_title';
modal_title.innerHTML = title;
close_btn.className = 'modal_close';
close_btn.innerHTML = '\u00D7';
modal_content.className = 'modal_content';
modal_content.innerHTML = contents;
$("body").append(modal);
$(modal).append(modal_box);
$(modal_box).append(modal_head, modal_content);
$(modal_head).prepend(modal_title);
$(modal_head).append(close_btn);
} else {
console.warn('jQuery, a required library, is not available at moment of function run. Please double check jQuery is loaded properly before running this function again.');
}
}
$(document).ready(function () {
jQueryLoaded = 1;
$("div.modal_close").on('click', function () {
$(this).parent().parent().closest('.modal').remove();
});
Modal('hello','<p>Example</p>');
});
/* Modals based off of W3Schools example! */
div.modal {
display: block;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background: rgba(0, 0, 0, 0.4);
font-family: 'Open Sans', sans-serif;
}
div.modal > div.modal_box {
background: #FFFFFF;
margin: auto;
padding: 5px;
border: 1px solid #000000;
width: 80%;
box-shadow: 3px 5px 3px rgba(0, 0, 0, 0.6);
}
div.modal > div.modal_box > div.modal_head {
width: 100%;
height: auto;
border: none;
border-radius: 0;
border-bottom: 1px solid #000000;
min-height: 10px;
font-weight: 16px;
}
div.modal > div.modal_box > div.modal_head > div.modal_title {
display: inline-block;
color: #000000;
text-align: center;
font-weight: 900;
font-size: 24px;
}
div.modal > div.modal_box > div.modal_head > div.modal_close {
margin: 1px;
font-weight: 900;
color: #000000;
border: 1px solid transparent;
padding: 2px;
border-radius: 5px;
background: transparent;
cursor: pointer;
float: right;
line-height: 10px;
user-select: none;
-webkit-user-select: none;
-o-user-select: none;
-k-user-select: none;
-moz-user-select: none;
}
div.modal > div.modal_box > div.modal_head > div.modal_close:hover,
div.modal > div.modal_box > div.modal_head > div.modal_close:focus {
border: 1px solid #000000;
background: rgba(0, 0, 0, 0.3);
}
div.modal > div.modal_box > div.modal_head > div.modal_close:active {
background: rgba(255, 0, 0, 0.8);
border: 1px solid #000000;
}
div.modal > div.modal_box > div.modal_content {
padding: 4px;
padding-left: 10px;
font-size: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script><link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
Mind you, the code to remove the modal was just the last one I tried. I tried many others like $(this).parent().parent().closest('.modal').remove(); and $(this).parent().parent().find('.modal').remove().
You're mixing JS and jQuery, not that it's not good, but you use it in an inappropriate way. jQuery is designed to help you manipulate with DOM and events - make use of it!
If you're building a Modal function to handle modals, the close should be handled from within the script, not by adding extra stuff all around your .js files.
How do you call your Modal?
Here's an example to give you an idea and get you started:
jQuery(function ($) { // DOM is ready and $ alias secured
Modal("opened",{
title : "Opened example",
content : "<p>Immediately opened from JS using <code>.open()</code></p>"
}).open();
Modal("test1", {
title : "This is Title",
content :
`<p>
<b>Lorem Ipsum</b>
Dolor sit amet<br>
Example
</p>`
});
Modal("another", {
title: "Auto-hide in 3sec",
content: "<p>Like it? <b>Show some love</b></p>",
duration: 3000
});
});
/*QuickReset*/ *{margin:0;box-sizing:border-box;} html,body{height:100%;font:14px/1.4 sans-serif;}
[data-modal]{ color:blue; cursor:pointer; }
<h1>Modal Demo</h1>
Click <a data-modal="test1">here</a> to call modal ID test1<br>
or you can click <a data-modal="another">here</a> to call another modal
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
/** Modal - Custom modals example by RokoCB
* #param {String} modalId - A modal name used to reference a modal
* #param {Object} data - {title:"String", content:"HTML", duration:ms}
* #return {Object} - methods: .open() .close()
*/
function Modal(modalId, data) {
// DEFAULT MODAL STYLES
var css = {
area: {
position: "fixed",
visibility: "hidden",
opacity: 0,
left: 0,
top: 0,
right: 0,
bottom: 0,
zIndex: 99999,
background: "rgba(0,0,0,0.4)",
transition: "0.4s",
},
modal: {
position: "absolute",
left: "50%",
top: "50%",
minWidth: 240,
transform: "translate(-50%, -50%)",
background: "#fff",
boxShadow: "0 8px 24px rgba(0,0,0,0.6)",
},
title: {
padding: "8px 32px 8px 16px",
fontSize: 18,
borderBottom:"1px solid rgba(0,0,0,0.15)",
},
content: {
padding: "16px",
},
close: {
position: "absolute",
top: 4,
right: 4,
padding: 8,
cursor: "pointer",
userSelect: "none",
}
}
// ELEMENTS
var $area = $("<div/>", {
class: "modal_area",
appendTo: "body",
css: css.area,
click : closeModal,
});
var $modal = $("<div/>", {
class: "modal",
appendTo: $area,
css: css.modal,
click: function(evt){evt.stopPropagation();}
});
$("<div/>", {
class: "modal_title",
appendTo : $modal,
text : data.title,
css: css.title,
});
$("<div/>", {
class: "modal_content",
appendTo : $modal,
html : data.content,
css: css.content,
});
$("<div/>", {
class: "modal_close",
appendTo : $modal,
text : '\u00d7',
css: css.close,
click : closeModal,
});
// ACTIONS
var closeTimeout = null;
function closeModal() {
$area.removeClass("open").css({visibility:"hidden", opacity:0});
}
function openModal() {
$area.addClass("open").css({visibility:"visible", opacity:1});
if(data.duration) {
clearTimeout(closeTimeout);
closeTimeout = setTimeout(closeModal, data.duration);
}
}
$(document).on("click", "[data-modal='"+modalId+"']", openModal);
// METHODS
return {
open : openModal,
close : closeModal
}
}
</script>
The button will have no event listener attached to it because you're creating it after the attaching of the event listener. There is two solution for this:
EITHER:
Add the event listener just after the button is created inside the Modal class here:
close_btn.onclick = function() {
$(this).closest('.modal').remove();
}
OR:
Use event delegation like this:
$(document).on('click', 'div.modal_close', function () {
$(this).closest('.modal').remove();
});
NOTE: Since, as mentioned in the comments, you are already using jQuery why not using it inside the Modal class too.

A javascript slider array issue

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()

div not retaining CSS attribute on click()

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>

Categories