This question already has answers here:
css rotate a pseudo :after or :before content:"" [duplicate]
(2 answers)
Closed 4 years ago.
Please check this code
https://codepen.io/manuchadha/pen/PBKYBJ
I have created a form. I want to be able to upload an image using the file upload input. When an image is selected, I want to show a thumbnail of the image just below the file selector box and also show a close (x) sign on the top-right corner of the image which could be used to delete the image.
I am trying to follow this example (https://codepen.io/brissmyr/pen/egidw) to create an X using css (not fonts) but I am unable to create it. What am I doing wrong? All I see are two vertical bars at the top corner of the image box but they are not transforming by 45degrees. I suspect that it could be a css transform issue but I could be wrong
The code is
/*handler for file upload*/
function handleFileSelect() {
console.log("got file upload event:");
/*
FileList object is the object returned as a result of a user selecting files using the <input> element,
from a drag and drop operation's DataTransfer object, or from the mozGetAsFile() API on an HTMLCanvasElement.
*/
var files = document.getElementById('question-file-upload').files; //event.target.files;
console.log("files selected:" + files + ", total selected: " + files.length);
for (var i = 0; i < files.length; i++) {
console.log("files name:" + files[i].name)
console.log("files object:" + files[i])
}
//working with only 1 file at the moment
var file = files[0];
if (files && file) {
/*
The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer,
using File or Blob objects to specify the file or data to read.
*/
var reader = new FileReader();
/*bind onload event of FileReader to _handleReaderLoaded
onload is a handler for the load event. This event is triggered by FileReader each time the reading operation is successfully completed.
*/
reader.onload = this._handleReaderLoaded.bind(this);
reader.readAsBinaryString(file);
}
}
function _handleReaderLoaded(readerEvt) {
var binaryString = readerEvt.target.result;
var base64textString = btoa(binaryString);
console.log(btoa(binaryString));
var src = "data:image/png;base64,";
src += base64textString;
var newImage = document.createElement('img');
newImage.src = src;
newImage.width = newImage.height = "80";
var closeButtonLink = document.createElement('a');
/*closeButtonLink.textContent = "x";*/
/*dont want font*/
closeButtonLink.setAttribute('href', "#");
closeButtonLink.classList.add("close");
document.querySelector('#imageContainer').appendChild(newImage);
document.querySelector('#imageContainer').appendChild(closeButtonLink);
}
body {
margin: 0px;
}
.body__div--background {
background: linear-gradient(45deg, #33b1f8 37%, #6e90f6 100%);
/*syntax linear-gradient(direction, color1 limit, color2 limit)*/
color: #555555;
font-family: Helvetica;
line-height: 1.5;
font-size: 11px;
letter-spacing: 0.25px;
}
#submit-practice-question-button {
display: block;
}
#imageContainer {
display: inline-block;
border: 1px solid black;
}
.close {
position: relative;
margin: 0px;
padding: 0px
/*right: 80px;
top:80px;
width: 32px;
height: 32px;
*/
opacity: 0.3;
}
.close:hover {
opacity: 1;
}
.close:before,
.close:after {
/*position: relative;*/
/*left: 15px;*/
border: 1px solid black;
top: 0px;
right: 80px;
content: ' ';
/*height: 33px;*/
width: 2px;
background-color: #333;
}
.close:before {
transform: rotate(45deg);
}
.close:after {
transform: rotate(-45deg);
}
<!DOCTYPE html>
<html lang="en">
<head>
<base href="">
<title>Example</title>
<!--meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"-->
<link rel="stylesheet" media="screen" href="fiddle.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="fiddle.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js"></script>
</head>
<body>
<!--a href="#" class="close"></a-->
<div id="form-div" class="body__div--background">
<form id="new-question-form" class="practice-question-form" [formGroup]="practiceQuestionForm" (ngSubmit)="addPracticeQuestion()" novalidate>
<div class="form-group">
<label for="file-upload" class="control-label required">Upload files</label>
<div class="custom-file" id="file-upload" lang="es">
<input type="file" class="custom-file-input" id="question-file-upload" multiple onchange="handleFileSelect(this.files)">
<label style="width:50%" class="custom-file-label" for="question-file-upload"></label>
</div>
</div>
<div id="imageContainer"></div>
<button type="submit" id="submit-practice-question-button" class="content-div__button--blue"> Submit! </button>
</form>
</div>
</body>
Pseudo elements are inline by default, so you must apply display: block or display: inline-block to transform them, check below snippet
/*handler for file upload*/
function handleFileSelect() {
console.log("got file upload event:");
/*
FileList object is the object returned as a result of a user selecting files using the <input> element,
from a drag and drop operation's DataTransfer object, or from the mozGetAsFile() API on an HTMLCanvasElement.
*/
var files = document.getElementById('question-file-upload').files; //event.target.files;
console.log("files selected:" + files + ", total selected: " + files.length);
for (var i = 0; i < files.length; i++) {
console.log("files name:" + files[i].name)
console.log("files object:" + files[i])
}
//working with only 1 file at the moment
var file = files[0];
if (files && file) {
/*
The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer,
using File or Blob objects to specify the file or data to read.
*/
var reader = new FileReader();
/*bind onload event of FileReader to _handleReaderLoaded
onload is a handler for the load event. This event is triggered by FileReader each time the reading operation is successfully completed.
*/
reader.onload = this._handleReaderLoaded.bind(this);
reader.readAsBinaryString(file);
}
}
function _handleReaderLoaded(readerEvt) {
var binaryString = readerEvt.target.result;
var base64textString = btoa(binaryString);
console.log(btoa(binaryString));
var src = "data:image/png;base64,";
src += base64textString;
var newImage = document.createElement('img');
newImage.src = src;
newImage.width = newImage.height = "80";
var closeButtonLink = document.createElement('a');
/*closeButtonLink.textContent = "x";*/
/*dont want font*/
closeButtonLink.setAttribute('href', "#");
closeButtonLink.classList.add("close");
document.querySelector('#imageContainer').appendChild(newImage);
document.querySelector('#imageContainer').appendChild(closeButtonLink);
}
body {
margin: 0px;
}
.body__div--background {
background: linear-gradient(45deg, #33b1f8 37%, #6e90f6 100%);
/*syntax linear-gradient(direction, color1 limit, color2 limit)*/
color: #555555;
font-family: Helvetica;
line-height: 1.5;
font-size: 11px;
letter-spacing: 0.25px;
}
#submit-practice-question-button {
display: block;
}
#imageContainer {
display: inline-block;
border: 1px solid black;
}
.close {
position: relative;
margin: 0px;
padding: 0px
/*right: 80px;
top:80px;
width: 32px;
height: 32px;
*/
opacity: 0.3;
}
.close:hover {
opacity: 1;
}
.close:before,
.close:after {
/*position: relative;*/
/*left: 15px;*/
border: 1px solid black;
top: 0px;
right: 80px;
content: 'X';
/*height: 33px;*/
width: 2px;
display: inline-block;
background-color: #333;
}
.close:before {
transform: rotate(45deg);
}
.close:after {
transform: rotate(-45deg);
}
<!DOCTYPE html>
<html lang="en">
<head>
<base href="">
<title>Example</title>
<!--meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"-->
<link rel="stylesheet" media="screen" href="fiddle.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="fiddle.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js"></script>
</head>
<body>
<!--a href="#" class="close"></a-->
<div id="form-div" class="body__div--background">
<form id="new-question-form" class="practice-question-form" [formGroup]="practiceQuestionForm" (ngSubmit)="addPracticeQuestion()" novalidate>
<div class="form-group">
<label for="file-upload" class="control-label required">Upload files</label>
<div class="custom-file" id="file-upload" lang="es">
<input type="file" class="custom-file-input" id="question-file-upload" multiple onchange="handleFileSelect(this.files)">
<label style="width:50%" class="custom-file-label" for="question-file-upload"></label>
</div>
</div>
<div id="imageContainer"></div>
<button type="submit" id="submit-practice-question-button" class="content-div__button--blue"> Submit! </button>
</form>
</div>
</body>
Related
I have created some javascript div, a, img elements.
Making my website easier to read instead of spamming the same stuff over and over again.
My problem right now is -->
I need to use href and src links from my array ("src") and add them to my created imgages and links.
So far i have found only one working way to do it with Math...() but i don't want to show the images in random order i want them to be in the order that i have putted them in the array.
This is my code down below i will be happy if anyone helps me out!
I think this can be solved with forEach but i can't figure it out...
var src = ["https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1176&q=80" ,
"https://images.unsplash.com/photo-1458966480358-a0ac42de0a7a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80"];
(function () {
function createDiv() {
var boardDiv = document.createElement("div");
var link = document.createElement("a");
var img = document.createElement("img");
boardDiv.className = "col-md-6 col-lg-4 item";
boardDiv.appendChild(link);
link.className = "lightbox"
link.appendChild(img);
link.href = src[0];
img.className ="img-fluid image scale-on-hover"
img.src = src[Math.floor(Math.random() * src.length)];
return boardDiv;
}
function createAndModifyDivs() {
var board = document.getElementById("image-builder"),
myDivs = [],
i = 0,
numOfDivs = src.length;
for (i; i < numOfDivs; i += 1) {
myDivs.push(createDiv());
board.appendChild(myDivs[i]);
}
}
createAndModifyDivs();
}());
.gallery-block.grid-gallery{
padding-bottom: 60px;
padding-top: 60px;
}
.gallery-block.grid-gallery .heading{
margin-bottom: 50px;
text-align: center;
}
.gallery-block.grid-gallery .heading h2{
font-weight: bold;
font-size: 1.4rem;
text-transform: uppercase;
}
.gallery-block.grid-gallery a:hover{
opacity: 0.8;
}
.gallery-block.grid-gallery .item img{
box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.15);
transition: 0.4s;
}
.gallery-block.grid-gallery .item{
margin-bottom: 20px;
}
#media (min-width: 576px) {
.gallery-block.grid-gallery .scale-on-hover:hover{
transform: scale(1.05);
box-shadow: 0px 10px 10px rgba(0, 0, 0, 0.15) !important;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Grid Gallery</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.css" />
</head>
<body>
<section class="gallery-block grid-gallery">
<div class="container">
<div class="heading">
<h3>Alexis</h3>
</div>
<div class="row" id="image-builder">
</div>
</div>
</section>
<div id="board">
</div>
</div>
<script src="app.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.js"></script>
<script>
baguetteBox.run('.grid-gallery', { animation: 'slideIn' });
</script>
</body>
</html>
You can change your createDiv() function to take in the img src as a parameter and then set it in your for loop. Your code could be cleaned up a bit and I can help with that if you leave a comment but for now I just wanted to answer your initial question.
var src = ["https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1176&q=80" ,
"https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1176&q=80"];
(function () {
// Take the image link as a parameter called imgSrc
function createDiv(imgSrc) {
var boardDiv = document.createElement("div");
var link = document.createElement("a");
var img = document.createElement("img");
boardDiv.className = "col-md-6 col-lg-4 item";
boardDiv.appendChild(link);
link.className = "lightbox"
img.className ="img-fluid image scale-on-hover"
link.appendChild(img);
// Assuming here you want to link to the image
link.href = imgSrc;
// Set the img src
img.src = imgSrc;
return boardDiv;
}
function createAndModifyDivs(elmId) {
const board = document.getElementById(elmId);
for (const imgSrc of src) {
board.appendChild(createDiv(imgSrc));
}
}
const galleries = ['image-builder', 'image-builder-2'];
for(const gallery of galleries) {
createAndModifyDivs(gallery);
baguetteBox.run(`#${gallery}`);
}
}());
.gallery-block.grid-gallery{
padding-bottom: 60px;
padding-top: 60px;
}
.gallery-block.grid-gallery .heading{
margin-bottom: 50px;
text-align: center;
}
.gallery-block.grid-gallery .heading h2{
font-weight: bold;
font-size: 1.4rem;
text-transform: uppercase;
}
.gallery-block.grid-gallery a:hover{
opacity: 0.8;
}
.gallery-block.grid-gallery .item img{
box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.15);
transition: 0.4s;
}
.gallery-block.grid-gallery .item{
margin-bottom: 20px;
}
#media (min-width: 576px) {
.gallery-block.grid-gallery .scale-on-hover:hover{
transform: scale(1.05);
box-shadow: 0px 10px 10px rgba(0, 0, 0, 0.15) !important;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Grid Gallery</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.css" />
</head>
<body>
<section class="gallery-block grid-gallery">
<div class="container">
<div class="heading">
<h3>Alexis</h3>
</div>
<div class="gallery" id="image-builder">
</div>
</div>
</section>
<section class="gallery-block grid-gallery">
<div class="container">
<div class="heading">
<h3>Other</h3>
</div>
<div class="gallery" id="image-builder-2">
</div>
</div>
</section>
<div id="board">
</div>
</div>
<script src="app.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.js"></script>
<script>
</script>
</body>
</html>
You only have to make these two changes, now you will pass the src as a parameter of createDiv() (look for the comments)
In App.js
var src = [
"https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1176&q=80",
"https://images.unsplash.com/photo-1458966480358-a0ac42de0a7a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80",
];
(function () {
//ADD A PARAMETER TO THE FUNCTION HERE
function createDiv(img_src) {
var boardDiv = document.createElement("div");
var link = document.createElement("a");
var img = document.createElement("img");
boardDiv.className = "col-md-6 col-lg-4 item";
boardDiv.appendChild(link);
link.className = "lightbox";
link.appendChild(img);
link.href = src[0];
img.className = "img-fluid image scale-on-hover";
img.src = img_src;
return boardDiv;
}
function createAndModifyDivs() {
var board = document.getElementById("image-builder"),
myDivs = [],
i = 0,
numOfDivs = src.length;
for (i; i < numOfDivs; i += 1) {
//PASS THE SRC OF THE DIRECT IMAGE AS PARAMETER HERE
myDivs.push(createDiv(src[i]));
board.appendChild(myDivs[i]);
}
}
createAndModifyDivs();
})();
I am developing a chat application on React JS, and I want an image to be uploaded if I copy paste an image on the chatbox. How do I trigger this?
What I need basically is:
An event that will be triggered when action "Paste" is performed.
A way to upload image into a file type input element from the clipboard.
You need to add an event listener on paste event, and get the items from the clipboard and check if its type is an image.
<html lang="en">
<head>
<meta charset="utf-8" />
<title>HTML DOM - Paste an image from the clipboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/css/demo.css" />
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inter&family=Source+Code+Pro&display=swap"
/>
<style>
.container {
/* Center the content */
align-items: center;
display: flex;
justify-content: center;
/* Misc */
height: 32rem;
padding: 1rem 0;
}
.key {
background-color: #f7fafc;
border: 1px solid #cbd5e0;
border-radius: 0.25rem;
padding: 0.25rem;
}
.preview {
align-items: center;
border: 1px solid #cbd5e0;
display: flex;
justify-content: center;
margin-top: 1rem;
max-height: 16rem;
max-width: 42rem;
}
</style>
</head>
<body>
<div class="container">
<div>
<div><kbd class="key">Ctrl</kbd> + <kbd class="key">V</kbd> in this window.</div>
<img class="preview" id="preview" />
<input id="file_input" type="file" />
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('paste', function (evt) {
const clipboardItems = evt.clipboardData.items;
const items = [].slice.call(clipboardItems).filter(function (item) {
// Filter the image items only
return /^image\//.test(item.type);
});
if (items.length === 0) {
return;
}
const item = items[0];
const blob = item.getAsFile();
const imageEle = document.getElementById('preview');
imageEle.src = URL.createObjectURL(blob);
let file = new File([blob], "file name",{type:"image/jpeg", lastModified:new Date().getTime()}, 'utf-8');
let container = new DataTransfer();
container.items.add(file);
document.querySelector('#file_input').files = container.files;
});
});
</script>
</body>
</html>
Resources
Pase an image from the clipboard
Set file value from blob
I am trying to get an input type-file, append it to unordered list and make it show up in browser
But it's not showing up and browser not showing any errors
Please help. I am trying to solve this problem already 3 days. I recently started coding, please don't make fun of me
This is my own project in order to learn better JavaScript
My html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>javascripttutorial</title>
<style>
.name-div {
color: aliceblue;
}
.photo-div {
color: aliceblue;
}
.date-div {
color: aliceblue;
}
.box-1 {
border: 1px solid black;
padding: 10px;
display: flex;
flex-direction: column;
height: 500px;
width: 100px;
float: left;
}
.box-2 {
border: 1px solid black;
padding: 10px;
display: flex;
flex-direction: column;
height: 500px;
width: 200px;
float: left;
}
.box-3 {
border: 1px solid black;
padding: 10px;
display: flex;
flex-direction: column;
height: 500px;
width: 150px;
float: left;
}
body {
margin-left: 20px;
margin-right: 20px;
}</style> <script src="script.js"></script></head><body>
<div style="margin: 10px;" class="name-div">
<input id="input-name" type="text" placeholder="Your name">
</div>
<div style="margin: 10px;" class="photo-div">
<input id="input-photo" type="file" onchange="previewFile()"><br>
<img src="" height="100" alt="Image preview...">
</div>
<div style="margin: 10px;" class="date-div">
<input id="input-date" type="date" placeholder="Your birthday">
</div>
<div style="margin: 10px;" class="button-div">
<button id="button">Submit</button>
</div>
<span class="box-1">
<ul id="messages-1">Name: </ul>
</span>
<span class="box-2">
<ul id="messages-2">Photo: </ul>
</span>
<span class="box-3">
<ul id="messages-3">Date: </ul>
</span>
<script async src="script.js"></script></body></html>>
My script
window.onload=function(){
var inputName = document.getElementById('input-name');
var inputPhoto = document.getElementById('input-photo');
var inputDate = document.getElementById('input-date');
var button = document.getElementById('button');
var messages1 = document.getElementById('messages-1');
var messages2 = document.getElementById('messages-2');
var messages3 = document.getElementById('messages-3');
button.addEventListener("click", function(){
var newMessage1 = document.createElement("li");
var newMessage2 = document.createElement("li");
var photo = document.createElement("img");
var newMessage3 = document.createElement("li");
newMessage1.innerHTML = inputName.value;
photo.setAttribute("style", "height: 30px; widht: 30px;");
var reader1 = new FileReader();
reader1.addEventListener("onloadend", function(){
reader1.readAsDataURL(inputPhoto);
photo.src = reader1.result;
});
newMessage3.innerHTML = inputDate.value;
messages1.appendChild(newMessage1);
messages2.appendChild(newMessage2)
messages3.appendChild(newMessage3);
newMessage2.appendChild(photo);
inputName.value = "";
inputDate.value = "";
});
}
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
Steps to Follow
Listen to the change event fire by the image file upload input on an image upload.
Grab the file from the parameter that receives to the event listener callback.
Then pass it to the FileReader.
That's it in here.
inputPhoto.addEventListener("change", (e) => {
var file = e.target.files[0];
fileReader.readAsDataURL(file);
});
Now listen to the load event fire by the FileReader.
Get the base64 from the parameter.
Create an image element to preview the uploaded image.
Then set the base64 to that image src attribute.
fileReader.addEventListener("load", (e) => {
var imgUploadWrap = document.getElementsByClassName("photo-div")[0];
var img = document.createElement("img");
var base64 = e.target.result;
img.setAttribute("id", "uploaded-img");
img.height = 100;
img.src = base64;
imgUploadWrap.append(img);
});
Notes:
I create a new image element on upload because it will be easier to reset it.
If you listen to the load event, not loadend, then you don't have to handle the file empty scenario because the load event is fired only if the upload is successful.
Finally when clicking the submit button, set the preview image element's src attribute to the image element inside the message.
if (uploadedImg) {
photo.height = 60;
photo.src = uploadedImg.src;
uploadedImg.remove();
}
Full Code - https://codesandbox.io/s/input-type-file-not-showing-up-even-with-filereader-71891729-u5bvft?file=/script.js
Is it possible to alter a CSS stylesheet using JavaScript?
I am NOT talking about:
document.getElementById('id').style._____='.....';
I AM talking about altering:
#id {
param: value;
}
besides doing something dirty (which we haven’t tried yet btw), like creating a new object in the head, innerHTML a style tag in there, etc. Although this, even if it did work, would pose a few issues as the style block is already defined elsewhere, and I’m not sure when/if the browser would even parse a dynamically created style block?
Yes you can; every browser supports this, including IE9+).
The insertRule() method allows dynamic addition of rules to a stylesheet.
With deleteRule(), you can remove existing rules from a stylesheet.
Rules within a stylesheet can be accessed via the cssRules attributes of a stylesheet.
We can use a combination of .insertRule and .cssRules to be able to do this all the way back to IE9:
function changeStylesheetRule(stylesheet, selector, property, value) {
// Make the strings lowercase
selector = selector.toLowerCase();
property = property.toLowerCase();
value = value.toLowerCase();
// Change it if it exists
for(var i = 0; i < stylesheet.cssRules.length; i++) {
var rule = stylesheet.cssRules[i];
if(rule.selectorText === selector) {
rule.style[property] = value;
return;
}
}
// Add it if it does not
stylesheet.insertRule(selector + " { " + property + ": " + value + "; }", 0);
}
// Used like so:
changeStylesheetRule(s, "body", "color", "rebeccapurple");
Demo
2020
Some advantages of this method:
Does not require (but allows) stylesheet to be specified.
Allows multiple styles to be added / modified at once
Accepts !important attribute
Ignores extra whitespace when matching CSS selector
Changes last matching existing rule, or appends to end of last matching stylesheet. (Other answers add/change the first rule which may be then overruled.)
Usage:
adjustCSSRules('#myDiv', 'width: 300px !important');
Method:
function adjustCSSRules(selector, props, sheets){
// get stylesheet(s)
if (!sheets) sheets = [...document.styleSheets];
else if (sheets.sup){ // sheets is a string
let absoluteURL = new URL(sheets, document.baseURI).href;
sheets = [...document.styleSheets].filter(i => i.href == absoluteURL);
}
else sheets = [sheets]; // sheets is a stylesheet
// CSS (& HTML) reduce spaces in selector to one.
selector = selector.replace(/\s+/g, ' ');
const findRule = s => [...s.cssRules].reverse().find(i => i.selectorText == selector)
let rule = sheets.map(findRule).filter(i=>i).pop()
const propsArr = props.sup
? props.split(/\s*;\s*/).map(i => i.split(/\s*:\s*/)) // from string
: Object.entries(props); // from Object
if (rule) for (let [prop, val] of propsArr){
// rule.style[prop] = val; is against the spec, and does not support !important.
rule.style.setProperty(prop, ...val.split(/ *!(?=important)/));
}
else {
sheet = sheets.pop();
if (!props.sup) props = propsArr.reduce((str, [k, v]) => `${str}; ${k}: ${v}`, '');
sheet.insertRule(`${selector} { ${props} }`, sheet.cssRules.length);
}
}
Demo
The method takes three arguments:
selector [String] - CSS selector - eg: '#myDiv'
Whitespaces are auto-reduced (.myClass #myDiv will match .myClass #myDiv)
rules [CSS String, Object] - eg (either is acceptable):
{ border: "solid 3px green", color: "white" }
'border: solid 3px green; color: white'
sheet (Optional) [String, StyleSheet]
if empty, all stylesheets will be checked
'myStyles.css' A relative or absolute URL to sheet
document.styleSheets[1] - A reference to a sheet
Other examples:
adjustCSSRules('#myDiv', {width: '30px'}); // all stylesheets
adjustCSSRules('#myDiv', 'width: 30px', 'style.css'); // style.css only
adjustCSSRules('#myDiv .myClass', 'width: 30px', document.styleSheets[0]); // only first stylesheet
When I want to programmatically add a bunch of styles to an object, I find it easier to programmatically add a class to the object (such class has styles asscociated with it in your CSS). You can control the precedence order in your CSS so the new styles from the new class can override things you had previously. This is generally much easier than modifying a stylesheet directly and works perfectly cross-browser.
change a property in a style rule
function change_css_style (titulo,selector,propiedad,valor) {
let i=0;
while (i<document.styleSheets.length) {
if (document.styleSheets[i].title==titulo) {
let y=0;
while (y<document.styleSheets[i].cssRules.length) {
if (document.styleSheets[i].cssRules[y].selectorText==selector) {
document.styleSheets[i].cssRules[y].style[propiedad] = valor;
y = document.styleSheets[i].cssRules.length;
}
y++;
}
i=document.styleSheets.length;
}
i++;
}
}
DEMO
<style title="chat_inicio">
.contenido .mensajes {
width: 100px;
height: 300px;
}
</style>
change the style book with the title chat_inicio with the selector .contenido .mensajes the property of the style width to 475px
<script>
cambiar_css_style ('chat_inicio','.contenido .mensajes','width','475px');
</script>
.style.cssText property works, try the code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0%;
padding: 0%;
}
html {
--theme-orange: orangered;
--theme-blue: rgb(67, 67, 197);
--theme-green: darkgreen;
--theme-black: black;
--theme-color: var(--theme-orange);
}
body {
font-family: 'Roboto', sans-serif;
background-color: rgb(251, 251, 251);
}
.nav-bar ul {
display: flex;
width: 100%;
background-color: var(--theme-color);
flex-wrap: wrap;
flex-direction: row;
align-items: center;
width: 100%;
}
.nav-bar ul a {
text-decoration: none;
margin: 15px 10px;
}
.nav-bar .theme {
background-color: white;
display: flex;
height: fit-content;
margin-left: auto;
margin-right: 20px;
border-radius: 10px;
}
.nav-bar .theme .box {
width: 20px;
height: 20px;
border: 1px solid black;
cursor: pointer;
}
.nav-bar .theme .orange {
background-color: var(--theme-orange);
}
.nav-bar .theme .blue {
background-color: var(--theme-blue);
}
.nav-bar .theme .green {
background-color: var(--theme-green);
}
.nav-bar .theme .black {
background-color: var(--theme-black);
}
.nav-bar ul li {
color: white;
font-weight: 500;
list-style: none;
padding: 10px 30px;
background-color: var(--theme-color);
transition: 0.2s;
}
.nav-bar ul li:hover {
box-shadow: inset 10px 10px 10px -12px;
scale: 0.95;
}
</style>
<body>
<div class="nav-bar">
<ul>
<li>Home</li>
<li>Page 1</li>
<li>Page 2</li>
<li>About Us</li>
<li>Contact Us</li>
<div class="theme">
<a><div class="box orange" id="orange"></div></a>
<a><div class="box blue" id="blue"></div></a>
<a><div class="box green" id="green"></div></a>
<a><div class="box black" id="black"></div></a>
</div>
</ul>
</div>
<script>
function colorChange(color) {
const htmlTag = document.getElementsByTagName("*")[0];
htmlTag.style.cssText = `--theme-orange: orangered;
--theme-blue: rgb(67, 67, 197);
--theme-green: darkgreen;
--theme-black: black;
--theme-color: var(--theme-${color});`;
}
function addEventListenerForBox() {
allBox = document.querySelectorAll('.box');
allBox.forEach(box => {
box.addEventListener('click', (event) => {
colorChange(event.target.id);
});
});
}
document.addEventListener('DOMContentLoaded', addEventListenerForBox);
</script>
</body>
</html>
Result:
One solution is:
Content CSS file:
#casesDndDropdown {
background: #FFFFFF;
border: 4px
}
You can override the #casesDndDropdown or any CSS class by defining it in the <style> tag inside body,
jQuery
$('<style>#id{background: #428bca;border: 0px}</style>').appendTo('body');
2023/2
A few years ago I read in w3schools: HTML style Tag that the <style> element supports the HTML Global Attributes and HTML Event Attributes.
The above means that, next to href, rel and target, any stylesheet can be disabled by toggling its disabled attribute. I had to dig deep to verify when and how this spec was implemented and found an old (November 2000) W3C document already mentioning support for the disabled attribute of a stylesheet.
tl;dr
putting disabled directly in the style definition like <style disabled> does not work.
toggling the disabled attribute false/true with Javascript disables/enables the entire referenced <style>...</style> block, wherever this block resides in your document.
Planning the position of style blocks in your document now becomes a matter of concern, as the regular browser logic is 'last in, first serve'.
All you need is a reference to a stylesheet element and a few Javascript oneliners:
function disabledToggle(e) { e.disabled = !e.disabled }
function disabledOff (e) { e.disabled = false }
function disabledOn (e) { e.disabled = true }
FYI
Check out the media attribute specification in the above W3C document.
The <link> element also supports the mentioned HTML Global Attributes and HTML Event Attributes.
Essentially, it has always been possible to kill a stylesheet with a single hipshot.
A simple proof of concept:
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Alternate font, activated in default <style>, but can be toggled on/off -->
<link id="lnk-poppins" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
<!-- Default styling, considered 'always active' -->
<style>
* { box-sizing: border-box }
body { font-family: Poppins, sans-serif }
.square {
margin: 5rem auto;
width : 50vmin; aspect-ratio: 1;
background-color: CornflowerBlue;
}
</style>
<!-- Media controlled style, only active on small devices -->
<style media="all and (max-width: 640px)">
body {
margin: 0; padding: 1rem;
width: 100%; min-height: 100vh;
background-color: hsl(90,100%,50%,.3);
}
</style>
<!-- Alternative styles: last in, first serve, so order matters -->
<style id="stl-red" >.square { background-color: Red }</style>
<style id="stl-green">.square { background-color: Green }</style>
<style id="stl-blue" >.square { background-color: Blue }</style>
<!-- Default style, but can be toggled: overrides all above when enabled -->
<style id="stl-default" >.square { background-color: Black }</style>
</head>
<body>
<fieldset>
<legend> Style Toggles </legend>
<p>Colors:</p>
<label for="default">
<input id="default" class="radio" type="radio" name="group" checked
oninput="disabledOff(defa);">
Default
</label>
<label for="red">
<input id="red" class="radio" type="radio" name="group"
oninput="disabledOff(red);disabledOn(defa);disabledOn(blue);disabledOn(green);">
Red
</label>
<label for="green">
<input id="green" class="radio" type="radio" name="group"
oninput="disabledOff(green);disabledOn(defa);disabledOn(blue);">
Green
</label>
<label for="blue">
<input id="blue" class="radio" type="radio" name="group"
oninput="disabledOff(blue);disabledOn(defa);">
Blue
</label>
<p>Font:</p>
<label for="poppins">
<input id="poppins" type="checkbox" oninput="disabledToggle(popp);" checked>
Poppins
</label>
<br><br>
<span>Old W3C Reference: <a target="_blank" href="https://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet-disabled">Attributes: <b>disabled</b> of type boolean</a></span>
</fieldset>
<div class="square"></div>
<script>
const red = document.getElementById('stl-red');
const green = document.getElementById('stl-green');
const blue = document.getElementById('stl-blue');
const defa = document.getElementById('stl-default');
const popp = document.getElementById('lnk-poppins');
function disabledToggle(e) { e.disabled = !e.disabled }
function disabledOff (e) { e.disabled = false }
function disabledOn (e) { e.disabled = true }
</script>
</body>
</html>
Is it possible to alter a CSS stylesheet using JavaScript?
I am NOT talking about:
document.getElementById('id').style._____='.....';
I AM talking about altering:
#id {
param: value;
}
besides doing something dirty (which we haven’t tried yet btw), like creating a new object in the head, innerHTML a style tag in there, etc. Although this, even if it did work, would pose a few issues as the style block is already defined elsewhere, and I’m not sure when/if the browser would even parse a dynamically created style block?
Yes you can; every browser supports this, including IE9+).
The insertRule() method allows dynamic addition of rules to a stylesheet.
With deleteRule(), you can remove existing rules from a stylesheet.
Rules within a stylesheet can be accessed via the cssRules attributes of a stylesheet.
We can use a combination of .insertRule and .cssRules to be able to do this all the way back to IE9:
function changeStylesheetRule(stylesheet, selector, property, value) {
// Make the strings lowercase
selector = selector.toLowerCase();
property = property.toLowerCase();
value = value.toLowerCase();
// Change it if it exists
for(var i = 0; i < stylesheet.cssRules.length; i++) {
var rule = stylesheet.cssRules[i];
if(rule.selectorText === selector) {
rule.style[property] = value;
return;
}
}
// Add it if it does not
stylesheet.insertRule(selector + " { " + property + ": " + value + "; }", 0);
}
// Used like so:
changeStylesheetRule(s, "body", "color", "rebeccapurple");
Demo
2020
Some advantages of this method:
Does not require (but allows) stylesheet to be specified.
Allows multiple styles to be added / modified at once
Accepts !important attribute
Ignores extra whitespace when matching CSS selector
Changes last matching existing rule, or appends to end of last matching stylesheet. (Other answers add/change the first rule which may be then overruled.)
Usage:
adjustCSSRules('#myDiv', 'width: 300px !important');
Method:
function adjustCSSRules(selector, props, sheets){
// get stylesheet(s)
if (!sheets) sheets = [...document.styleSheets];
else if (sheets.sup){ // sheets is a string
let absoluteURL = new URL(sheets, document.baseURI).href;
sheets = [...document.styleSheets].filter(i => i.href == absoluteURL);
}
else sheets = [sheets]; // sheets is a stylesheet
// CSS (& HTML) reduce spaces in selector to one.
selector = selector.replace(/\s+/g, ' ');
const findRule = s => [...s.cssRules].reverse().find(i => i.selectorText == selector)
let rule = sheets.map(findRule).filter(i=>i).pop()
const propsArr = props.sup
? props.split(/\s*;\s*/).map(i => i.split(/\s*:\s*/)) // from string
: Object.entries(props); // from Object
if (rule) for (let [prop, val] of propsArr){
// rule.style[prop] = val; is against the spec, and does not support !important.
rule.style.setProperty(prop, ...val.split(/ *!(?=important)/));
}
else {
sheet = sheets.pop();
if (!props.sup) props = propsArr.reduce((str, [k, v]) => `${str}; ${k}: ${v}`, '');
sheet.insertRule(`${selector} { ${props} }`, sheet.cssRules.length);
}
}
Demo
The method takes three arguments:
selector [String] - CSS selector - eg: '#myDiv'
Whitespaces are auto-reduced (.myClass #myDiv will match .myClass #myDiv)
rules [CSS String, Object] - eg (either is acceptable):
{ border: "solid 3px green", color: "white" }
'border: solid 3px green; color: white'
sheet (Optional) [String, StyleSheet]
if empty, all stylesheets will be checked
'myStyles.css' A relative or absolute URL to sheet
document.styleSheets[1] - A reference to a sheet
Other examples:
adjustCSSRules('#myDiv', {width: '30px'}); // all stylesheets
adjustCSSRules('#myDiv', 'width: 30px', 'style.css'); // style.css only
adjustCSSRules('#myDiv .myClass', 'width: 30px', document.styleSheets[0]); // only first stylesheet
When I want to programmatically add a bunch of styles to an object, I find it easier to programmatically add a class to the object (such class has styles asscociated with it in your CSS). You can control the precedence order in your CSS so the new styles from the new class can override things you had previously. This is generally much easier than modifying a stylesheet directly and works perfectly cross-browser.
change a property in a style rule
function change_css_style (titulo,selector,propiedad,valor) {
let i=0;
while (i<document.styleSheets.length) {
if (document.styleSheets[i].title==titulo) {
let y=0;
while (y<document.styleSheets[i].cssRules.length) {
if (document.styleSheets[i].cssRules[y].selectorText==selector) {
document.styleSheets[i].cssRules[y].style[propiedad] = valor;
y = document.styleSheets[i].cssRules.length;
}
y++;
}
i=document.styleSheets.length;
}
i++;
}
}
DEMO
<style title="chat_inicio">
.contenido .mensajes {
width: 100px;
height: 300px;
}
</style>
change the style book with the title chat_inicio with the selector .contenido .mensajes the property of the style width to 475px
<script>
cambiar_css_style ('chat_inicio','.contenido .mensajes','width','475px');
</script>
.style.cssText property works, try the code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0%;
padding: 0%;
}
html {
--theme-orange: orangered;
--theme-blue: rgb(67, 67, 197);
--theme-green: darkgreen;
--theme-black: black;
--theme-color: var(--theme-orange);
}
body {
font-family: 'Roboto', sans-serif;
background-color: rgb(251, 251, 251);
}
.nav-bar ul {
display: flex;
width: 100%;
background-color: var(--theme-color);
flex-wrap: wrap;
flex-direction: row;
align-items: center;
width: 100%;
}
.nav-bar ul a {
text-decoration: none;
margin: 15px 10px;
}
.nav-bar .theme {
background-color: white;
display: flex;
height: fit-content;
margin-left: auto;
margin-right: 20px;
border-radius: 10px;
}
.nav-bar .theme .box {
width: 20px;
height: 20px;
border: 1px solid black;
cursor: pointer;
}
.nav-bar .theme .orange {
background-color: var(--theme-orange);
}
.nav-bar .theme .blue {
background-color: var(--theme-blue);
}
.nav-bar .theme .green {
background-color: var(--theme-green);
}
.nav-bar .theme .black {
background-color: var(--theme-black);
}
.nav-bar ul li {
color: white;
font-weight: 500;
list-style: none;
padding: 10px 30px;
background-color: var(--theme-color);
transition: 0.2s;
}
.nav-bar ul li:hover {
box-shadow: inset 10px 10px 10px -12px;
scale: 0.95;
}
</style>
<body>
<div class="nav-bar">
<ul>
<li>Home</li>
<li>Page 1</li>
<li>Page 2</li>
<li>About Us</li>
<li>Contact Us</li>
<div class="theme">
<a><div class="box orange" id="orange"></div></a>
<a><div class="box blue" id="blue"></div></a>
<a><div class="box green" id="green"></div></a>
<a><div class="box black" id="black"></div></a>
</div>
</ul>
</div>
<script>
function colorChange(color) {
const htmlTag = document.getElementsByTagName("*")[0];
htmlTag.style.cssText = `--theme-orange: orangered;
--theme-blue: rgb(67, 67, 197);
--theme-green: darkgreen;
--theme-black: black;
--theme-color: var(--theme-${color});`;
}
function addEventListenerForBox() {
allBox = document.querySelectorAll('.box');
allBox.forEach(box => {
box.addEventListener('click', (event) => {
colorChange(event.target.id);
});
});
}
document.addEventListener('DOMContentLoaded', addEventListenerForBox);
</script>
</body>
</html>
Result:
One solution is:
Content CSS file:
#casesDndDropdown {
background: #FFFFFF;
border: 4px
}
You can override the #casesDndDropdown or any CSS class by defining it in the <style> tag inside body,
jQuery
$('<style>#id{background: #428bca;border: 0px}</style>').appendTo('body');
2023/2
A few years ago I read in w3schools: HTML style Tag that the <style> element supports the HTML Global Attributes and HTML Event Attributes.
The above means that, next to href, rel and target, any stylesheet can be disabled by toggling its disabled attribute. I had to dig deep to verify when and how this spec was implemented and found an old (November 2000) W3C document already mentioning support for the disabled attribute of a stylesheet.
tl;dr
putting disabled directly in the style definition like <style disabled> does not work.
toggling the disabled attribute false/true with Javascript disables/enables the entire referenced <style>...</style> block, wherever this block resides in your document.
Planning the position of style blocks in your document now becomes a matter of concern, as the regular browser logic is 'last in, first serve'.
All you need is a reference to a stylesheet element and a few Javascript oneliners:
function disabledToggle(e) { e.disabled = !e.disabled }
function disabledOff (e) { e.disabled = false }
function disabledOn (e) { e.disabled = true }
FYI
Check out the media attribute specification in the above W3C document.
The <link> element also supports the mentioned HTML Global Attributes and HTML Event Attributes.
Essentially, it has always been possible to kill a stylesheet with a single hipshot.
A simple proof of concept:
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Alternate font, activated in default <style>, but can be toggled on/off -->
<link id="lnk-poppins" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
<!-- Default styling, considered 'always active' -->
<style>
* { box-sizing: border-box }
body { font-family: Poppins, sans-serif }
.square {
margin: 5rem auto;
width : 50vmin; aspect-ratio: 1;
background-color: CornflowerBlue;
}
</style>
<!-- Media controlled style, only active on small devices -->
<style media="all and (max-width: 640px)">
body {
margin: 0; padding: 1rem;
width: 100%; min-height: 100vh;
background-color: hsl(90,100%,50%,.3);
}
</style>
<!-- Alternative styles: last in, first serve, so order matters -->
<style id="stl-red" >.square { background-color: Red }</style>
<style id="stl-green">.square { background-color: Green }</style>
<style id="stl-blue" >.square { background-color: Blue }</style>
<!-- Default style, but can be toggled: overrides all above when enabled -->
<style id="stl-default" >.square { background-color: Black }</style>
</head>
<body>
<fieldset>
<legend> Style Toggles </legend>
<p>Colors:</p>
<label for="default">
<input id="default" class="radio" type="radio" name="group" checked
oninput="disabledOff(defa);">
Default
</label>
<label for="red">
<input id="red" class="radio" type="radio" name="group"
oninput="disabledOff(red);disabledOn(defa);disabledOn(blue);disabledOn(green);">
Red
</label>
<label for="green">
<input id="green" class="radio" type="radio" name="group"
oninput="disabledOff(green);disabledOn(defa);disabledOn(blue);">
Green
</label>
<label for="blue">
<input id="blue" class="radio" type="radio" name="group"
oninput="disabledOff(blue);disabledOn(defa);">
Blue
</label>
<p>Font:</p>
<label for="poppins">
<input id="poppins" type="checkbox" oninput="disabledToggle(popp);" checked>
Poppins
</label>
<br><br>
<span>Old W3C Reference: <a target="_blank" href="https://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet-disabled">Attributes: <b>disabled</b> of type boolean</a></span>
</fieldset>
<div class="square"></div>
<script>
const red = document.getElementById('stl-red');
const green = document.getElementById('stl-green');
const blue = document.getElementById('stl-blue');
const defa = document.getElementById('stl-default');
const popp = document.getElementById('lnk-poppins');
function disabledToggle(e) { e.disabled = !e.disabled }
function disabledOff (e) { e.disabled = false }
function disabledOn (e) { e.disabled = true }
</script>
</body>
</html>