Changing the font-size of future elements with JavaScript - javascript

I am building a simple chat bot.On each new message received from the server, a new HTML element is created and pushed to the browser. So, for example, message 1 will be:
<div class="message-computer"><p>Hi, how are you?</p></div>
Then you (the user) types/sends a message, which shows up as:
<div class="message-user"><p>I am good, thanks!</p></div>
and so on and so forth. I created a slider to change the size of the text being sent to/from the chat bot. It now works, but it only edits EXISTING HTML elements. New messages sent to/from the server are still in the original size.
$('input').on('change', function() {
var v = $(this).val();
$('.message-computer p').css('font-size', v + 'em')
$('.message-user p').css('font-size', v + 'em')
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="range" value="1" min="1" max="1.6" step=".1" id="slider" ondrag="changeSize()" />
How can I make the change in font size apply to all new elements sent to the browser?
Thanks

Not sure I understand well your problem, your code snippet doesn't contain any text.
But when using jQuery to update style, CSS statment is added individualy into each element style attribute (look at your browser inspector).
So newly added elements wont have their style attribute modified until you rechange the input value, and so will inherit from global CSS rules.
I suggest to apply the font style to the parents .message-computer & .message-user.
If you can't, wrap p elements into a dedicated div and apply the style to the div.
If you really need to apply it individually to each element, run $('input').trigger('change'); just after inserting new elements into the DOM.

What you want to do is add a class to a parent tag of your HTML, and to then have a CSS rule which applies to all of the like-elements on the page.
Then, no matter how many .message element you add to your .parent element, a CSS rule applies to them equally.
For instance, something like this would work. You could make this approach more efficient, but this illustrates the idea.
$('input').on('change', function() {
var v = $(this).val();
$('.parent').removeClass('font-1');
$('.parent').removeClass('font-2');
$('.parent').removeClass('font-3');
$('.parent').removeClass('font-4');
$('.parent').removeClass('font-5');
$('.parent').addClass('font-' + v);
});
.parent.font-1 .message {
font-size: 1em;
}
.parent.font-2 .message {
font-size: 2em;
}
.parent.font-3 .message {
font-size: 3em;
}
.parent.font-4 .message {
font-size: 4em;
}
.parent.font-5 .message {
font-size: 5em;
}
.message-computer {
color: red;
}
.message-user {
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="range" value="1" min="1" max="5" step="1" id="slider" ondrag="changeSize()" />
<div class="parent font-1">
<div class="message-computer message"><p>I AM ROBOT</p></div>
<div class="message-user message"><p>Only human.</p></div>
</div>

You're only modifying existing node.
If you want that new node take those rules simply build a javascript function that add or update dynamically a css node
function changeSize(v)
{
var css = [
".message-computer p, .message-user p {font-size: "+v+"em;}"
].join("");
var head = document.head || document.getElementsByTagName('head')[0];
var style = null;
if(!document.getElementById("customTextSize"))
{
style = document.createElement('style');
style.id = "customTextSize";
style.type = 'text/css';
style.appendChild(document.createTextNode(css));
head.appendChild(style);
}
else
{
style = document.getElementById("customTextSize");
style.removeChild(style.firstChild);
style.appendChild(document.createTextNode(css));
}
}
On your on change simply call the function :
changeSize(v)

Related

How do I change ::selected in JavaScript? [duplicate]

I'm searching online and I didn't find anything.
I'm trying to update the placeholder color of a textbox using javascript, but how can I do that?
I have a color picker and the color is changing.
If I have something like this in my CSS, how can I update it?
::placeholder {
color: red;
}
<input placeholder="placeholder" />
Is there a javascript command to edit this?
Something like
document.getElementById('text').style.placeholderColor = newColor;
Use CSS variables. You can also target only the needed element
function update() {
document.querySelector('input[type=text]').style.setProperty("--c", "blue");
}
::placeholder {
color: var(--c, red);
}
<input type="text" placeholder="I will be blue">
<input type="number" placeholder="I will remain red">
<button onclick="update()">change</button>
CSS variables are useful when it comes to modify pseudo elements that you cannot access with JS such as :before/:after/::placeholer/::selection, etc. You simply define your custom property that you can easily update on the main element and the pseudo element will inherit it.
Related : Selecting and manipulating CSS pseudo-elements such as ::before and ::after using jQuery
As stated in the other answers, you cannot change pseudo-element styles inline. However, you can modify the CSS rule in the <style> itself, and you don't need a browser support ing CSS variables for that. Access the stylesheet and either get the existing rule or insert your own, then play with its style declarations like you would with an element .style:
const {sheet} = Object.assign(document.head.appendChild(document.createElement("style")), {type: "text/css" });
const placeholderStyle = sheet.rules[sheet.insertRule("::placeholder {}")].style;
placeholderStyle.color = "red";
Object.assign(document.body.appendChild(document.createElement("input")), {
type: "button", value: "Color!", onclick() {
placeholderStyle.color = "#"+Math.round(Math.random()*0xFFF).toString(16).padStart("0",3);
}});
<input placeholder="placeholder" />
There is another approach, but it's somewhat hacky: use JS to append more CSS to the end of the body. Browsers will override current CSS with the newest CSS, assuming the rules are identical.
function changeColor(toColor) {
addCSS = document.createElement('style');
addCSS.innerHTML = "::placeholder { color: " + toColor + "; }";
document.body.append(addCSS);
}
::placeholder { color: green; }
<input type="text" placeholder="placeholder">
<button onclick="changeColor('red')">red</button>
<button onclick="changeColor('blue')">blue</button>
The snippet below works without needing to make any changes to any existing CSS. You would need to modify it to work with your color picker, but hopefully this will give you something to start with.
const placeholder = document.createElement("style");
placeholder.innerHTML = `::placeholder { color:red;font-weight:bold;font-size:1.25rem;} #plchld { font-size:1.25rem;text-align:center; } `;
const plchld = document.getElementById("plchld");
plchld.addEventListener("click", function () {
plchld.setAttribute("placeholder", "Now I'm Bright Red!");
document.form.appendChild(placeholder);
});
plchld.addEventListener("blur", function () {
plchld.setAttribute("placeholder", "now I'm a dreary gray again...");
document.form.removeChild(placeholder);
});
<form name="form" action="">
<input type="text" id="plchld" size="28" placeholder="I'm currently a dreary shade of gray...">
</form>
If the placeholder color semantics depends on some state, it can be set indirectly
::placeholder { color: green; }
.warn::placeholder { color: red; }
<input id="test" placeholder="hello">
<button onclick="test.classList.toggle('warn')">Warning!</button>
In many cases this doesn't require javascript at all:
::placeholder { color: green; }
.color::after { content: 'green'; }
:checked + .color + ::placeholder { color: red; }
:checked + .color::after { content: 'red'; }
<input type="checkbox" id="color01">
<label class="color" for="color01">Color: </label>
<input placeholder="hello">

Accessing a CSS custom property (aka CSS variable) through JavaScript

How do you get and set CSS custom properties (those accessed with var(…) in the stylesheet) using JavaScript (plain or jQuery)?
Here is my unsuccessful try: clicking on the buttons changes the usual font-weight property, but not the custom --mycolor property:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<style>
body {
--mycolor: yellow;
background-color: var(--mycolor);
}
</style>
</head>
<body>
<p>Let's try to make this text bold and the background red.</p>
<button onclick="plain_js()">Plain JS</button>
<button onclick="jQuery_()">jQuery</button>
<script>
function plain_js() {
document.body.style['font-weight'] = 'bold';
document.body.style['--mycolor'] = 'red';
};
function jQuery_() {
$('body').css('font-weight', 'bold');
$('body').css('--mycolor', 'red');
}
</script>
</body>
</html>
You can use document.body.style.setProperty('--name', value);:
var bodyStyles = window.getComputedStyle(document.body);
var fooBar = bodyStyles.getPropertyValue('--foo-bar'); //get
document.body.style.setProperty('--foo-bar', newValue);//set
The native solution
The standard methods to get/set CSS3 variables are .setProperty() and .getPropertyValue().
If your Variables are Globals (declared in :root), you can use the following, for getting and setting their values.
// setter
document.documentElement.style.setProperty('--myVariable', 'blue');
// getter
document.documentElement.style.getPropertyValue('--myVariable');
However the getter will only return the value of a var, if has been set, using .setProperty().
If has been set through CSS declaration, will return undefined. Check it in this example:
let c = document.documentElement.style.getPropertyValue('--myVariable');
alert('The value of --myVariable is : ' + (c?c:'undefined'));
:root{ --myVariable : red; }
div{ background-color: var(--myVariable); }
<div>Red background set by --myVariable</div>
To avoid that unexpected behavior you have to make use of the getComputedStyle()method , before calling .getPropertyValue().
The getter will then, look like this:
getComputedStyle(document.documentElement,null).getPropertyValue('--myVariable');
In my opinion, accessing CSS variables should be more simple, fast, intuitive and natural...
My personal approach
I've implemented CSSGlobalVariablesa tiny (<3kb) javascript helper which automatically detects and packs into an Object all the active CSS global variables in a document, for easier access & manipulation.
// get the document CSS global vars
let cssVar = new CSSGlobalVariables();
// set a new value to --myVariable
cssVar.myVariable = 'red';
// get the value of --myVariable
console.log( cssVar.myVariable );
Any change applied to the Object properties, is translated automatically to the CSS variables.
Available in : https://github.com/colxi/css-global-variables
The following example illustrates how one may change the background using either JavaScript or jQuery, taking advantage of custom CSS properties known also as CSS variables (read more here). Bonus: the code also indicates how one may use a CSS variable to change the font color.
function plain_js() {
// need DOM to set --mycolor to a different color
d.body.style.setProperty('--mycolor', 'red');
// get the CSS variable ...
bodyStyles = window.getComputedStyle(document.body);
fontcolor = bodyStyles.getPropertyValue('--font-color'); //get
// ... reset body element to custom property's new value
d.body.style.color = fontcolor;
d.g("para").style["font-weight"] = "bold";
this.style.display="none";
};
function jQuery_() {
$("body").get(0).style.setProperty('--mycolor','#f3f');
$("body").css("color",fontcolor);
$("#para").css("fontWeight","bold");
$(this).css("display","none");
}
var bodyStyles = null;
var fontcolor = "";
var d = document;
d.g = d.getElementById;
d.g("red").addEventListener("click",plain_js);
d.g("pink").addEventListener("click",jQuery_);
:root {
--font-color:white;
--mycolor:yellow;
}
body {
background-color: var(--mycolor);
color:#090;
}
#para {
font: 90% Arial,Helvetica;
font-weight:normal;
}
#red {
background:red;
}
#pink {
background:#f3f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<p id="para">Let's try to make the background red or pink and change the text to white and bold.</p>
<button id="red">Red</button>
<button id="pink">Pink</button>
Note that with jQuery, in order to set the custom property to a differnt value, this response actually holds the answer. It uses the body element's get() method which allows access to the underlying DOM structure and returns the body element, thereby facilitating the code setting the custom property --mycolor to a new value.
You can use getComputedStyle function to get css variables,Here is a example.
const colors = document.querySelectorAll(".color");
const result = document.getElementById("result");
colors.forEach((color) => color.addEventListener("click", changeColor));
function changeColor(event) {
const target = event.target;
// get color
const color = getComputedStyle(target).getPropertyValue("--clr");
document.body.style.backgroundColor = color;
// active color
colors.forEach((color) => color.classList.remove("active"));
target.classList.add("active");
result.textContent = getComputedStyle(target).getPropertyValue("--clr")
}
result.textContent = "#1dd1a1";
body{
background-color: #1dd1a1;
}
.colors{
position: absolute;
padding: 2rem;
display: flex;
gap: 1rem;
}
.color{
display: inline-block;
width: 2rem;
height: 2rem;
background-color: var(--clr);
border-radius: 50%;
cursor: pointer;
transition: $time-unit;
}
.color.active{
border: .2rem solid #333;
transform: scale(1.25);
}
<h1>Click to change Background</h1>
<section class="colors">
<span class="color active" style="--clr: #1dd1a1"></span>
<span class="color" style="--clr: #ff6b6b"></span>
<span class="color" style="--clr: #2e86de"></span>
<span class="color" style="--clr: #f368e0"></span>
<span class="color" style="--clr: #ff9f43"></span>
</section>
Current Color: <span id="result"></span>

Integrating css into Jquery

My problem is simple but I'm new to jquery and css so I don't really know what I'm doing. I have a css file style.css and this is what's in it.
keyword {
font-size: 12px;
color: #0000FF;
}
stringWord {
font-size: 12px;
color: #ff6a00;
}
I'm trying to change text inside of a text area so here is where that is declared.
<div class="DivWithScroll" id="my_text" contenteditable="true"
onkeypress="return myKeyPress(event)" onkeydown="return onKeyDown(event)">
In my jquery code I want it to go to the css file of keyword and change the color of the text.
This is what I have so far but it's not working properly
for (var i = 0; i < reservedKeyWords.length; i++) {
if ( lastWordTyped == reservedKeyWords[i] ) {
console.log(lastWordTyped + "::" + reservedKeyWords[i]);
$('DivToScroll').css("keyword");
return;
}
}
`
Like I said I'm new to all of this so any help is greatly appreciated.
Instead of .css('keyword') use .addClass('keyword').
Also note that your jQuery selector is targeting 'DivToScroll' rather than 'DivWithScroll' and you may want to change the jQuery selector to be
$('#my_text')
to reference the div by ID.

Change CSS value by javascript for whole document

I want on ajax call change the values loaded from CSS file, it means not only for one element like:
document.getElementById("something").style.backgroundColor="<?php echo "red"; ?>";
but similar script which is change the css value generally, not only for element by ID, idealy like background color for CSS CLASS divforchangecolor:
CSS:
.divforchangecolor{
display: block;
margin: 20px 0px 0px 0px;
padding: 0px;
background-color: blue;
}
HTML:
<div class="divforchangecolor"><ul><li>something i want to style</li><ul></div>
<div class="divforchangecolor">not important</div>
<div class="divforchangecolor"><ul><li>something i want to style</li><ul></div>
<div class="divforchangecolor">not improtant</div>
Ideal solution for me:
onclick="--change CSS value divforchangecolor.backgroundColor=red--"
but i need to change CSS to reach .divforchangecolor ul li and .divforchangecolor ul li:hover
If you can't just apply the classname to these elements. You could add a new selector to your page. The following vanilla JS would be able to do that (jsFiddle).
function applyDynamicStyle(css) {
var styleTag = document.createElement('style');
var dynamicStyleCss = document.createTextNode(css);
styleTag.appendChild(dynamicStyleCss);
var header = document.getElementsByTagName('head')[0];
header.appendChild(styleTag);
};
applyDynamicStyle('.divforchangecolor { color: pink; }');
Just adapt the thought behind this and make it bullet proof.
var elements=document.getElementsByClassName("divforchangecolor");
for(var i=0;i<elements.length;i++){
elements[i].style.backgroundColor="red";
}
var e = document.getElementsByClassName('divforchangecolor');
for (var i = 0; i < e.length; i++) e[i].style.backgroundColor = 'red';
Use getElementByClassName() and iterate over the array returned to achieve this
You can select elements by class with document.getElementsByClassName or by css selector (includes class) with document.querySelectorAll().
Here are two approaches, for example: Live demo here (click).
Markup:
<div class="divforchangecolor"></div>
<div class="divforchangecolor"></div>
<div class="divforchangecolor"></div>
<div class="divforchangecolor"></div>
<div class="some-container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
JavaScript:
var toChange = document.getElementsByClassName('divforchangecolor');
for (var i=0; i<toChange.length; ++i) {
toChange[i].style.backgroundColor = 'green';
}
var toChange2 = document.querySelectorAll('.some-container > div');
for (var i=0; i<toChange.length; ++i) {
toChange2[i].style.backgroundColor = 'red';
}
I recommend the second solution if it is possible in your case, as the markup is much cleaner. You don't need to specifically wrap the elements in a parent - elements already have a parent (the body, for example).
Another option is to have the background color you want to change to in a css class, then you can change the class on your elements (and therefore the style changes), rather than changing the css directly. That is also good practice, as it lets you keep your styles all in css files, while js is just manipulating which one is used.
On the whole document your approach can be a bit different:
ajax call
call a function when done
conditionally set a class on the body like <body class='mycondition'></body>
CSS will take care of the rest .mycondition .someclass: color: red;
This approach will be more performant than using JavaScript to change CSS on a bunch of elements.
You can leverage CSS selectors for that:
.forchangecolor {
display: block;
margin: 20px 0px 0px 0px;
padding: 0px;
background-color: blue;
}
.red-divs .forchangecolor {
background-color: red;
}
Then, with javascript, add the red-divs class to a parent element (could be the <body>, for example), when one of the divs is clicked:
document.addEventListener("click", function(event) {
var target = event.target;
var isDiv = target.className.indexOf("forchangecolor") >= 0;
if(isDiv) {
document.body.classList.add("red-divs");
}
});
Working example: http://jsbin.com/oMIjASI/1/edit

Not wrapping the 'value' in the input box?

I have this simple code:
<input type="text" value="Some Extremely Really Long Word" />
How do I make sure the value (in this case 'Some Extremely Really Long Word') shows up completely (ie. is not clipped).
I tried to apply the style: overflow:visible and display:nowrap but it didn't work.
I don't want to apply a style like: width: 200px because I don't know how long the words will be.
Fiddle: http://jsfiddle.net/TfKbp/3/
I've used this in the past to dynamically expand the width of a text INPUT to the width of its contents. Basically, you create a SPAN with the exact same font family, font size, etc. and use the keypress event to add the characters, measure its size, and resize the INPUT.
EDIT 1
To dynamically size the text box for its initial value requires just a little more code...
HTML
<input id="txtLong" type="text" value="What does the fox say? Ring-ding-ding-ding-dingeringeding! Gering-ding-ding-ding-dingeringeding! Gering-ding-ding-ding-dingeringeding! What the fox say?" />
<span id="spanLong" style="display: none;"></span>
JavaScript
var txtLong = $("#txtLong");
var spanLong = $("#spanLong");
spanLong.text(txtLong.val());
txtLong.css("width", spanLong.width());
txtLong.keypress(function(e){
if (e.which !== 0 && e.charCode !== 0) {
var char = String.fromCharCode(e.keyCode | e.charCode);
spanLong.text(txtLong.val() + char);
txtLong.css("width", spanLong.width());
}
});
CSS
input, span {
padding: 2px 3px;
font-size: 11px;
font-family: Sans-serif;
white-space: pre;
}
New and Improved Fiddle
EDIT 2
Since you're looking for a way to select text by clicking on it, I thought I'd also point out that you don't necessarily need an INPUT to do that. Check out this JSFiddle. And as an added bonus, it doesn't use JQuery. I know you were kinda opposed to that.
EDIT 3
I found a way to simply resize a textbox to the width of its initial value using only plain JavaScript by adapting this blog post.
HTML
<input type="text" id="txtLong" value="Some very long text that all needs to show"/>
<span id="ruler"></span>
JavaScript
String.prototype.visualLength = function()
{
var ruler = document.getElementById("ruler");
ruler.innerHTML = this;
return ruler.offsetWidth;
}
window.onload = function() {
var txtLong = document.getElementById("txtLong");
var width = txtLong.value.visualLength();
txtLong.setAttribute("style", "width:" + width + "px");
}
CSS
#ruler {
visibility: hidden;
white-space: nowrap;
}
#txtLong, #ruler {
font-family: sans-serif;
font-size: 11pt;
}
JSFiddle
There is no declarative way (that I know of) to do this, but it is fairly easy to do using jQuery. What you essentially need to do is make a second element (not an input) that contains all the same styling as the input. Then measure the width of the second element, and set width of the input to that new width.
Here's how you'd do that:
HTML:
<input type='text' value='Some Extremely Really Long Word' id='my-input' />
jQuery:
$(document).ready(function() {\
var $input = $('#my-input'),
$clone = $('<div></div>');
$clone.html($input.val());
$clone.css({
whiteSpace: 'nowrap',
font: $input.css('font'),
paddingLeft: $input.css('padding-left'),
paddingRight: $input.css('padding-right')
});
$clone.appendTo($('body'));
$input.css({
width: $clone.width();
});
$clone.remove();
})

Categories