How to modify divs generated by jQuery? - javascript

Complete noob question here:
I have this 16x16 grid of divs generated by jQuery
var rows = 16;
var columns = 16;
var $row = $("<div />", {
class: 'row'
});
var $square = $("<div />", {
class: 'square'
});
$(document).ready(function() {
for (var i = 0; i < columns; i++) {
$row.append($square.clone());
}
for (var x = 0; x < rows; x++) {
$(".box_main").append($row.clone());
}
});
.row {
width: auto;
height: 40px;
background: #313131;
}
.square {
width: 40px;
height: 40px;
border-radius: 10px;
margin: 0;
display: inline-block;
background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Can I somehow use the addClass and removeClass (or anything else) in order to change the background-color of each div one by one upon hovering/mouseenter over them?
I tried work something out but I'm not even sure whether it's possible or not to do this.

addClass()/removeClass() (or even JS) is not needed for this - you can achieve it using the :hover pseduo selector of CSS alone. Try this:
.square:hover {
background: #C00; /* amend colour as needed */
}
Working example:
var rows = 16;
var columns = 16;
var $row = $("<div />", {
class: 'row'
}).appendTo('body');
var $square = $("<div />", {
class: 'square'
});
$(document).ready(function() {
for (var i = 0; i < columns; i++) {
$row.append($square.clone());
}
for (var x = 0; x < rows; x++) {
$(".box_main").append($row.clone());
}
});
body {
background: #313131;
}
.row {
width: auto;
height: 40px;
background: #313131;
}
.square {
width: 40px;
height: 40px;
border-radius: 10px;
margin: 0;
display: inline-block;
background: #fff;
}
.square:hover {
background: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

beside the :hover pseduo selector, you might need to add an actual class to it with JS (perhaps it would make more sense if triggered by other event), nevertheless, here is an example using JS (addClass/removeClass)
var rows = 16;
var columns = 16;
var $row = $("<div />", {
class: 'row'
});
var $square = $("<div />", {
class: 'square'
});
$row.appendTo('body');
$(document).ready(function() {
for (var i = 0; i < columns; i++) {
$row.append($square.clone());
}
for (var x = 0; x < rows; x++) {
$(".box_main").append($row.clone());
}
$('.square').hover(function() { $(this).addClass('hovering'); }, function() { $(this).removeClass('hovering'); });
});
.row {
width: auto;
height: 40px;
background-color: #313131;
}
.square {
width: 40px;
height: 40px;
border-radius: 10px;
margin: 0;
display: inline-block;
background-color: #fff;
}
.hovering {
background-color: cyan;
border: 3px dashed blue;
width: 34px;
height: 34px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

How can I remove all borders from a group of elements except for the one created?

I'm trying to dynamically make all borders disappear except the newest created container's border I have tried the commented out section of the JavaScript. Can someone please provide an explanation/example of how this can be done?
function countButtonLinks() {
var elementGroups = document.getElementById('containsAll');
if(elementGroups.children.length == 0) {
var numID = 1;
}
if(elementGroups.children.length == 1) {
var numID = 2;
}
if(elementGroups.children.length == 2) {
var numID = 3;
}
if(elementGroups.children.length == 3) {
var numID = 4;
}
if(elementGroups.children.length == 4) {
var numID = 5;
}
if(elementGroups.children.length == 5) {
var numID = 6;
}
return numID;
}
function createContainer() {
if(document.getElementById('containsAll').children.length < 6) {
var elementA = document.createElement("span");
var elementAInnerTxt = document.createElement("div");
elementA.id = 'elem' + countButtonLinks();
elementAInnerTxt.id = 'elemInner' + countButtonLinks();
elementA.className = 'elem1';
elementAInnerTxt.className = 'elemInner1';
elementA.appendChild(elementAInnerTxt);
document.getElementById('containsAll').appendChild(elementA);
}
}
.containsAll {
width: 91%;
height: 75%;
position: absolute;
float: left;
margin-top: 1%;
margin-left: 1%;
background-color: transparent;
z-index: 91;
border: 1px #000000 solid;
border-radius: 7px;
padding: 5px;
}
.elem1 {
max-width: 100%;
max-height: 100%;
min-width: 100px;
min-height: 60px;
float: left;
background-color: transparent;
border: 1px #333333 solid;
border-radius: 5px;
}
.elemInner1 {
max-width: 100%;
max-height: 100%;
min-width: 100px;
min-height: 60px;
float: left;
background-color: transparent;
padding: 5px;
}
.buttonClass {
width: 100px;
height: 50px;
}
<button class="buttonClass" type="button" onclick="createContainer();">Click Me</button>
<div id="containsAll" class="containsAll"></div>
Please, no JQuery.
function countButtonLinks(){
var elementGroups = document.getElementById('containsAll');
// you don't need to use 'var numID'
return elementGroups.children.length + 1;
}
function createContainer(){
if(document.getElementById('containsAll').children.length < 6){
// add code here
for(var i=0;i<document.getElementById('containsAll').children.length;i++){
document.getElementById('containsAll').children[i].style.border = '0 none';
}
var elementA = document.createElement("span");
//...
Simply call the existing children of the element and remove the border before inserting
another element:
function countButtonLinks(){
var elementGroups = document.getElementById('containsAll');
var groupLength = elementGroups.children.length;
return groupLength++;
}
function createContainer() {
var containsAll = document.getElementById('containsAll'),
childrenLength = containsAll.children.length;
if (childrenLength >= 6) {
return; // Bail immediately since we only need to add a new element if the children's length is less than 6
}
// Call previous children
for ( var i = 0; i < childrenLength; i++ ) {
let child = containsAll.children[i];
// You can add a new class here that will remove the border
// but in this example, we'll use the style attribute to remove the border
child.style.border = 0;
}
// Now, add the new element
var elementA = document.createElement("span");
var elementAInnerTxt = document.createElement("div");
elementA.id = 'elem' + countButtonLinks();
elementAInnerTxt.id = 'elemInner' + countButtonLinks();
elementA.className = 'elem1';
elementAInnerTxt.className = 'elemInner1';
elementA.appendChild(elementAInnerTxt);
containsAll.appendChild(elementA);
}
Also, if you're going to use an element multiple times inside a function, make it a habit to store that element in a variable so you don't repeatedly calls the document.getElementById function.
You can accomplish this using the CSS :last-child selector
var container = document.getElementById('container');
function count_button_links()
{
return container.children.length + 1;
}
function new_container()
{
if (count_button_links() > 6) return false;
let span = document.createElement('span');
span.id = 'el_' + count_button_links();
span.className = 'box';
container.appendChild(span);
}
#container {
width: 100%;
background-color: transparent;
border: 1px solid #000;
border-radius: 7px;
padding: 5px;
display:flex;
height:200px;
}
.box {
flex:0 0 100px;
height:60px;
background-color: transparent;
border-radius: 5px;
}
.box:last-child{
border:1px solid #333;
}
button {
width: 100px;
height: 50px;
}
<button type="button" onclick="new_container();">Click Me</button>
<div id="container"></div>

Call functions instead of reloading page

Basically I have this function that picks two different random images from a folder. At the moment I'm using onClick="window.location.reload() to run the function everytime you click.
Is there anyway I can call the funcion onClick without refreshing the page?
Thanks in advance.
body {
border: 0;
color: #000;
background: #fff;
margin: 0;
padding: 0;
font: 2.1vw/1.2em HelveticaNeue, Arial, sans-serif;
letter-spacing: .02em
}
.logo {
cursor: pointer;
position: fixed;
top: 0;
left: 0;
width: 100vw;
text-align: center;
z-index: 100
}
#one,
#two {
position: fixed;
width: 50vw;
top: 0;
display: table
}
#one {
left: 0;
text-align: right
}
#two {
right: 0;
text-align: left
}
.inner {
display: table-cell;
vertical-align: middle;
height: 100vh;
width: 100vw
}
<script>
var IMG = new Array()
IMG[0] = 'https://cdn.shopify.com/s/files/1/0224/5205/products/Siser_EasyWeed_Bright_Red_2048x.jpg?v=1523704262'
IMG[1] = 'http://thezilla.com/wp-content/uploads/2015/07/blue.png'
IMG[2] = 'http://d18nh7ureywlth.cloudfront.net/wp-content/uploads/6901-vibrant-green.jpg'
var j = 0
var p = IMG.length;
var preBuffer = new Array()
for (i = 0; i < p; i++) {
preBuffer[i] = new Image()
preBuffer[i].src = IMG[i]
}
var WI1 = Math.floor(Math.random() * p);
var WI2 = Math.floor(Math.random() * (p - 1));
if (WI2 >= WI1) {
WI2 += 1;
}
function showImage1() {
document.write('<img src="' + IMG[WI1] + '">');
}
function showImage2() {
document.write('<img src="' + IMG[WI2] + '">');
}
</script>
<div class=logo onClick="window.location.reload()"><span class=inner>( RANDOM DYPTICHS )</span></div>
<div id=one><span class=inner><script>showImage1();</script></span></div>
<div id=two><span class=inner><script>showImage2();</script></span></div>
Ideally, there is no need to use ajax either.
I simply used an addEventListener('click'...) and encapsulated your code.
Click on the screen and the images will change randomly.
To Note: Take into a habit of adding (;) where is needed, Javascript is not strict (unless using "use strict") on colons but it can cause a lot of bugs in the future. Also, use commas (' or ") in your attributes in HTML.
Read Javascript Style Guide written by W3 Schools, they do a
good job explaining to newbies about famous javascript conventions
around the globe.
var IMG = new Array(
'https://i.picsum.photos/id/562/200/200.jpg?hmac=F4ylYRNFPH6rDzYo48_NUieJXXI2yaMl9ElwGeFQHZo',
'https://i.picsum.photos/id/650/200/200.jpg?hmac=gu3C13pBxCSHokbnumczMYlmWRLt3CFGx1sDaPpfRnk',
'https://i.picsum.photos/id/67/200/200.jpg?hmac=sN5XCCMqqmBvgDbYmAowWy2VToCkSYP5igDL_iRxK3M');
function getRandomImagePair() {
var j = 0;
var p = IMG.length;
var preBuffer = new Array();
for (i = 0; i < p; i++) {
preBuffer[i] = new Image();
preBuffer[i].src = IMG[i];
}
WI1 = Math.floor(Math.random() * p);
WI2 = Math.floor(Math.random() * (p - 1));
if (WI2 >= WI1) {
WI2 += 1;
}
document.querySelector('#imgOne').src = IMG[WI1];
document.querySelector('#imgTwo').src = IMG[WI2];
}
getRandomImagePair();
document.querySelector('.logo .inner').addEventListener('click', e => {
getRandomImagePair();
});
body {
border: 0;
color: #000;
background: #fff;
margin: 0;
padding: 0;
font: 2.1vw/1.2em HelveticaNeue, Arial, sans-serif;
letter-spacing: .02em
}
.logo {
cursor: pointer;
position: fixed;
top: 0;
left: 0;
width: 100vw;
text-align: center;
z-index: 100;
}
#one,
#two {
position: fixed;
width: 50vw;
top: 0;
display: table
}
#one {
left: 0;
text-align: right
}
#two {
right: 0;
text-align: left
}
.inner {
display: table-cell;
vertical-align: middle;
height: 100vh;
width: 100vw
}
<div class='logo'><span class='inner'>( RANDOM DYPTICHS )</span></div>
<div id='one'><span class='inner'><img id="imgOne" src="#" /></span></div>
<div id='two'><span class='inner'><img id="imgTwo" src="#" /></span></div>

onClick event - only one event at time

I have simple javascript function to add borders for each elements inside container. How can I make that only one element can be in onclick state? So just one element at moment should have border.
var fileA = document.querySelectorAll('file_a');
for ( var i = 0; i < fileA.length; i++ ) (function(i){
fileA[i].onclick = function() {
fileA[i].style.border = '1px solid teal';
};
})(i);
container_a {
background: rgb(220,220,220);
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 2%;
display: flex;
flex-wrap: wrap;
}
file_a {
background: rgb(245,245,245);
box-shadow: 0px 5px 10px rgba(0,0,0,0.07);
width: 100%;
max-height: 100px;
display: block;
-webkit-transform: scale(0.98);
transition-duration: 250ms;
}
file_a:hover {
-webkit-transform: scale(1);
}
file_a.redclass {
background-color: red;
}
<container_a>
<file_a>1</file_a>
<file_a>2</file_a>
<file_a>3</file_a>
<file_a>4</file_a>
</container_a>
You need to remove all borders before you add your new one. See this fiddle for an example. https://jsfiddle.net/e79puv91/
var fileA = document.querySelectorAll('file_a');
for ( var i = 0; i < fileA.length; i++ ) (function(i){
fileA[i].onclick = function() {
for (var x = 0; x < fileA.length; ++x) {
fileA[x].style.border = '';
}
fileA[i].style.border = '1px solid teal';
};
})(i);

jQuery filters sometimes showing all elements

When I toggle between jQuery filters that show elements with a certain class, sometimes the selected filter shows all elements and not just the ones with the respective class.
You can see this in the below fiddle. Switch between the select options and sometimes they'll show all results.
Fiddle.
function activateButtons(_data){
$('.jobs-teams select').on("change", function(e) {
e.preventDefault();
for(i = 0; i < _data.length; i++) {
var teamRaw = _data[i].title;
var team = cleanString(teamRaw);
var jobs = $(".jobs-list");
if ($(this).find(":selected").hasClass(team)) {
if ($(this).hasClass("active")) {
$(this).removeClass("active");
jobs.find(".job").fadeIn("fast");
}
else {
$(".jobs-teams").find("a").removeClass("active");
$(this).addClass("active");
jobs.find("."+team).fadeIn("fast");
jobs.find(".job").not("."+team).fadeOut("fast");
}
}
}
})
}
Issues with the code that just need to be updated are the following.
//$(this) return the select tag. you should target options
if ($(this).hasClass("active")) {
$(this).removeClass("active");
jobs.find(".job").fadeIn("fast");
}
else {
//$(".jobs-teams").find("a") returns undefined remember that you changed the anchors to select options
$(".jobs-teams").find("a").removeClass("active");
$(this).addClass("active");
jobs.find("."+team).fadeIn("fast");
jobs.find(".job").not("."+team).fadeOut("fast");
}
CODE SNIPPET:
// Replace "leverdemo" with your own company name
url = 'https://api.lever.co/v0/postings/leverdemo?group=team&mode=json'
//Functions for checking if the variable is unspecified
function cleanString(string) {
if (string) {
var cleanString = string.replace(/\s+/ig, "");
return cleanString;
}
else {
return "Uncategorized";
}
}
function nullCheck(string) {
if (!string) {
var result = 'Uncategorized'
return result;
}
else {
return string;
}
}
function createJobs(_data) {
for(i = 0; i < _data.length; i++) {
var team = nullCheck(_data[i].title)
var teamCleanString = cleanString(team);
$('#jobs-container .jobs-teams select').append(
'<option value="" class=' + teamCleanString + '>' + team + '</option>'
);
}
for(i = 0; i < _data.length; i++) {
for (j = 0; j < _data[i].postings.length; j ++) {
var posting = _data[i].postings[j]
var title = posting.text
var description = posting.description
//Making each job description shorter than 250 characters
var shortDescription = $.trim(description).substring(0, 250)
.replace('\n', ' ') + "...";
var location = nullCheck(posting.categories.location);
var locationCleanString = cleanString(location);
var commitment = nullCheck(posting.categories.commitment);
var commitmentCleanString = cleanString(commitment);
var team = nullCheck(posting.categories.team);
var teamCleanString = cleanString(team);
var link = posting.hostedUrl;
$('#jobs-container .jobs-list').append(
'<div class="job '+teamCleanString+' '+locationCleanString+' '+commitmentCleanString+'">' +
'<a class="job-title" href="'+link+'"">'+title+'</a>' +
'<p class="tags"><span>'+team+'</span><span>'+location+'</span><span>'+commitment+'</span></p>' +
'<p class="description">'+shortDescription+'</p>' +
'<a class="btn" href="'+link+'">Learn more</a>' +
'</div>'
);
}
}
}
function activateButtons(_data){
$('.jobs-teams select').on("change", function(e) {
e.preventDefault();
for(i = 0; i < _data.length; i++) {
var teamRaw = _data[i].title;
var team = cleanString(teamRaw);
var jobs = $(".jobs-list");
var $this = $(this).find(":selected");
if ($this.hasClass(team)) {
if ($this.hasClass("active")) {
$this.removeClass("active");
jobs.find(".job").fadeIn("fast");
}
else {
$(".jobs-teams select").find("option").removeClass("active");
$this.addClass("active");
jobs.find("."+team).fadeIn("fast");
jobs.find(".job").not("."+team).fadeOut("fast");
}
}
}
}).change();
}
//Fetching job postings from Lever's postings API
$.ajax({
dataType: "json",
url: url,
success: function(data){
createJobs(data);
activateButtons(data);
}
});
body {
font-family: 'Lato', sans-serif;
overflow-y: scroll;
}
p {
margin: 0 0 1em 0;
line-height: 1.4em;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
section {
position: relative;
padding: 30px;
}
.container {
max-width: 960px;
margin: 0 auto;
}
.job {
display: inline-block;
vertical-align: top;
width: 50%;
padding: 40px 30px;
}
h1 {
font-size: 48px;
color: #454545;
padding: 0 30px;
}
.job-title {
font-size: 24px;
text-decoration: none;
color: #454545;
}
.job-title:hover {
color: #00A0DF;
}
.tags span {
color: #999;
font-size: 12px;
color: grayMediumDark;
}
.tags span:after {
content: ', ';
}
.tags span:last-of-type:after {
content: '';
}
.description {
color: #999;
}
.btn {
display: inline-block;
padding: 7px 15px;
text-decoration: none;
font-weight: normal;
color: #999;
border: 2px solid #ebebeb;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #f9f9f9;
}
.btn:hover {
background: #ebebeb;
color: #555;
}
.btn.active {
background: #454545;
border-color: #454545;
color: #fff;
}
.jobs-teams {
margin-bottom: 40px;
padding: 0 30px
}
.jobs-teams .btn {
margin: 0 8px 8px 0;
}
.jobs-teams .btn:first-of-type {
margin-left: 0;
}
.jobs-teams .btn:last-of-type {
margin-right: 0;
}
<section>
<div class="container" id="jobs-container">
<h1>Open jobs</h1>
<div class="jobs-teams">
<select>
</select>
</div>
<div class="jobs-list">
</div>
</div>
</section>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
Consider doing it with fewer lines:
function activateButtons(_data) {
$('.jobs-teams select').on("change", function(e) {
e.preventDefault();
var selected_class = $('.jobs-teams select').find(':selected').attr('class');
$('.jobs-list').find('div.job')
.not('.' + selected_class).fadeOut('fast').end() //remove the ones that do not match
.filter('.' + selected_class).not(':visible').fadeIn('fast'); // bring in the ones that do match (and are not already visible)
})
.change(); //have the form pre-load with the default selected value
}
Oh--I also added a line to have the jobs honor the default selection (.change(); //have the form pre-load with the default selected value).
Working fiddle.

bug IE 11 with overflow auto

there are a bug on IE 11 when i empty the html in a DIV and I remove class in the list with JavaScriptS.
The DIV loses the syle CSS "Overflow:auto" and guard is a great height
There is no bug on another navigator.
Sample:
<!DOCTYPE html>
<html>
<head>
<title>CSS</title>
<style>
div {
margin: 5px;
}
ul {
margin: 5px;
max-height: 200px;
overflow: auto;
}
ul li.selected {
font-weight: bold;
}
.dest {
width: 500px;
min-height: 21px;
max-height: 120px;
overflow: auto;
border: 1px solid #ccc;
background-color: #f9f9f0;
padding: 3px;
}
.dest span {
display: block;
background-color: #fff;
float: left;
border-radius: 2px;
border: 1px solid #ccc;
margin: 2px;
padding: 0px 2px 0px 2px;
line-height: 21px;
height: auto;
}
</style>
<script>
window.onload = function(){
document.getElementById("btclear").onclick = function(){
document.getElementById("dest").innerHTML = "";
};
document.getElementById("btclearplus").onclick = function(){
document.getElementById("dest").innerHTML = "";
var ul = document.getElementById("list");
var lis = ul.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].className = "";
}
};
document.getElementById("btall").onclick = function(){
for(var i = 0; i < 50; i++) {
var span = document.createElement("span");
span.innerHTML = "first name " + i + " last name " + i;
document.getElementById("dest").appendChild(span);
}
var ul = document.getElementById("list");
var lis = ul.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].className = "selected";
}
};
for(var i = 0; i < 50; i++) {
for(var i = 0; i < 50; i++) {
var li = document.createElement("li");
li.innerHTML = "nom" + i + " prenom" + i;
document.getElementById("list").appendChild(li);
}
}
}
</script>
</head>
<body>
<div id="dest" class="dest"></div>
<div>
<ul id="list"></ul>
</div>
<div>
<button id="btall">Select all</button>
<button id="btclear">Clear all</button>
<button id="btclearplus">Clear all and deselect</button>
</div>
</body>
</html>
Thank you, Jean-Pierre
change the one of the loops variable i to j because you have same variable in both loops
for(var i = 0; i < 50; i++) {
for(var j = 0; j < 50; j++) {
// do you logic
}
}
I deleted the double loop, the problem was not that here.
In Internet Explorer, you must click the "Select All" button and then the button "Clear all and deselect" to reproduce the problem.
<!DOCTYPE html>
<html>
<head>
<title>CSS</title>
<style>
div {
margin: 5px;
}
ul {
margin: 5px;
max-height: 200px;
overflow: auto;
}
ul li.selected {
font-weight: bold;
}
.dest {
width: 500px;
min-height: 21px;
max-height: 120px;
overflow: auto;
border: 1px solid #ccc;
background-color: #f9f9f0;
padding: 3px;
}
.dest span {
display: block;
background-color: #fff;
float: left;
border-radius: 2px;
border: 1px solid #ccc;
margin: 2px;
padding: 0px 2px 0px 2px;
line-height: 21px;
height: auto;
}
</style>
<script>
window.onload = function(){
document.getElementById("btclear").onclick = function(){
document.getElementById("dest").innerHTML = "";
};
document.getElementById("btclearplus").onclick = function(){
document.getElementById("dest").innerHTML = "";
var ul = document.getElementById("list");
var lis = ul.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].className = "";
}
};
document.getElementById("btall").onclick = function(){
for(var i = 0; i < 50; i++) {
var span = document.createElement("span");
span.innerHTML = "first name " + i + " last name " + i;
document.getElementById("dest").appendChild(span);
}
var ul = document.getElementById("list");
var lis = ul.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].className = "selected";
}
};
for(var i = 0; i < 50; i++) {
var li = document.createElement("li");
li.innerHTML = "nom" + i + " prenom" + i;
document.getElementById("list").appendChild(li);
}
}
</script>
</head>
<body>
<div id="dest" class="dest"></div>
<div>
<ul id="list"></ul>
</div>
<div>
<button id="btall">Select all</button>
<button id="btclear">Clear all</button>
<button id="btclearplus">Clear all and deselect</button>
</div>
</body>
</html>
Thank you, Jean-Pierre
Overflow: Auto problem / bug in IE
.element { overflow-y: auto; overflow-x: visible; width: 450px; }
DEMO

Categories

Resources