Changing style of div after adding sibling div - javascript

When I add a sibling div to the #boundary div, I can no longer change the style of the #box child div. What am I doing wrong? The following is a simplified version of my code:
let box = document.getElementById("box");
let boundary = document.getElementById("boundary")
//Adding this line prevents my code from changing the #box style to blue
boundary.innerHTML += "<div>A</div>"
document.addEventListener("keydown", function(event) {
if (event.key == "ArrowDown") {
box.style.backgroundColor = "blue"
}
})
#box {
width: 75px;
height: 75px;
background-color: green;
border: solid black 1px;
position: absolute;
top: 100px;
left: 100px;
}
<div id="boundary">
<div id="box"></div>
</div>

When you append a new string to innerHTML it's like you create a new HTML content inside #boudary so the old element you selected is different from the new one created.
To verify this, select your element after the DOM change and you will get the new one created and you will be able to change its style:
let boundary = document.getElementById("boundary")
boundary.innerHTML += "<div>A</div>";
//Here you select the new one
let box = document.getElementById("box");
document.addEventListener("click", function(event) {
box.style.backgroundColor = "blue"
})
#box {
width: 75px;
height: 75px;
background-color: green;
border: solid black 1px;
position: absolute;
top: 100px;
left: 100px;
}
<div id="boundary">
<div id="box"></div>
</div>

Adding a string to innerHTML creates a new #box DOM element, and this breaks the box reference in your code. Use Element.insertAdjacentHTML() instead:
let box = document.getElementById("box");
let boundary = document.getElementById("boundary")
boundary.insertAdjacentHTML( 'beforeend', "<div>A</div>");
document.addEventListener("keydown", function(event) {
if (event.key == "ArrowDown") {
box.style.backgroundColor = "blue"
}
})
#box {
width: 75px;
height: 75px;
background-color: green;
border: solid black 1px;
position: absolute;
top: 100px;
left: 100px;
}
<div id="boundary">
<div id="box"></div>
</div>
Another option is to remove the let box = document.getElementById("box"); line. This will work because every element with id creates an automatic global variable, that references it and updates automatically.
let boundary = document.getElementById("boundary")
boundary.innerHTML += "<div>A</div>";
document.addEventListener("keydown", function(event) {
if (event.key == "ArrowDown") {
box.style.backgroundColor = "blue"
}
})
#box {
width: 75px;
height: 75px;
background-color: green;
border: solid black 1px;
position: absolute;
top: 100px;
left: 100px;
}
<div id="boundary">
<div id="box"></div>
</div>

You need to put a semicolon after it.
boundary.innerHTML += "<div>A</div>";
I hope this helps.

Related

Why change the color inside the div does not work?

Div with the id is clicking, the div with class is not clicking. By clicking div I want to change the color. If the color input within the div class is not working, if it is out of div class it works normally. How do I fix this?
var div = document.getElementsByTagName("div");
var divCount = div.length;
var clickedDivId;
for (var i = 0; i < divCount; i += 1) {
div[i].onclick = function(e) {
if (e.target.id) alert(this.id);
clickedDivId = this.id;
e.stopPropagation();
};
}
function BackgroundColor(){
var x = document.getElementsByClassName("backgroundcolor")[0].value;
document.getElementById(clickedDivId).style.backgroundColor = x;
}
#divid{
width: 450px;
height: 170px;
margin: 10px;
padding: 10px;
background-color: blue;
}
.divclass{
width: 450px;
height: 170px;
margin: 10px;
padding: 10px;
background-color: blue;
}
<div class="divclass">
<input type="color" class="backgroundcolor" onchange="BackgroundColor()">
</div>
<div id="divid"></div>
The click event is firing for both divs, but your handler only shows the alert if the clicked div has an id, which the first one doesn't have.
You are also using old APIs (getElementsByTagName and getElementsByCalssName) that should really not be used anymore and the solution is much simpler that what you've done:
let color = document.querySelector(".backgroundcolor"); // Get reference to color input
let targetDiv = document.getElementById("divid"); // Get reference to second div
// Set up click event handler on the document
document.addEventListener("click", function(evt){
// Check to see if event originated at a div
if(evt.target.nodeName === "DIV"){
alert("You clicked a div!"); // Act accordingly
}
});
// Set up change event on color input
color.addEventListener("change", function(evt){
// Set color of target div
targetDiv.style.backgroundColor = color.value;
});
#divid{
width: 450px;
height: 170px;
margin: 10px;
padding: 10px;
background-color: blue;
}
.divclass{
width: 450px;
height: 170px;
margin: 10px;
padding: 10px;
background-color: blue;
}
<div class="divclass">
<input type="color" class="backgroundcolor">
</div>
<div id="divid">
</div>
function BackgroundColor(){
var x = document.getElementById("backgroundcolor1").value;
document.getElementById("clickedDivId").style.backgroundColor = x;
}
#divid{
width: 450px;
height: 170px;
margin: 10px;
padding: 10px;
background-color: blue;
}
.divclass{
width: 450px;
height: 170px;
margin: 10px;
padding: 10px;
background-color: blue;
}
<div id="clickedDivId" class="divclass">
<input type="color" id="backgroundcolor1" onclick="BackgroundColor()">
</div>
<div id="divid"></div>
It is better to use ID. I guess this is what you want.
By keep changing the color the background will change as well.

Show element if another element is outside screen (JS)

If element1 is outside visible area, element2 should be visible. If element1 is inside visible area, element2 should be hidden. (I would like not to use jQuery if possible) This I have so far.
function check(){
var div1 = document.getElementById("element1");
var div2 = document.getElementById("element2");
if(div1.top > (window.top + viewport.height )) {
div2.style.display = "none";
}
else {
div2.style.display = "block";
}
}
With this I get the error 'viewport is not defined'. I know it has to be defined but dont really know how to.
You should attach the function to the scroll event on what element is scrolling and checking that scroll position with the end (as bottom position) of your element1 to check.
This is an example:
function check(){
var div1 = document.getElementById("element1");
var div2 = document.getElementById("element2");
if(document.documentElement.scrollTop > (div1.clientTop + div1.clientHeight )) {
div2.style.display = "block";
}
else {
div2.style.display = "none";
}
}
window.onscroll=check;
body{
height: 200vh;
position: relative;
}
#element1{
border: 1px solid green;
width: 200px;
height: 50px;
}
#element2{
border: 1px solid red;
width: 200px;
height: 50px;
position: fixed;
display: none; /*initial display state*/
top: 50vh;
right: 0;
background-color: salmon;
}
<div id="element1"></div>
<div id="element2"></div>
Also, you can check for the Intersection Observer API which is used sometimes for lazy loading images.
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
If you don't plan on supporting really old browsers (like IE11 and below), you can actually use the Intersection Observer API to achieve what you're doing. The advantage is that the API actually contains configurable logic that can further fine tune at what threshold you want to toggle display state of the target element.
In fact, almost 74% of global browser traffic actually supports Intersection Observer. With the notable exception of Safari. Fret not, there is a polyfill available if you need it.
Here is an example:
function callback(entries) {
entries.forEach(function(entry) {
var elementToToggle = document.getElementById('element2');
elementToToggle.style.display = entry.isIntersecting ? 'none' : 'block';
});
}
var observer = new IntersectionObserver(callback);
observer.observe(document.getElementById('element1'));
body {
min-height: 200vh;
position: relative;
}
.element {
width: 50%;
height: 50px;
border: 1px solid rgba(0,0,0,.25);
}
#element1 {
background-color: steelblue;
position: absolute;
top: 100px;
}
#element2 {
background-color: rebeccapurple;
position: fixed;
top: 25;
right: 0;
}
<div class="element" id="element1"></div>
<div class="element" id="element2"></div>

Prevent Mouseenter and Mouseleave Firing Within Element Without Using Pointer-Events

I'm using 'mouseenter' and 'mouseleave' to change the visibility of an image when I enter and leave an element. My issue is these events keep firing even when I'm within the element. Using 'pointer-events = none' works but it turns off another animation I have on the image. Is there a solution to this that either doesn't use pointer-events nor mousenter/leave and allows me to have animations on my image? DEMO
HTML:
<img id="image" src=""/>
<div id='box' class="box"></div>
CSS:
.box {
border: 2px solid red;
height: 400px;
width: 60%;
margin: 10px auto;
}
#image {
position:absolute;
width: 60px;
height: 60px;
display: none;
}
JS:
$(document).mousemove(function(e){
const height = $('#image').height() / 2;
const width = $('#image').width() / 2;
$("#image").css({
left:e.pageX-width,
top:e.pageY-height
});
});
$('.box').mouseenter(_=> {
$('#image').show();
});
$('.box').mouseleave(_=> {
$('#image').hide();
});
I'm not sure if this accomplishes what you're looking for - but you could change the z-index of the image and the background of the parent container, like:
$(document).mousemove(function(e){
const height = $('#image').height() / 2;
const width = $('#image').width() / 2;
$("#image").css({
left:e.pageX-width,
top:e.pageY-height
});
});
let entries = 0;
let exits = 0
$('.box').mouseenter(_=> {
$('#image').show();
entries += 1;
document.getElementById("entries").textContent=entries;
});
$('.box').mouseleave(_=> {
$('#image').hide();
exits += 1;
document.getElementById("exits").textContent=exits;
});
.box {
border: 2px solid red;
height: 400px;
width: 60%;
margin: 10px auto;
background: transparent;
}
#image {
position:absolute;
width: 60px;
height: 60px;
display: none;
z-index: -1;
}
#display {
position: absolute;
top:0;
left: 0;
border: 1px solid black;
width: 100px;
height: 100px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="image" src="https://i5.walmartimages.ca/images/Large/580/6_r/875806_R.jpg"/>
<div id='box' class="box"></div>
<div id= 'display'>
<div id= 'entries'>00</div>
<div id= 'exits'>00</div>
</div>
Which will cause the .box to always be on top, even though the image is under your cursor.
Have you tried maybe setting a value to indicate the current state of the image?
Something like this:
var showImage = false;
$(document).mousemove(function(e){
const height = $('#image').height() / 2;
const width = $('#image').width() / 2;
$("#image").css({
left:e.pageX-width,
top:e.pageY-height
});
});
$('.box').mouseenter(_=> {
if (showImage)
return;
showImage = true;
$('#image').show();
});
$('.box').mouseleave(_=> {
showImage = false;
$('#image').hide();
});

Arrays are not working with If Statement

New on StackOverFlow - Just have a simple question.
Could you please let me know why it is not changing the color of Div element when the condition is true for the If Statement. .MeTest's display property is Block - Also, no error messages are in the Console.
Here is my test code :
var x = document.getElementsByClassName("MeTest");
if (x[0].style.display == 'block')
{
document.getElementsByClassName("haveIt")[1].style.backgroundColor = "red";
}
#MeTest {
position: fixed;
height: 200px;
width: 200px;
background-color: #fdacc3;
}
div {
background: #4dd329;
border: 1px solid white;
height: 200px;
width: 200px;
display: block;
}
.MeTest {
display: block;
}
<div class="MeTest"></div>
<div class="testThis" style="float: right;"></div>
<div class="haveIt" style="position: fixed; top: 400px;"></div>
Thanks!
You have only one element with the class name haveIt. So you should make the following change:
document.getElementsByClassName("haveIt")[0]
Furthermore, in orde the condition you check to be true, you should define a style with display block for the div with class MeTest.
var x = document.getElementsByClassName("MeTest");
if (x[0].style.display == 'block')
{
document.getElementsByClassName("haveIt")[0].style.backgroundColor = "red";
}
#MeTest{
position: fixed;
height: 200px;
width: 200px;
background-color: #fdacc3;
}
div{
background: #4dd329;
border: 1px solid white;
height: 200px; width: 200px;
display: block;
}
.MeTest{
display: block;
}
<div class="MeTest" style="display: block;"></div>
<div class="testThis" style="float: right;"></div>
<div class="haveIt" style="position: fixed; top: 200px;"></div>
PS: I changed the value of top from 400px to 200px, in order to be seen when you run the snippet.
Update
I see that in my first question about statements, you changed to
display to Block in the HTML DOM - When I call that element in the Css
stylesheet and change the Display to Block, it doesn't work that way.
Any thoughts why it is happening?
It doesn't work since the display property of the element is imposed by the style sheet, it's not a value included in the style attribute of the html element. That you can do in this case, it to make use of getComputedStyle method like in the below snippet.
var x = document.getElementsByClassName("MeTest");
var display = window.getComputedStyle(x[0],null)
.getPropertyValue("display");
if (display == 'block'){
document.getElementsByClassName("haveIt")[0].style.backgroundColor = "red";
}
#MeTest{
position: fixed;
height: 200px;
width: 200px;
background-color: #fdacc3;
}
div{
background: #4dd329;
border: 1px solid white;
height: 200px; width: 200px;
display: block;
}
.MeTest{
display: block;
}
<div class="MeTest"></div>
<div class="testThis" style="float: right;"></div>
<div class="haveIt" style="position: fixed; top: 200px;"></div>
For info regarding the Window.getComputedStyle please have a look [here].1
var x = document.getElementsByClassName("MeTest")[0];
if (getComputedStyle(x).getPropertyValue("display")== 'block')
{
document.getElementsByClassName("haveIt")[1].style.backgroundColor = "red";
}

Child div elements not appearing in parent div element created by JavaScript function

I started learning JavaScript about a few weeks ago, and I have a problem. I have here two functions that are meant to bring up a menu when a button is clicked. In theory the menu that pops up should bring up a small div element from the left side, and 6 div elements within that div element. The main div element has the id "pokemonswitch" and when I click the button with the related function it only brings up "pokemonswitch" the other div elements don't seem to want to appear inside "pokemonswitch". I have tinkered with the code and have gotten various results.
1: Div elements appear in "pokemonswitch as programmed but after I click another button that removes "pokemonwitch" the div elements remain there despite the parent element not being there.
2: The div elements do not appear at all within "pokemonswitch".
3: The div elements appear in random places and the rest of the function doesn't work.
My goal is to have a function that calls up "pokemonswitch" with six div elements inside of it. Is there something I am missing about structure that is causing my child div elements to act so crazy? I hope this is clear enough to be answered, if not I will be more than happy to append more details to the problem.
//MAKE DIV ELEMENT pokemonswitch VISIBLE AND ASSOCIATIVE SLOTS AS WELL
function pkmnFunction() {
var element = document.getElementById('pokemonswitch');
var cancel = document.getElementById('optionsdiv');
element.style.visibility = "visible";
document.getElementById('slot1').style.visibility = "visible";
document.getElementById('slot2').style.visibility = "visible";
document.getElementById('slot3').style.visibility = "visible";
document.getElementById('slot4').style.visibility = "visible";
document.getElementById('slot5').style.visibility = "visible";
document.getElementById('slot6').style.visibility = "visible";
cancel.innerHTML = "<input id='cancelbutton' type='button' value='cancel' onclick='canFunction()' style='position:absolute; top:95px; left:35px;'></input>";
element.innerHTML = "<div id='slot1'></div><div id='slot2'></div><div id='slot3'></div><div id='slot4'></div><div id='slot5'></div><div id='slot6'></div>";
}
//MAKE DIV ELEMENT pokemonswitch HIDDEN AND ASSOCIATED slot ELEMENTS AS WELL
function canFunction() {
var element = document.getElementById('pokemonswitch');
var cancel = document.getElementById('optionsdiv');
document.getElementById('slot1').style.visibility = "hidden";
document.getElementById('slot2').style.visibility = "hidden";
document.getElementById('slot3').style.visibility = "hidden";
document.getElementById('slot4').style.visibility = "hidden";
document.getElementById('slot5').style.visibility = "hidden";
document.getElementById('slot6').style.visibility = "hidden";
element.style.visibility = "hidden"
cancel.innerHTML = "<input id='b5' type='button' onclick='setSlots()' value='Check Slot' ></input><input id='b1' type='button' value='Fight!'></input><input id='b2' type='button' onclick='pkmnFunction()' value='Pkmn'></input><input id='b3' type='button' value='Items' onclick='itemFunction()'></input><input id='b4' type='button' value='Run'></input>";
}
////////////ASSOCIATED CSS STYLE CODE//////////////////
#pokemonswitch {
position: absolute;
width: 180px;
margin - left: -15px;
height: 100 % ;
border: solid;
border - color: black;
border - width: 2px;
border - radius: 25px;
background - color: 0099CC;
z - index: 3;
visibility: hidden;
}
#slot1 {
position: absolute;
top: 0px;
left: -10px;
padding: 5px;
text - align: center;
border: solid;
border - width: 1px;
background - color: red;
width: 170px;
height: 65px;
z - index: 4;
}
#slot2 {
position: absolute;
top: 65px;
left: -10px;
padding: 5px;
text - align: center;
border: solid;
border - width: 1px;
background - color: red;
width: 170px;
height: 65px;
z - index: 4;
visibility: hidden;
}
#slot3 {
position: absolute;
top: 130px;
left: -500px;
padding: 5px;
text - align: center;
border: solid;
border - width: 1px;
background - color: red;
width: 170px;
height: 65px;
z - index: 4;
visibility: hidden;
}
#slot4 {
position: absolute;
top: 195px;
left: -500px;
padding: 5px;
text - align: center;
border: solid;
border - width: 1px;
background - color: red;
width: 170px;
height: 65px;
z - index: 4;
visibility: hidden;
}
#slot5 {
position: absolute;
top: 260px;
left: -500px;
padding: 5px;
text - align: center;
border: solid;
border - width: 1px;
background - color: red;
width: 170px;
height: 65px;
z - index: 4;
visibility: hidden;
}
#slot6 {
position: absolute;
top: 325px;
left: -250px;
padding: 5px;
text - align: center;
border: solid;
border - width: 1px;
background - color: red;
width: 170px;
height: 65px;
z - index: 4;
visibility: hidden;
}
The issue is, you are trying to refer an element that isn't even created yet.
element.innerHTML = "<div id='slot1'></div><div id='slot2'></div><div id='slot3'></div><div id='slot4'></div><div id='slot5'></div><div id='slot6'></div>";//Place this first
document.getElementById('slot1').style.visibility = "visible";
document.getElementById('slot2').style.visibility = "visible";
document.getElementById('slot3').style.visibility = "visible";
document.getElementById('slot4').style.visibility = "visible";
document.getElementById('slot5').style.visibility = "visible";
document.getElementById('slot6').style.visibility = "visible";
cancel.innerHTML = "<input id='cancelbutton' type='button' value='cancel' onclick='canFunction()' style='position:absolute; top:95px; left:35px;'></input>";
Also few other things I noticed were:
Instead of using style.visibility use style.display. <input> isn't a container element, so remove </input> everywhere.
document.getElementById('slot1').style.visibility = "visible";
element.innerHTML = "<div id='slot1'></div>";
This is not right. The first line suggests that an element with id slot already exists. The second line adds a new div with that same id.
If the element should already exist, you can add the existing element
var slot1 = document.getElementById('slot1');
slot1.style.visibility = "visible";
element.appendChild(slot);
If not, you can create it first:
var slot1 = document.createElement('div');
slot1.id = 'slot1';
slot1.style.visibility = "visible";
element.appendChild(slot);
I do it this way! Create a div that contains the form you want and make this div display:none. Then on click make it visible where you want to
<div style="display:none">
<div id="mycontent">
content content
</div>
</div>
then use
document.getElementById('ID')..style.display="value"

Categories

Resources