css not affecting div - javascript

I made this function to make 16 columns and rows.but I want the div that they are in to be on the right side, so for some reasons, I can't seem to change the div through (inline) css. I'm guessing its a problem with the function? Thanks for the help.
<html>
<body>
<div id="buttonContainer">
<button></button>
</div>
<div id="gridContainer" style = "left: 500px;">
</div>
</body>
<script>
const buttons = document.querySelector("#buttonContainer");
const btn1 = document.createElement("button");
btn1.classList.add("btn1");
buttonContainer.appendChild(btn1);
function divs(){
const gridContainer = document.querySelector("#gridContainer");
for(var i = 0; i < 17; i++){
var row = document.createElement("div");
row.className = "row";
for(var x = 1; x <= 17; x++){
var cell = document.createElement("div");
cell.className = "gridsquare";
cell.innerText = (i);
row.appendChild(cell);
}
gridContainer.appendChild(row);
}
}
divs();
</script>
</html>

There are different ways to move a div to the right. One is to give it a position:absolute (so it can move around freely) and then apply right : 0.
I have also removed the glitchy <button part.
const buttons = document.querySelector("#buttonContainer");
const btn1 = document.createElement("button");
btn1.classList.add("btn1");
buttonContainer.appendChild(btn1);
function divs() {
const gridContainer = document.querySelector("#gridContainer");
for (var i = 0; i < 17; i++) {
var row = document.createElement("div");
row.className = "row";
for (var x = 1; x <= 17; x++) {
var cell = document.createElement("div");
cell.className = "gridsquare";
cell.innerText = (i);
row.appendChild(cell);
}
gridContainer.appendChild(row);
}
}
divs();
#gridContainer{
position : absolute;
right: 0;
}
<div id="buttonContainer"></div>
<div id="gridContainer"></div>
EDIT : more modern/robust solution with Flexbox
The problem with position:absolute is that it kind of "detaches" the element from the rest of the DOM, so other elements start placing themselves underneath it, and it can quickly cause layout nightmares.
Here's an alternative with Flexbox :
.parent{
border : blue solid 2px;
height: 200px;
width: 100%;
display: flex;
justify-content: flex-end;
}
.child {
flex-basis : 150px; /* This is like width:150px */
background : green;
}
<div class="parent">
<div class="child"></div>
</div>

Related

changing the content of a div

I would like to change the content of a div. I have three divs:
<div
class="box1"
style="height: 200px; width: 200px; background-color: red"
>
A
</div>
<br />
<div
class="box2"
style="height: 200px; width: 200px; background-color: blue"
>
<label for="">tex</label>
<input type="text" />
</div>
<br />
<div
class="box3"
style="height: 200px; width: 200px; background-color: yellow"
>
C
</div>
when the page is ready the 2 and 3rd box displays none:
function hideElementBoxOnLoad() {
let box1 = document.querySelector(".box1");
let box2 = document.querySelector(".box2");
let box3 = document.querySelector(".box3");
box2.style.display = "none";
box3.style.display = "none";
}
$(document).ready(hideElementBoxOnLoad);
I want a click that toggles the content of box2 and box3 into box1 and then back to box1 content:
function changeContent() {
let chang = true;
let box1 = document.querySelector(".box1");
let box2 = document.querySelector(".box2");
let box3 = document.querySelector(".box3");
let box2Content = box2.textContent;
let box3Content = box3.textContent;
if (chang) {
box1.textContent = box2Content;
chang = !chang;
if ((box1.textContent === box2Content)) {
box1.textContent = box3Content;
}
}
}
let btn = document.getElementById("btn");
btn.addEventListener("click", changeContent);
So far it worked but it does not display the content of box2 only box3. what did i do wrong and what better way can i toggle with a boolean.
See below
Instead of trying to swap content between each div just use JS to go through the array of them and swap an active class between them;
var boxes = document.getElementsByClassName('box');
var change = document.getElementById('change');
var counter = 0;
change.addEventListener('click', function(){
boxes[counter].classList.remove('active');
boxes[counter].nextElementSibling.classList.add('active');
counter++;
if(counter === boxes.length) {
counter = 0;
boxes[0].classList.add('active');
}
});
.box {
display: none;
width: 100px;
height: 100px;
background-color: gray;
}
.box.active {
display:block
}
<div class="box active">A</div>
<div class="box">B</div>
<div class="box">C</div>
<button id="change">Change Content</button>
im not completely sure if i understood ur question.
but below u can see and even test with the snippet button.
the button now add what ever content in in the yellow box, and whats in the input field of the blue box into the red box. listing them downwards.
if you want to replace the content completely.
just change the logic to box1.innerHTML += spacer+box3.innerHTML+spacer+input.value
this is the most simple way to do it thats easy to understand just by reading the code i think.
hope this helps!
function changeContent() {
//the button
const btn = document.getElementById("btn");
//the boxes
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");
const box3 = document.getElementById("box3");
//a spacer
const spacer = "<br>";
//the input field
const input = document.getElementById("input");
//logic
box1.innerHTML += spacer+box3.innerHTML+spacer+input.value
}
div{
border-radius: 5px;
text-align: center;
font-family: sans-serif;
}
#box1{
min-height: 200px;
width: 200px;
padding: 5px;
background-color: rgb(255, 73, 73);
}
#box2 {
height: 200px;
width: 200px;
padding: 5px;
background-color: rgb(0, 195, 255);
}
#box3 {
height: 200px;
width: 200px;
padding: 5px;
background-color: yellow;
}
button{
padding: 3px;
margin-top: 10px;
}
<div id="box1">
<p>contetnt A</p>
</div>
<br />
<div id="box2" >
<label for="">tex</label>
<input id="input" type="text" />
<button id="btn" onclick="changeContent()">click me</button>
</div>
<br />
<div id="box3">
contetnt C
</div>
List of bugs :-
You had declared the var chang locally instead of globally, which make it true whenever you runs the function.
You are directly writing value from one tag to another, which causing the data loss, when you run your function second time.
For example :- When you click the button first time, the data is swapped, but for the second click, the data first div is lost and cannot be brought back...
Solution :- Store the data in an array in document.ready event handler and extract data from the array to update you html tags.
function hideElementBoxOnLoad() {
let box1 = document.querySelector(".box1");
let box2 = document.querySelector(".box2");
let box3 = document.querySelector(".box3");
box2.style.display = "none";
box3.style.display = "none";
content = [box1.textContent, box2.textContent, box3.textContent];
let btn = document.getElementById("btn");
btn.addEventListener("click", changeContent);
}
var content = [];
window.onload = (hideElementBoxOnLoad);
var index = 0;
function changeContent() {
let chang = true;
let box1 = document.querySelector(".box1");
/* let box2 = document.querySelector(".box2");
let box3 = document.querySelector(".box3");
let box2Content = box2.textContent;
let box3Content = box3.textContent;
if (chang) {
box1.textContent = box2Content;
chang = !chang;
if ((box1.textContent === box2Content)) {
box1.textContent = box3Content;
}
}
*/
function cycle(n, x = 0, y = content.length - 1, a = 1) {
n += a;
if (n > y) return x;
if (n < x) return y;
return n;
}
index = cycle(index);
box1.textContent = content[index];
}
<div class="box1" style="height: 200px; width: 200px; background-color: red">
A
</div>
<br />
<div class="box2" style="height: 200px; width: 200px; background-color: blue">
<label for="">tex</label>
<input type="text" />
</div>
<br />
<div class="box3" style="height: 200px; width: 200px; background-color: yellow">
C
</div>
<button id="btn"> CLICK ME </button>
Explaination
Here I first stored the tags textContent in a array content, in the starting of the code.
Then, inside the button click handler, a simple cycle function to cycle on the values stored inside the content array.

javascript pass screen width to function

I have implemented an infinite scroll and I need to modify the width of all elements to adjust to the display width.
the code is
var elements = document.getElementsByClassName('myDiv');
for (var i = 0; i < elements.length; i++) {
elements[i].style.width = (screen.width / 2);
}
and does not work (does not change the width of the div)
but
var elements = document.getElementsByClassName('myDiv');
for (var i = 0; i < elements.length; i++) {
elements[i].style.width = "10px";
}
works
and alert(screen.width) returns correctly the screen's width.
can someone help me ?
Add the px - the unit is expected
document.querySelectorAll('.myDiv')
.forEach(div => div.style.width = `${(screen.width / 2)}px`)
.myDiv { background-color: yellow; }
<div class="myDiv" style="width:100px">Hello</div>
<div class="myDiv" style="width:200px">Hello</div>
<div class="myDiv" style="width:300px">Hello</div>
<div class="myDiv" style="width:400px">Hello</div>
<div class="myDiv" style="width:500px">Hello</div>
<div class="myDiv" style="width:600px">Hello</div>

Create a button to toggle flex-direction between row and column for a style

I am tying to create a button that will toggle a style flex-direction between "row" and "column"
The code I tried was based on some other code that I used for toggling the display between "flex" and "none".
I can't use Id's because there a multiple non contiguous element.
I TRIED THE CODE BELOW
function setDisplay(className, displayValue) {
var items = document.getElementsByClassName(className);
for (var i=0; i < items.length; i++) {
items[i].style.flexDirection = displayValue;
}
}
function showResponsive() {
var elements = document.getElementsByClassName("main");
Array.prototype.forEach.call(elements, function(el) {
if (el.style.flex-direction === "column") {
el.style.flex-direction = "row";
} else {
el.style.flex-direction = "column";
}
});
}
.green{
background:green;
width:300px;
height:300px;
}
.red{
background:red;
width:300px;
height:300px;
}
.black{
background:black;
width:300px;
height:300px;
}
.main{
display:flex;
flex-direction:column
}
<div><i>Click switch</i></div>
<div>
<label class="switch">
<input type="checkbox" onclick="showResponsive()" >
<span class="slider round"></span>
</label>
</div>
<div class="main">
<div class="green"></div>
<div class="red"></div>
<div class="black"></div>
</div>
The code above is based on the code below which works for changing the style.display between "flex" and "none"
function setDisplay(className, displayValue) {
var items = document.getElementsByClassName(className);
for (var i=0; i < items.length; i++) {
items[i].style.flexDirection = displayValue;
}
}
function showResponsive() {
var elements = document.getElementsByClassName("main");
Array.prototype.forEach.call(elements, function(el) {
if (el.style.flex-direction === "column") {
el.style.flex-direction = "row";
} else {
el.style.flex-direction = "column";
}
});
}
Replace your JavaScript code with the following code:
function showResponsive () {
var elements = document.getElementsByClassName("main");
Array.prototype.forEach.call(elements, function(el) {
if (el.style.flexDirection === "column") {
el.style.flexDirection = "row";
} else {
el.style.flexDirection = "column";
}
});
}
The property names on the style object are in camel-case and not kebab-case. So when setting the flex direction use:
el.style.flexDirection = "row";

Javascript how to use function match()?

I have a problem with my javascript code in a word search. Let me explain:
I have an HTML page like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>xPression Reports</title>
<link href="index.css" rel="stylesheet" type="text/css" />
</head>
<body>
<button>Accueil</button>
<div id="myBtnContainer">
<button class="btn active" onclick="filterSelection('all')">Show all</button>
<button class="btn" onclick="filterSelection('bis')">bis</button>
<button class="btn" onclick="filterSelection('bis.xindd')">bis.xindd</button>
</div>
<div class="container">
<div class=" filterDiv bis" >bis 2017/06</div>
<div class=" filterDiv bis" >bis 2017/07</div>
<div class=" filterDiv bis.xindd" >bis.xindd 2017/06</div>
<div class=" filterDiv bis.xindd" >bis.xindd 2018/01</div>
</div>
<script src="index.js"></script>
</body>
</html>
(I simplified it)
with CSS:
body{
background-color: #d3d3d3;
}
.container {
overflow: hidden;
}
.filterDiv {
float: left;
color: black;
border: 1px solid black;
width: auto;
text-align: center;
margin: 2px;
display: none; /* Hidden by default */
}
/* The "show" class is added to the filtered elements */
.show {
display: block;
}
/* Style the buttons */
.btn {
border: none;
outline: none;
background-color: #f1f1f1;
cursor: pointer;
}
/* Add a light grey background on mouse-over */
.btn:hover {
background-color: #ddd;
}
/* Add a dark background to the active button */
.btn.active {
background-color: #666;
color: white;
}
img {
width:50px;
}
and a javascript:
filterSelection("all")
function filterSelection(c) {
var x, i;
x = document.getElementsByClassName("filterDiv");
if (c == "all") c = "";
// Add the "show" class (display:block) to the filtered elements, and remove the "show" class from the elements that are not selected
for (i = 0; i < x.length; i++) {
w3RemoveClass(x[i], "show");
if (x[i].matches(c) > -1) w3AddClass(x[i], "show");
}
}
// Show filtered elements
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
//alert(arr1);
arr2 = name.split(" ");
//alert(arr2);
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {
element.className += " " + arr2[i];
}
}
}
// Hide elements that are not selected
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
//alert(arr1);
arr2 = name.split(" ");
//alert(arr2);
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
// Add active class to the current control button (highlight it)
var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
current[0].className = current[0].className.replace(" active", "");
this.className += " active";
});
}
Everything works as it should be that when I click on a button, only the frames corresponding to the button are displayed. However for 6 of them do not work for example with bis and bis.xindd, I think it because the js take only "bis" for searching and so when I click on "bis", bis and bis.xindd are displaying.
And I think the mistake comes from this function:
filterSelection("all")
function filterSelection(c) {
var x, i;
x = document.getElementsByClassName("filterDiv");
if (c == "all") c = "";
// Add the "show" class (display:block) to the filtered elements, and remove the "show" class from the elements that are not selected
for (i = 0; i < x.length; i++) {
w3RemoveClass(x[i], "show");
if (x[i].matches(c) > -1) w3AddClass(x[i], "show");
}
}
I saw information on Regex and especially the function ma * tch but I do not see how the used here
thank you in advance for your help
A working solution for your filter list would look like this: https://jsfiddle.net/jkrielaars/szagq5hm/31/
However: Periods in a class name is not a good idea.
Here is why your code is not working:
On https://developer.mozilla.org/en-US/docs/Web/API/Element/matches it states that the argument should be the element selector string. Having a period in your classname is going to mess this up.
You need to add the period to indicate you're dealing with a class, however, since you also have a period in the classname you will have this as a result: ".bis.xindd".
If you see that as a selector string, it means an element with both .bis and .xindd classes. This is not what you are aiming for.
Is you insist on using periods in your classnames, have a look at .classList.contains().
Below you can see how this differs from .matches().
var test1 = document.getElementById('test1')
var test2 = document.getElementById('test2')
console.debug('matches does not work without the class period', test1.matches('bis'));
console.debug('matches does not work without the class period', test2.matches('bis.xindd'));
console.debug('matches does work with the class period', test1.matches('.bis'));
console.debug('matches does not work with a class name with a period in it', test2.matches('.bis.xindd'));
console.debug('test1 should contain bis', test1.classList.contains("bis"));
console.debug('test 2 should contain bis.xindd', test2.classList.contains("bis.xindd"));
console.debug('test2 should not match with just "bis"', test2.classList.contains("bis"));
<div id="test1" class="filterDiv bis">bis 2017/06</div>
<div id="test2" class="filterDiv bis.xindd" >bis.xindd 2017/06</div>

How to create pair game using node values and set a setTimeout() method

I want to create a pair game that if the same textnode is matched it will set the background in white to reveal the matched textnode if not it will set a timeout and get back in original state.
The Problem of this is if I use the childNodes.nodeValue in match it saids that ChildNodes.nodeValue is not a function. And I try another code. I declare a variable that calls the element tag name of div which is I append a textNode in div. I want to compare two consecutive childNodes of div and if it is the same node, I change the color of the background to white. and I use the setTimout method, if not the color of background will go back again in original state which is black, I am pretty confused about this.
can you scan my code and help me to figure out what is the problem of this code?
here is the code.
<html>
<head>
<style>
div.row {
clear : left;
margin: auto;
width: 520px;
}
div.col {width:100px;
height:100px;
border: 3px solid black;
float : left;
margin: 10px;
font-size: 75px;
text-align: center;
background-color: black;
}
</style>
</head>
<body>
<div class="row">
<div id="00" class="col"></div>
<div id="01"class="col"></div>
<div id="02"class="col"></div>
<div id="03"class="col"></div>
</div>
<div class="row">
<div id="10" class="col"></div>
<div id="11"class="col"></div>
<div id="12"class="col"></div>
<div id="13"class="col"></div>
</div>
<div class="row">
<div id="20" class="col"></div>
<div id="21"class="col"></div>
<div id="22"class="col"></div>
<div id="23"class="col"></div>
</div>
<div class="row">
<div id="30" class="col"></div>
<div id="31"class="col"></div>
<div id="32"class="col"></div>
<div id="33"class="col"></div>
</div>
<script>
var size = 4;
var player = 0;
var board = new Array(size);
for (var i = 0; i < size; i++) {
board[i] = new Array(size);
for (var j = 0; j < size; j++) {
board[i][j] = 0;
}
}
var div_elements = document.getElementsByClassName("col");
for (var i = 0; i < div_elements.length;i++) {
div_elements[i].addEventListener("click", function() {mclick(this);});
}
var count=0;
function mclick(obj) {
if(match(div_elements.childNodes[0].nodeValue) == match(div_elements.childNodes[1].nodeValue)
{
obj.style.backgroundColor="white";
}
else{
setTimeout(function(){ obj.style.backgroundColor="white" }, 1000);
}
}
function shuffle() {
var value;
var text;
var text_node;
for (var i = 0; i < (size * size) ; i++) {
value = Math.ceil(Math.random() * 8);
board[Math.floor(i/4)][i %4] = value;
}
for (var i = 0; i < div_elements.length; i++)
{
text = board[Math.floor(i/4)][i%4];
text_node = document.createTextNode( text);
div_elements[i].appendChild(text_node);
}
}
shuffle();
</script>
</body>
</html>
You must be more specific. What kind of problem are you having? What are the error messages? What do you do that triggers the problem?
At least, put the code in a pastebin.com or something similar so that others don't need to setup a project for testing your whole stuff.

Categories