I have site that, in response to user interaction, dynamically creates divs using jquery. The div will have a span inside containing a timestamp to show its creation time, and the user can click a button to show or hide the timestamp span.
I ran into the issue of, when the user selects to hide timestamps, how do you prevent future dynamically added spans from showing? In reference to this question Create a CSS rule / class with jQuery at runtime, I added a style tag in the head dynamically. However, I also intended to allow the user to be able to choose a font from a drop down list and change the font style of the text inside the divs. Following this method now seems like it would create a lot of overhead.
Both issues revolve around the same issue: change already existing element and any future dynamically created matching element's css style, but I'm not sure the method mentioned above is really the best solution?
EDIT: SNIPPET
$(function() {
$('#add').click(function() {
$('#display').append("<div><span class='time'> ex. Timestamp</span> Div text contents...</div>");
});
$('#hidetime').click(function() {
$(this).text(function(i, text) {
if (text === "Hide Time") {
$("<style>").prop("type", "text/css")
.html(".time {display: none}").appendTo("head");
return "Show Time";
} else {
$('style').remove();
return "Hide Time";
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='add'>Add</button>
<button id='hidetime'>Hide Time</button>
<div id='display'>
</div>
You've provided no code to debug, but the way you can do this is to toggle a class such as notimestamps on the container element for the whole thing.
Then in your main CSS code you can simply do something along the lines of:
.container.notimestamps span {
display:none;
}
If you're changing font styles, you can do something very similar.
Example:
.container.font-arial {
font-family: arial, sans-serif;
}
.container.font-tahoma {
font-family: tahoma, sans-serif;
}
Using your recently added example you would change it to:
$(function() {
$('#add').click(function() {
$('#display').append("<div><span class='time'> ex. Timestamp</span> Div text contents...</div>");
});
$('#hidetime').click(function() {
$('#display').toggleClass('notimestamp');
});
$('#font').change(function() {
$('#display').attr('data-font', $(this).val());
});
});
#display.notimestamp span {
display:none;
}
#display {
font-family:sans-serif;
}
#display[data-font="arial"] {
font-family:Arial;
}
#display[data-font="georgia"] {
font-family:Georgia;
}
#display[data-font="tahoma"] {
font-family:Tahoma;
}
#display[data-font="tnr"] {
font-family:"Times New Roman";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='add'>Add</button>
<button id='hidetime'>Hide Time</button>
<select id="font">
<option value="arial">Arial</option>
<option value="georgia">Georgia</option>
<option value="tahoma">Tahoma</option>
<option value="tnr">Times New Roman</option>
</select>
<div id='display'>
</div>
You can achieve it using plain javascript
Here is an example. You can add any similar styles dynamically
HTML
<div id="myDiv" style="margin: 50px 50px 50px 50px">This is a div.</div>
<br />
<button type="button" onclick="removemargin()">remove margin</button>
<button type="button" onclick="removeLeftMargin()">remove leftmargin</button>
<button type="button" onclick="removeTopMargin()">remove topmargin</button>
<button type="button" onclick="addCssMargin()">add margin by adding class (dominant here)</button>
CSS
#myDiv {
background: #EEE;
}
.myclass{
margin : 100px 10px 15px 50px !important;
background:red !important;
}
JAVASCRIPT
function removemargin() {
document.getElementById("myDiv").style.margin = "0";
}
function removeLeftMargin() {
document.getElementById("myDiv").style.marginLeft = "0";
}
function removeTopMargin() {
document.getElementById("myDiv").style.marginTop = "0";
}
function addCssMargin() {
var d = document.getElementById("myDiv");
d.className = d.className + " myclass";
}
JsFiddle
Related
I used the following code to toggle a button class in order to make a full-screen mobile menu.
HTML
button class="hamburger hamburger--slider" type="button">
<a href='#'><div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</a>
document.addEventListener('DOMContentLoaded', function() {
jQuery(function($){
$('.hamburger').click(function(){
$('.hamburger--slider').toggleClass('is-active');
});
});
});
Now I would like to hide another item in my header when the toggled class .is-active is present.
The following code works to hide the item, but once the toggled class is gone, the item does not reappear but stays hidden until the page is reloaded.
jQuery(function($) {
if ($('.hamburger--slider.is-active').length) {
$('.rey-headerCart-wrapper').hide();
}
});
Appreciate any help :) !
you have to show the element again after the burger menu closes:
document.addEventListener('DOMContentLoaded', function() {
jQuery(function($){
$('.hamburger').click(function(){
$('.hamburger--slider').toggleClass('is-active');
// hide / show other element
if ($('.hamburger--slider.is-active').length) {
$('.rey-headerCart-wrapper').hide();
} else {
$('.rey-headerCart-wrapper').show();
}
});
});
});
Or in vanilla javascript:
window.addEventListener("load", () => {
document.querySelector(".hamburger").addEventListener("click", () => {
document.querySelector(".hamburger--slider").classList.toggle("is-active");
// hide / show other element
const cart = document.querySelector(".rey-headerCart-wrapper");
if (document.querySelector(".hamburger--slider.is-active")) {
cart.style.display = "none";
} else {
cart.style.display = "block";
// apply original display style
// cart.style.display = "inline-block";
// cart.style.display = "flex";
};
});
})
In order to make toggle functions like this more understandable, maintainable and extendable you need to think about your HTML structure.
In your current structure, you have a button that toggles a class on itself. Therefore any element beyond that button that has to change appearance or beaviour has to check which class that button has, or you have to extend the click-event handler in order to add these elements (that's what you did here).
This can get quite messy really fast.
A better approach could be to not toggle a class on the button but on an element that is a common parent to all elements that you want to change the behavior of.
That way anything you ever add to that wrapper already can be manipulated via CSS, without the need of changing your JS.
$('.nav-toggler').on('click', function() {
$('#nav-wrapper').toggleClass('active');
});
.menu, .cart {
padding: 1em;
margin: 2px;
}
.cart {
background: #FFF000;
}
.menu{
background: #F1F1F1;
display: none;
}
#nav-wrapper.active > .menu {
display: block;
}
#nav-wrapper.active > .cart {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="nav-wrapper">
<button class="nav-toggler">Toggle</button>
<div class="menu">My Menu</div>
<div class="cart">My Cart</div>
</div>
I was in the middle of self studying HTML, CSS and JavaScript when at my job, an interviewer came to me and suggested to study jQuery as it was the “standard” now days.
So I decided to do that and started to migrate my own web page project for a future game I'm going to make, to jQuery, and it is pretty easy to understand so far and made me compress 150 or so lines of javaScript into 70 (more or less).
Now I am trying to add a class to a button when clicked using jQuery,
for that I am using:
$(this).addClass("buttonActive");
In CSS, the button is:
.menu .buttonActive {
background-color: #222629;
}
When clicking the button, the buttin does change color, and that is perfect, but I wanted to make so that the color changes to the original one once I click another button, but it is not working.
For that I am using:
$("#buttonClicked").removeClass("buttonActive");
I also tried adding another class together when removing the buttonActive but it didn't work.
$("#buttonClicked").removeClass("buttonActive").addClass("buttonNotActive");
.buttonNotActive {
background-color: #10394E;
}
Try this example:
First remove buttonActive class from all buttons except the clicked one
Toggle buttonActive class for the clicked button
$(".myButton").click(function() {
$(".myButton").not($(this)).removeClass('buttonActive');
$(this).toggleClass("buttonActive");
})
.menu .buttonActive {
background-color: #222629;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu">
<button class="myButton">My button</button>
<button class="myButton">My button</button>
<button class="myButton">My button</button>
</div>
I didn't understand well. Like this?
$("#buttonClicked").click(function(){
$(this).addClass("buttonActive");
})
$("#change").click(function(){
$("#buttonClicked").removeClass("buttonActive");
})
.menu .buttonActive {
background-color: #222629;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu">
<button id="buttonClicked">Button</button>
<button id="change">Change</button>
</div>
Add a class to each of the elements that would be clicked. Use that class for the click function. When that element is clicked, remove the active class from the elements, and apply it to the element that was clicked.
In this example when you click on one of the elements its background will change to red. If you click on another element, it returns to its original color.
$( ".menu-item" ).click(function() {
$(".menu-item").removeClass("buttonActive");
$(this).addClass("buttonActive");
});
.item-1 {
background-color: green;
}
.item-2 {
background-color: orange;
}
.item-3 {
background-color: purple;
}
.menu p {
color: #fff;
}
.buttonActive {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<div class="menu">
<p class="item-1 menu-item">Item 1</p>
<p class="item-2 menu-item">Item 2</p>
<p class="item-3 menu-item">Item 3</p>
</div>
Thanks to everyone who answered.
Thanks to the ideas, I thought of selecting all buttons from my page and removing the buttonActive class
$(:button).removeClass("buttonActive");
$(this).addClass("buttonActive");
In a web form, I'm using two select2 control at two panel each.
I wish to change only one of the select2's background colour when it hit certain condition through javascript else it will remain its original colour.
How can I accomplish that?
I am at the stage where the css code below I found is able to modify the select2 to the result I want.
.select2-container .select2-selection{
background: yellow;
}
Any help is much appreciated.
Edited:
Adding some part of my code:
CSS
.select2-container {
position: relative;
z-index: 2;
float: left;
margin-bottom: 0;
display: table;
table-layout: fixed;
font-size: smaller;
}
Markup
<div class="container-fluid">
<div class="col-md-7">
<table>
<tr>
<td>
<select id="ddl_Select2ONE" runat="server" class="form-control select"></select>
</td>
</tr>
</table>
</div>
<div class="col-md-5">
<table>
<tr>
<td>
<select id="ddl_Select2TWO" runat="server" class="form-control select"></select>
</td>
</tr>
</table>
</div>
</div>
Javascript
pageLoad(){
configureSelect2()
}
configureSelect2(){
if(hf_value.value == "1"){
//Change only ddl_Select2ONE to yellow background
}
else{
//Change only ddl_Select2ONE to original background
}
}
Then I will perform some checking on javascript's pageload when it check a hidden field value for conditional enable.
You can use:
document.getElementById('idOfElement').classList.add('select2-container')`;
Or using jquery:
$("#idOfElement").addClass("select2-container");
$("#idOfElement").addClass("select2-selection");
Ok your javascript should look something like this:
document.querySelector('#ddl_Select2ONE').style.background = "Yellow";
And in your else clause:
document.querySelector('#ddl_Select2TWO').style.background = "Yellow";
Try this
function declaration syntax was wrong.
use with classList function
//add in your js
function pageLoad() {
configureSelect2()
}
function configureSelect2() {
if (hf_value.value == "1") {
document.getElementById("ddl_Select2ONE").classList.add("yellow");
} else {
document.getElementById("ddl_Select2ONE").classList.remove("yellow");
}
}
//add in your css
.yellow{
background-color:yellow !important;
}
Solved and solution provided here :
What I need was the "!important" in css class and finding the span I need to add the css class to.
CSS
.yellowBackground{
background: yellow !important;
}
javascript
function pageLoad(){
configureSelect2()
}
function configureSelect2(){
td_Name = document.getElementById("<%=td_Name.ClientID %>");
if (hf_Value.value == "1") {
($(td_Name).find('span')).addClass('yellowBackground');
}
else {
($(td_Name).find('span')).removeClass('yellowBackground');
}
}
Hope this helps!
I'm trying to create a function to change my font color but I need to print it, at the moment all it's ok but I'm having problems with the CSS on print, here is my code
$('#draw').on('click', 'p', function () {
if($(this).hasClass("highlited")) {
$(this).removeClass("highlited");
} else {
$(this).addClass("highlited");
}
});
$('#click').click(function () {
var html = "";
html += '<p>I want to be red...</p>';
html += '<p>Me too...</p>';
html += '<p>Ok... Me too...</p>';
$('#draw').html(html);
});
.highlited {
color: red;
}
#media print {
.highlited {
color: red;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="draw">
<button id="click">Click me</button>
</div>
<hr />
<button onclick="window.print();">Print</button>
NOTE
On snippet works perfect but when I try it in my browser not and on codepen too.
Code not working on CodePen
I'm using Google Chrome. What is the problem and how can I solve it? Thanks in advance.
EDIT
In this picture you can see my problem, When you click a '' element the font color change to red but when you click on print button appears in black, this happen with CodePen code and in my browser but I don't know why works perfectly on Snippet code...
This is what you need. Some sites have their own media print so you need to add -webkit-print-color-adjust: exact; to your media print and !important it to make sure it overrides any other media print.
http://codepen.io/anon/pen/JRXEko
<div id="draw">
<button id="click">Click me</button>
</div>
<hr />
<button onclick="window.print();">Print</button>
.highlited {
color: red;
}
#media print {
.highlited {
color: red !important;
-webkit-print-color-adjust: exact;
}
}
$('#draw').on('click', 'p', function () {
if($(this).hasClass("highlited")) {
$(this).removeClass("highlited");
} else {
$(this).addClass("highlited");
}
});
$('#click').click(function () {
var html = "";
html += '<p>I want to be red...</p>';
html += '<p>Me too...</p>';
html += '<p>Ok... Me too...</p>';
$('#draw').html(html);
});
Your issue is that the p tags are not on the page until you have clicked #click. Try this instead:
$(document).on('click', '#draw p', function () {
if($(this).hasClass("highlited")) {
$(this).removeClass("highlited");
} else {
$(this).addClass("highlited");
}
});
https://jsbin.com/fetumucero/edit?html,css,js,console,output
Maybe the codepen?
View explaple plnkr:
plnkr.co/edit/NZrYQdGNOntaVwkvK4ZH?p=preview
regards!
This question already has answers here:
Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)
(26 answers)
Closed 2 years ago.
I have the grap constructured by CSS, which is dynamically changes by JS. I show graph max value by pseudo element as:
.graph:before {
content:""; //value that want set by JS
position:absolute;
top:0;
left:0;
}
That's why I need to set this value by JS. I tried $(".graph:before").css("content", hh); but it didn't help. How to get that value?
I hope the below snippet might help, you can specify the content value you want via JS using the CSS attr() function.
Below you have two options: to use JavaScript or jQuery:
jQuery:
$('.graph').on('click', function () {
//do something with the callback
$(this).attr('data-before','anything'); //anything is the 'content' value
});
JavaScript:
var graphElem = document.querySelector('.graph');
graphElem.addEventListener('click', function (event) {
event.target.setAttribute('data-before', 'anything');
});
CSS:
.graph:before {
content: attr(data-before); /* value that that refers to CSS 'content' */
position:absolute;
top: 0;
left: 0;
}
Update (2018): as has been noted in the comments, you now can do this.
You can't modify pseudo elements through JavaScript since they are not part of the DOM. Your best bet is to define another class in your CSS with the styles you require and then add that to the element. Since that doesn't seem to be possible from your question, perhaps you need to look at using a real DOM element instead of a pseudo one.
You can use CSS variable
:root {
--h: 100px;
}
.elem:after {
top: var(--h);
}
let y = 10;
document.documentElement.style.setProperty('--h', y + 'px')
https://codepen.io/Gorbulin/pen/odVQVL
I believe there is a simple solution using the attr() function to specify the content of the pseudo element. Here is a working example using the 'title' attribute, but it should work also with custom attributes.:
document.getElementById('btn_change1').addEventListener("click", function(){
document.getElementById('test_div').title='Status 1';
});
document.getElementById('btn_change2').addEventListener("click", function(){
document.getElementById('test_div').title='Status 2';
});
#test_div {
margin: 4em;
padding:2em;
background: blue;
color: yellow;
}
#test_div:after {
content:attr(title);
background: red;
padding:1em;
}
<button id='btn_change1'>Change div:after to [Status 1]</button>
<button id='btn_change2'>Change div:after to [Status 2]</button>
<div id='test_div' title='Initial Status'>The element to modify</div>
People who are still looking some solution of same problem, it is doable as follows using jQuery:
<button id="changeBefore">Change</button>
<script>
var newValue = '22';//coming from somewhere
var add = '<style>.graph:before{content:"'+newValue+'"!important;}</style>';
$('#changeBefore').click(function(){
$('body').append(add);
});
</script>
This example illustrate that on clicking button: changeBefore , the value for .graph:before will change as per new dynamic coming value for it.
For more description about changing of :before or :after element style or getting its content:
Lets suppose your HTML is like this:
<div id="something">Test</div>
And then you are setting its :before in CSS and designing it like:
#something:before{
content:"1st";
font-size:20px;
color:red;
}
#something{
content:'1st';
}
Please notice I also set content attribute in element itself so that you can take it out easily later.
Now there is a button clicking on which, you want to change the color of :before to green and its font-size to 30px. You can achieve that as follows:
Define a css with your required style on some class .activeS :
.activeS:before{
color:green !important;
font-size:30px !important;
}
Now you can change :before style by adding the class to your :before element as follows:
<button id="changeBefore">Change</button>
<script>
$('#changeBefore').click(function(){
$('#something').addClass('activeS');
});
</script>
If you just want to get content of :before, it can be done as:
<button id="getContent">Get Content</button>
<script>
$('#getContent').click(function(){
console.log($('#something').css('content'));//will print '1st'
});
</script>
I hope it helps
I had a similar problem, but with icons. I needed to switch the play and pause icons for an audio player in html5.
The problem here was that HTML, CSS and jQuery all interpret differently the "content" values to show icons, due to the use of \ symbol.
So the best workaround is to delete and re-create the node. Here's my code:
<ul class="list list--buttons">
<li><i class="fa fa-step-backward"></i></li>
<li><i class="fa fa-play"></i></li>
<li><i class="fa fa-step-forward"></i></li>
</ul>
And the script
<script type="text/javascript">
$(
function(){
var aud = $('audio')[0];
$('.playpause').on('click', function(e){
e.preventDefault();
if (aud.paused) {
aud.play();
/* from play icon to pause icon */
$('.playpause .fa-play').remove();
$('.playpause').append('<i class="fa fa-pause"></i>');
}
else {
aud.pause();
/* from play icon to pause icon */
$('.playpause .fa-pause').remove();
$('.playpause').append('<i class="fa fa-play"></i>');
}
})
$('.next').on('click', function(e){
e.preventDefault();
aud.src = '{$content:audio-file}';
})
$('.previuos').on('click', function(e){
e.preventDefault();
aud.src = '{$content:audio-file}';
})
aud.ontimeupdate = function(){
$('.progress').css('width', aud.currentTime / aud.duration * 100 + '%')
}
})
</script>
Hope it helps!
You can use document.styleSheets to modify pseudo selector cssRules
document.styleSheets[0].cssRules[0].style.content = '"111"';
If you use something like an onoffswitch and want to translate the css content attribute with i18next then you can use one of the i18next Framework example from github (i18next Jquery Framework) and then you extended the function with this code:
var before = i18next.t('onoffswitch.before');
var after = i18next.t('onoffswitch.after');
$('.onoffswitch-inner')
.attr('data-before', before )
.attr('data-after', after );
and the css code must be this:
.onoffswitch-inner:before {
content: attr(data-before);
padding-left: 10px;
background-color: #65AFF5; color: #FFFFFF;
}
.onoffswitch-inner:after {
content: attr(data-after);
padding-right: 10px;
background-color: #EEEEEE; color: #999999;
text-align: right;
}