Reapplying style attributes after dynamically appending elements - javascript

On my page, if I change the attributes of an element such as
<div class="showInitially"></div>
by setting
$(".showInitially").hide()
then any elements added dynamically afterwards like
container.append("<div class='showInitially'>text</div>");
do not inherit the changes.
I know I can re-apply all the changes after I add another element but somehow this seems inefficient and hacky, especially if there are a number of changes to styles made. So, is there another way to add elements to the page that will automatically have the inherited style and attribute changes applied to them?
I've tried
container.trigger("create");
but this does nothing. An example is shown in the snippet below:
var container=$("#container");
var buttons = $("button")
var allDivs = $("#container .showInitially")
buttons.on("click", function(){
buttons.addClass("alt");
allDivs.addClass("alt");
allDivs.hide();
addButton();
})
function addButton(){
container.append("<div><button>Change another color</button></div> <div class='showInitially'>text</div>");
}
body {
background: #cccccc;
padding: 20px;
font-family: Helvetica;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
div{
color:black;
}
.alt{
background: red;
}
.showInitially{
color:orange;
display:inline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container" >
<button>Change color</button> <div class="showInitially">text</div>
</div>

Modify the CSS rule dynamically.
Blatantly ripped off from How do you read CSS rule values with JavaScript? and modify a css rule object with javascript and then cobbled together.
Part of the issue with your code was that your on click only attached the click handler to buttons that already existed. Any new button would not get a click handler, so I moved the handler to the document and added a selector.
var container=$("#container");
var buttons = $("button")
var allDivs = $("#container .showInitially")
$(document).on("click", "button", function(){
buttons.addClass("alt");
allDivs.addClass("alt");
modStyle('.showInitially', 'display', 'none');
//allDivs.hide();
addButton();
})
function addButton(){
container.append("<div><button>Change another color</button></div> <div class='showInitially'>text</div>");
}
function modStyle(className, foo, bar) {
var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules;
for (var x = 0; x < classes.length; x++) {
if (classes[x].selectorText == className) {
(classes[x].cssText) ? classes[x].style[foo] = bar : classes[x].style[foo] = bar;
}
}
}
body {
background: #cccccc;
padding: 20px;
font-family: Helvetica;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
div{
color:black;
}
.alt{
background: red;
}
.showInitially{
color:orange;
display:inline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container" >
<button>Change color</button> <div class="showInitially">text</div>
</div>

Related

How to give an element an id

I have the following code
var inter = [];
const changeColor = (evt) => {
if (evt.currentTarget.classList.contains("is-active")) {
evt.currentTarget.classList.remove("is-active");
} else {
evt.currentTarget.classList.add("is-active");
var elements = document.getElementsByClassName('is-active');
inter = [];
for (var i = 0; i < elements.length; i++) {
inter.push(elements[i].innerHTML)
}
alert(inter);
}
};
const EL_tagger1010_children = document.querySelectorAll(".tagger1010 span");
EL_tagger1010_children.forEach(EL => EL.addEventListener("click", changeColor));
.tagger1010 span {
padding: 6px 10px;
background: #D0E8E4;
border-radius: 18px;
color: #000000;
font-family: Roboto;
font-size: 12px;
margin: 0 4px 8px 0;
font-weight: 500;
display: inline-block;
word-wrap: break-word;
white-space: normal;
cursor: pointer;
user-select: none;
border: 1px solid BBD0CD;
}
.tagger1010 span.is-active {
background-color: #008fde;
color: #ffffff;
}
.tagger1010 span:hover {
background-color: #008fde;
color: #ffffff;
}
<div class="tagger1010">
<span>Google</span>
<span>Microsoft</span>
<span>Facebook</span>
<span>LinkedIn</span>
</div>
<div class="as-console-wrapper"></div>
<div class="as-console"></div>
<div class="as-console-wrapper">
<div class="as-console">
</div>
</div>
This code does what I want it to do for now, but I would like to create an element that has an id that stores the value of the "inter" array in the following code. I have never before seen an instance where a single variable has an id that can be referenced elsewhere. So I was wondering if I can put the value of the "inter" array in a div element, or if I can just assign an id to the inter array itself?
Try using the DOM id feature:
document.getElementById("demo").id = "newid";
Reference:
https://www.w3schools.com/jsref/prop_html_id.asp
You cannot assign the id of an HTML node to a JS array, but you can put the contents of an array in to a div and assign an id to that div. You can create the div on the fly in the JS code, or put it directly into your HTML and just fill in the array values and assign the id. Following an example of how to create a div in JavaScript, set an id on it and put the array values into it one by one:
var arr = ["some", "array", "values"];
div = document.createElement("div"); // create a new div
div.id = "someid"; // set the id of the div
for (var item of arr) {
div.innerHTML += "<p>" + item + "</p>"; // put each array item into a separate paragraph in the div
}
document.body.appendChild(div); // append the div with the paragraphs to the document body
#someid {
background-color: yellow;
}
<body>
<p>The array values are displayed below.</p>
</body>
Giving you another option of just using radio button list to render the selectable list. To get the selection, you just read the form field value.
[name="rb-site"] {
display: none;
}
[name="rb-site"] label {
padding: 6px 10px;
background: #D0E8E4;
border-radius: 18px;
color: #000000;
font-family: Roboto;
font-size: 12px;
margin: 0 4px 8px 0;
font-weight: 500;
display: inline-block;
word-wrap: break-word;
white-space: normal;
cursor: pointer;
user-select: none;
border: 1px solid BBD0CD;
}
[name="rb-site"]:checked + label {
background-color: #008fde;
color: #ffffff;
}
[name="rb-site"] + label:hover {
background-color: #008fde;
color: #ffffff;
}
<div class="tagger1010">
<input type="radio" value="google" id="rb-google" name="rb-site">
<label for="rb-google">Google</label>
<input type="radio" value="microsoft" id="rb-microsoft" name="rb-site">
<label for="rb-microsoft">Microsoft</label>
<input type="radio" value="Facebook" id="rb-facebook" name="rb-site">
<label for="rb-facebook">Facebook</label>
<input type="radio" value="LinkedIn" id="rb-linkedin" name="rb-site">
<label for="rb-linkedin">LinkedIn</label>
</div>
So when you want to get the selected radio button and read the variable.
document.querySelctor('name="rb-site"]:checked').value
It is more HTML, but less JavaScript.

How to I remove all the child element except the first element?

It is a BlackJack game. I have a container which the first child element is a template for cloning card purpose. How to I remove all the child elements except the first element? I think the current code which is the "clearContainer" method remove all child elements.
function makeCardPlayer() {
// .card is created in the template card css class
var card = $(".card.templatePlayer").clone();
//card.removeClass("templatePlayer");
card.addClass("newCard");
$("#cardContainerPlayer").append(card);
}
function clearContainer() {
debugger
//$("cardContainerPlayer > *").slice(1).remove();
var myNode = document.getElementById("cardContainerPlayer");
var fc = myNode.firstChild;
var sib = fc && fc.nextSibling;
while (myNode.lastChild && myNode.lastChild !== sib) {
myNode.removeChild(myNode.lastChild);
}
}
makeCardPlayer();
clearContainer();
#cardContainerPlayer {
display: flex;
flex-wrap: wrap;
}
.card {
display: inline-block;
vertical-align: top;
text-align: center;
margin: 5px;
padding: 10px;
width: 70px;
height: 100px;
font-size: 26px;
background-color: black;
border: solid 1px black;
color: white;
border-radius: 10px;
}
.newCard {
display: inline-block;
vertical-align: top;
text-align: center;
margin: 5px;
padding: 10px;
width: 70px;
height: 100px;
font-size: 26px;
background-color: yellow;
border: solid 1px black;
color: white;
border-radius: 10px;
}
.templatePlayer {
/*display: none;*/
}
<!DOCTYPE html>
<html>
<body>
<div id="cardContainerPlayer">
<div class="card templatePlayer">
<span class="playerCardFace"></span>
<span class="playerCardSuit"></span>
</div>
</div>
</body>
</html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Here are the code which I have removed out extra codes for brevity.
YOu seem to be avoiding jQuery in clearContainer. If you want to use it that function, then
function clearContainer() {
$("#cardContainerPlayer > *").slice(1).remove();
}
That selects all child elements of the container and uses slice to get a set of only the ones after the first one, then removes them.
If you want to use the DOM directly:
function clearContainer() {
var myNode = document.getElementById("cardContainerPlayer");
var fc = myNode.firstChild;
var sib = fc && fc.nextSibling;
while (myNode.lastChild && myNode.lastChild !== sib) {
myNode.removeChild(myNode.lastChild);
}
}
Or you might use firstElementChild, nextElementSibling, and lastElementChild, depending on what you want to do and whether you need to handle text nodes in there. More on those various properties in MDN's DOM documentation.
You should use the nextSibling() method to find and delete every sibling of the 1st child :
function clearContainer() {
debugger
var myNode = document.getElementById("cardContainerPlayer");
var fc = myNode.firstChild;
while (fc.nextSibling) {
myNode.removeChild(fc.nextSibling);
}
}
In your clearContainer() method, you can use something like this
function clearContainer() {
debugger
var myNode = document.getElementById("cardContainerPlayer");
var fc = myNode.firstChild;
while (fc.nextSibling) {
myNode.removeChild(fc.nextSibling);
}
}
By removing the next sibling of the child, at the end you will be left just with the firstChild.

Can't append a Child to a newly created one (HTML and JS)

<style>
div {
border: 1px solid black;
padding: 5px;
width: 400px;
margin: 0 auto;
}
div h1 {
text-align: center;
margin-top: 0px;
margin-bottom: 0px;
}
section {
border: 1px solid black;
padding: 5px;
}
input[type=text] {
padding: 3px;
width:150px;
height:10px;
}
</style>
<body>
<div id="wrapper">
<h1>Tuesday TODO List</h1>
<input type="text" id="sectionText" class="sectionText" placeholder="Title" />
<button id="btn" class="btn">New Section</button>
</div></body>
My Script
var a = document.getElementById('btn');
a.addEventListener('click', function () {
var b = document.createElement('section');
document.getElementById('wrapper').appendChild(b);
}, false);
So far the script works, but i want to append a child and set it's id to var b and when i try it, it doesn't works.
var d = document.createElement('INPUT');
d.setAttribute('type', 'text').setId('id name');
b.appendChild(d);
And this 3 lines when i put them inside of the event listener it doesn't works, i just separated them outside for convenience
Your code should have to be like this,
var d = document.createElement('INPUT');
d.setAttribute('type', 'text')
d.setAttribute('id', 'id name');
Since setAttribute doesn't return anything rather than undefined.
You can't chain it.
There is no function like setId available by default in the node's
proto. You have to use setAttribute for setting an id.

Disappearing drop down menu

I am trying to create a disappearing drop down menu that disappears into the top of the page, and you can only see the word 'open'. This opens the the menu, the word open changes to the word close which when clicked makes the menu disappear again. Help would be much appricated.
<html>
<head>
<title>dropdown</title>
<link rel="stylesheet" type="text/css" href="dropdown_css.css">
<script type = "text/javascript">
function navagate(menu) {
var panel = document.getElementById(menu),maxh = "-362px", navg = document.getElementById('navag');
if (panel.style.marginTop == maxh){
panel.style.marginTop = "0px";
navag.innerHTML = "Close";
}
else {
panel.style.marginTop = maxh;
navag.innerHTML = "Open";
}
}
window.onload = function(){panel.style.marginTop = "-362px";}
</script>
<body>
<div id = "panel">
<ul>
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
<div id ="sections_button">
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
</html>
#panel {
width : 160px;
height: 130px;
background-color: gray;
margin-left: 30px;
margin-top:20px;
}
#panel li {
list-style-type: none;
}
Here, I've made a JS fiddle that may help you out: http://jsfiddle.net/942z0nhh/ I did not play around with the styling at all.
A few things I noticed:
You're making some mistakes that I think you wouldn't make if you indented properly. Take a look here, where you closed your body twice:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
Second, you have some spelling mistakes:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
vs
function navagate(menu) {
You can see there that your function would never be called because of it.
Lastly, your 'open' and 'close' a here:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
Was within the div your function was overwriting. The function would change it to 'close'- but then it wouldn't be visible to the user anyway! I moved it above, which I hope makes sense.
Please let me know if you have any other questions, or if I misunderstood.
You could also do it only with CSS. It's the "css checkbox hack". I'm having it not like you want it but it is pretty close. Changing the text from open to close should be also possible.
At the moment, I don't know how to move the open/close label below the ul list.
*, html {
padding: 0px;
font-family: sans-serif;
}
/* Checkbox Hack */
input[type=checkbox] {
position: absolute;
display: none;
}
label {
display: block;
cursor: pointer;
content: "close";
}
/* Default State */
#wrapper {
display: block;
background: gray;
color: white;
text-align: center;
}
/* Toggled State */
input[type=checkbox]:checked ~ #menu {
display: block;
background: lightgray;
color: black;
top:0px;
}
.menuToggle ul{
display: none;
width: 100%;
}
#menu {
padding-top: 5px;
margin: 0px;
list-style: none;
}
<div id="wrapper">
<div class="menuToggle">
<label for="toggle-1">open</label>
<input type="checkbox" id="toggle-1"/>
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
</div>
</div>
With jQuery you could do it like the example below.
I think it is now almost like you wanted it. Maybe some styling improvements are required.
With the css hack I couldn't manage the text change. With js you have more possibilities. You could also improve/modify the animations.
$(function() {
var $menuButton = $('#openButton');
var $menu = $('#menu');
var btnToggleAnim = function() {
$menuButton.animate({opacity: 'toggle'}, "fast");
};
var menuToggleAnim = function() {
$('#menu').animate({
height:'toggle',
//opacity: 'toggle'
}, { duration: "slow" });
};
$('#closeButton,#openButton').on('click', function() {
menuToggleAnim();
btnToggleAnim();
});
});
*, html {
padding: 0px;
font-family: sans-serif;
}
a {
text-decoration:none;
}
#openButton {
display:block;
background: gray;
color: #fff;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
#closeButton{
display: block;
background: gray;
color: #fff;
text-align: center;
border: 2px solid lightgray;
border-bottom-left-radius: 13px;
border-bottom-right-radius: 13px;
}
#wrapper {
display: block;
text-align: center;
}
#menu {
display: none;
background: lightgray;
color: black;
padding-top: 5px;
margin: 0px;
list-style: none;
}
#menu {
color: #000;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
open
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
<li>close</li>
</ul>
</div>

How do you set a JavaScript onclick event to a class with css

Let's say I want that every time the user click any link an alert pops up that says "hohoho".
Do I need to add onclick="alert('hohoho')" to every link or can I set this with CSS so that it works with every link?
You can't do it with just CSS, but you can do it with Javascript, and (optionally) jQuery.
If you want to do it without jQuery:
<script>
window.onload = function() {
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
anchor.onclick = function() {
alert('ho ho ho');
}
}
}
</script>
And to do it without jQuery, and only on a specific class (ex: hohoho):
<script>
window.onload = function() {
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
if(/\bhohoho\b/).match(anchor.className)) {
anchor.onclick = function() {
alert('ho ho ho');
}
}
}
}
</script>
If you are okay with using jQuery, then you can do this for all anchors:
<script>
$(document).ready(function() {
$('a').click(function() {
alert('ho ho ho');
});
});
</script>
And this jQuery snippet to only apply it to anchors with a specific class:
<script>
$(document).ready(function() {
$('a.hohoho').click(function() {
alert('ho ho ho');
});
});
</script>
You can do this by thinking of it a little bit differently. Detect when the body is clicked (document.body.onclick - i.e. anything on the page) and then check if the element clicked (event.srcElement / e.target) has a class and that that class name is the one you want:
document.body.onclick = function(e) { //when the document body is clicked
if (window.event) {
e = event.srcElement; //assign the element clicked to e (IE 6-8)
}
else {
e = e.target; //assign the element clicked to e
}
if (e.className && e.className.indexOf('someclass') != -1) {
//if the element has a class name, and that is 'someclass' then...
alert('hohoho');
}
}
Or a more concise version of the above:
document.body.onclick= function(e){
e=window.event? event.srcElement: e.target;
if(e.className && e.className.indexOf('someclass')!=-1)alert('hohoho');
}
You could do it with jQuery.
$('.myClass').click(function() {
alert('hohoho');
});
It can't be done via CSS as CSS only changes the presentation (e.g. only Javascript can make the alert popup). I'd strongly recommend you check out a Javascript library called jQuery as it makes doing something like this trivial:
$(document).ready(function(){
$("a").click(function(){
alert("hohoho");
});
});
Following JCOC611 suggestion:
window.onload = function() {
let elements = document.getElementsByClassName("someClassName");
for(let i = 0; i < elements.length; i++) {
elements[i].onclick = function () {
alert("Clicked in an element of the class.");
}
}
};
Here is my solution through CSS, It does not use any JavaScript at all
HTML:
Open Modal
<div id="openModal" class="modalDialog">
<div> X
<h2>Modal Box</h2>
<p>This is a sample modal box that can be created using the powers of CSS3.</p>
<p>You could do a lot of things here like have a pop-up ad that shows when your website loads, or create a login/register form for users.</p>
</div>
</div>
CSS:
.modalDialog {
position: fixed;
font-family: Arial, Helvetica, sans-serif;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
z-index: 99999;
opacity:0;
-webkit-transition: opacity 400ms ease-in;
-moz-transition: opacity 400ms ease-in;
transition: opacity 400ms ease-in;
pointer-events: none;
}
.modalDialog:target {
opacity:1;
pointer-events: auto;
}
.modalDialog > div {
width: 400px;
position: relative;
margin: 10% auto;
padding: 5px 20px 13px 20px;
border-radius: 10px;
background: #fff;
background: -moz-linear-gradient(#fff, #999);
background: -webkit-linear-gradient(#fff, #999);
background: -o-linear-gradient(#fff, #999);
}
.close {
background: #606061;
color: #FFFFFF;
line-height: 25px;
position: absolute;
right: -12px;
text-align: center;
top: -10px;
width: 24px;
text-decoration: none;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
}
.close:hover {
background: #00d9ff;
}
CSS alert No JavaScript Just pure HTML and CSS
I believe that it will do the trick for you as it has for me
Many 3rd party JavaScript libraries allow you to select all elements that have a CSS class of a particular name applied to them. Then you can iterate those elements and dynamically attach the handler.
There is no CSS-specific manner to do this.
In JQuery, you can do:
$(".myCssClass").click(function() { alert("hohoho"); });
Asking about "a class" in the question title, the answer is getElementsByClassName:
var hrefs = document.getElementsByClassName("YOUR-CLASS-NAME-HERE");
for (var i = 0; i < hrefs.length; i++) {
hrefs.item(i).addEventListener('click', function(e){
e.preventDefault(); /*use if you want to prevent the original link following action*/
alert('hohoho');
});
}

Categories

Resources