Related
I wanted to change color according to user preference dynamically like when a user selects a color then it is applied synchronously to the element .
Like when an element is clicked color picker opens and then it works like developer tools color-picker , when a color is chosen from the picker it is applied to element and if user wants to change the color again in same picker than that also applied
Tried to went through following questions but couldn't find answer :
Change background colors dynamically using input event
how to dynamically select a color from a color picker by using jQuery?
HTML Input Color Picker, Apply Changes In Sync With Color Picker Selection
I wanted to code work like this in below snippet, whichever element is clicked than colors are changes of that element.
In original code html is like this :
<div id="clockOuterCircle"><div id="clockStyleCircle"></div></div> which can be solved by bubbling/capturing
var reed = document.getElementById("clockOuterCircle");
var reed1 = document.getElementById("clockStyleCircle");
reed.addEventListener('click', deed)
reed1.addEventListener('click', deed)
function deed() {
var reed2 = document.getElementById("colorClock");
reed2.click();
var reed3 = reed2.value;
// reed1.addEventListener('change', function() {
this.style.backgroundColor = reed3;
document.getElementById("demo").innerHTML = reed3;
//})
}
#clockStyleCircle {
position: absolute;
width: 16vw;
height: 16vw;
text-align: center;
padding: 0%;
top: 28.5%;
left: 28.5%;
border-radius: 50%;
border: 3px solid black;
background-color: rgb(255, 233, 35);
}
#clockOuterCircle {
display: flex;
justify-content: center;
align-items: center;
width: 42vw;
height: 42vw;
margin: auto;
border-radius: 50%;
border: 4px solid rgb(255, 62, 62);
background-color: rgb(253, 133, 133);
user-select: none;
}
<div id="clockStyleCircle"></div>
<div id="clockOuterCircle"></div>
<div id="demo"></div>
<input type="color" name="colorClock" id="colorClock">
Possible answer of dynamically changing color can be like this in below snippet, like using
input event separately on each element.
var reed = document.getElementById("clockOuterCircle");
var reed1 = document.getElementById("clockStyleCircle");
reed.addEventListener('click', deed)
reed1.addEventListener('click', deed)
//function deed() {
// var reed2 = document.getElementById("colorClock");
// reed2.click();
// var reed3 = reed2.value;
// reed1.addEventListener('change', function() {
// this.style.backgroundColor = reed3;
// document.getElementById("demo").innerHTML = reed3;
//})
//}
reed2 = document.getElementById("colorClock");
reed2.addEventListener('input', deed)
function deed() {
var reed3 = reed2.value;
reed.style.backgroundColor = reed3;
}
reed4 = document.getElementById("colorClock2");
reed4.addEventListener('input', deed1)
function deed1() {
var reed5 = reed4.value;
reed1.style.backgroundColor = reed5;
}
#clockStyleCircle {
position: absolute;
width: 16vw;
height: 16vw;
text-align: center;
padding: 0%;
top: 28.5%;
left: 28.5%;
border-radius: 50%;
border: 3px solid black;
background-color: rgb(255, 233, 35);
}
#clockOuterCircle {
display: flex;
justify-content: center;
align-items: center;
width: 42vw;
height: 42vw;
margin: auto;
border-radius: 50%;
border: 4px solid rgb(255, 62, 62);
background-color: rgb(253, 133, 133);
user-select: none;
}
<div id="clockStyleCircle"></div>
<div id="clockOuterCircle"></div>
<div id="demo"></div>
<input type="color" name="colorClock" id="colorClock">
<input type="color" name="colorClock" id="colorClock2">
But in above method color is not changing of clicked element instead a fixed element color is changed which is defined beforehand . So have to apply code to different elements separately, as there are many elements so wanted to apply both ways
Thanks for the help in advance.
Updated to stop bubbling with event.stopPropagation()
If I've understood you correctly, you want to launch a colour picker every time any particular element in your page is clicked which allows you to change that element's background colour.
This solution adds and then launches a colour picker when any element with the class circle is clicked, then removes it again after a colour has been selected.
The colour picker input is hidden with display:none but the dialog box is visible.
let body = document.body;
let circles = document.querySelectorAll('.circle');
circles.forEach((circle) => {
circle.addEventListener('click', () => {
let existingColourPickers = document.querySelectorAll('input.colour-picker')
existingColourPickers.forEach((existingColourPicker) => {
if (body.contains(existingColourPicker)) {
body.removeChild(existingColourPicker);
}
});
event.stopPropagation();
let colourPicker = document.createElement("input");
colourPicker.type = "color";
colourPicker.className = "colour-picker";
body.appendChild(colourPicker);
colourPicker.click();
colourPicker.addEventListener("input", () => {
circle.style.backgroundColor = event.target.value;
}, false);
colourPicker.addEventListener("change", () => {
body.removeChild(colourPicker);
}, false);
});
});
#clockStyleCircle {
position: absolute;
width: 16vw;
height: 16vw;
text-align: center;
padding: 0%;
top: 28.5%;
left: 28.5%;
border-radius: 50%;
border: 3px solid black;
background-color: rgb(255, 233, 35);
z-index:1;
}
#clockOuterCircle {
display: flex;
justify-content: center;
align-items: center;
width: 42vw;
height: 42vw;
margin: auto;
border-radius: 50%;
border: 4px solid rgb(255, 62, 62);
background-color: rgb(253, 133, 133);
user-select: none;
}
#another-circle {
width:50px;
height:50px;
border-radius: 50%;
border: 4px green solid;
background-color:blue;
position:absolute;
top:20px;
left:20px;
}
.colour-picker {
display:none;
}
<body>
<div id="clockOuterCircle" class="circle">
<div id="clockStyleCircle" class="circle"></div>
</div>
<!-- another circle -->
<div id="another-circle" class="circle"></div>
<!-- ... -->
</body>
What you had was pretty close. I just separated the color picking code into a new function. Try this..
var reed = document.getElementById("clockOuterCircle");
var reed1 = document.getElementById("clockStyleCircle");
reed.addEventListener('click', deed)
reed1.addEventListener('click', deed)
async function deed() {
var color = await getUserColor();
this.style.backgroundColor = color;
document.getElementById("demo").innerHTML = color;
}
function getUserColor() {
return new Promise(done => {
var color_picker = document.createElement('input');
color_picker.setAttribute('type', 'color');
color_picker.style.opacity = 0;
document.body.appendChild(color_picker);
color_picker.addEventListener('change', function() {
var color = this.value;
this.remove();
done(color);
});
color_picker.click();
});
}
#clockStyleCircle {
position: absolute;
width: 16vw;
height: 16vw;
text-align: center;
padding: 0%;
top: 28.5%;
left: 28.5%;
border-radius: 50%;
border: 3px solid black;
background-color: rgb(255, 233, 35);
}
#clockOuterCircle {
display: flex;
justify-content: center;
align-items: center;
width: 42vw;
height: 42vw;
margin: auto;
border-radius: 50%;
border: 4px solid rgb(255, 62, 62);
background-color: rgb(253, 133, 133);
user-select: none;
}
<div id="clockStyleCircle"></div>
<div id="clockOuterCircle"></div>
<div id="demo"></div>
Your example defines the background-color using two different methods class and style, which may produce unexpected results.
Here is an example using the most basic form of JavaScript, that does not set the background-color via class.
When you click an area, it will change to the selected color and when you select a color, the last area clicked, will change to the same color.
To keep it brief and simple, the example does not check, if the elements it operates on, are well defined.
// The last area clicked
var div_last_clicked = 0;
// Called when the document has finished loading
function myonload() {
// Detect when an area is clicked
let elems = document.querySelectorAll('.mydiv');
for(let i = 0; i < elems.length; ++i) {
let elem = elems[i];
elem.addEventListener('click', mydiv_clicked);
}
// Detect when the color changes
let ob = document.querySelector('.mycolor');
ob.addEventListener('change', mycolor_changed);
}
// Called when an area is clicked
function mydiv_clicked(e) {
let ob = document.querySelector('.mycolor');
div_last_clicked = e.target;
div_last_clicked.style = "background-color:" + ob.value;
}
// Called when the color changes
function mycolor_changed(e) {
if(div_last_clicked)
div_last_clicked.style = "background-color:" + e.target.value;
}
.mydiv {
height:30px;
width: 200px;
border:1px solid black;
margin-bottom:2px;
}
<body onload="myonload()">
<input class="mycolor" type="color" value="#ff0000" />
<p>When you click an area below, it will change to the selected color.</p>
<p>When you change the color, the last area clicked will also change
to the same color.</p>
<div class="mydiv">First area</div>
<div class="mydiv">Second area</div>
<div class="mydiv">Third area</div>
</body>
Based on your additional info, if you want to have a single colour input on the page, you can add a data-id attribute to each of your circles, and use that as a reference for which element the colour input should update when changed:
var restyleBG = document.querySelectorAll(".restyleBackground")
var colorPicker = document.getElementById("colorClock");
var selected;
restyleBG.forEach((restyle) => {
restyle.addEventListener('click', changeBGcolor, false)
})
function changeBGcolor(event) {
event.stopPropagation()
selected = document.querySelector(`[data-id="${event.srcElement.dataset.id}"]`);
colorPicker.click();
}
colorPicker.addEventListener('input', (event) => {
selected.style.backgroundColor = colorPicker.value;
})
#clockStyleCircle {
position: absolute;
width: 16vw;
height: 16vw;
text-align: center;
padding: 0%;
top: 28.5%;
left: 28.5%;
border-radius: 50%;
border: 3px solid black;
background-color: rgb(255, 233, 35);
z-index: 1;
}
#clockOuterCircle {
display: flex;
justify-content: center;
align-items: center;
width: 42vw;
height: 42vw;
margin: auto;
border-radius: 50%;
border: 4px solid rgb(255, 62, 62);
background-color: rgb(253, 133, 133);
user-select: none;
}
#another-circle {
width: 50px;
height: 50px;
border-radius: 50%;
border: 4px green solid;
background-color: blue;
position: absolute;
top: 20px;
left: 20px;
}
#colorClock {
display: none;
}
<body>
<input type="color" name="colorClock" id="colorClock">
<div id="clockOuterCircle" class="restyleBackground" data-id="1">
<div id="clockStyleCircle" class="restyleBackground" data-id="2"></div>
</div>
<!-- another circle -->
<div id="another-circle" class="restyleBackground" data-id="3"></div>
<!-- ... -->
</body>
I have a custom scroll wheel and I want to make a button to switch between two classes for that scroll wheel, for example let's say I have these CSS lines to style the scroll wheel:
body::-webkit-scrollbar {
width: 1em;
}
body::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(180, 88, 88, 0.473);
background-color: rgb(131, 69, 69);
}
body::-webkit-scrollbar-thumb {
background-color: rgb(185, 115, 115);
outline: 1px solid slategrey;
}
But when I click the button I want it to change to this CSS:
body::-webkit-scrollbar {
width: 1em;
}
body::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px DIFFERENT COLOR;
background-color: DIFFERENT COLOR;
}
body::-webkit-scrollbar-thumb {
background-color: DIFFERENT COLOR;
outline: 1px solid slategrey;
}
Everything I have read uses the ID to change the CSS for that element but I can't do that with a scroll wheel. I hope this explained it well enough please ask me if you want me to add more code, examples etc.
You can just toggle a class on the body which changes the styling.
Below is an extra snippet that makes use of CSS variables.
const changeBtn = document.querySelector('.change-btn');
changeBtn.addEventListener('click', () => {
document.body.classList.toggle('changed');
});
/* For demo purposes */
body {
height: 500vw;
}
/* Default styling */
body::-webkit-scrollbar {
width: 1em;
}
body::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(180, 88, 88, 0.473);
background-color: rgb(131, 69, 69);
}
body::-webkit-scrollbar-thumb {
background-color: rgb(185, 115, 115);
outline: 1px solid slategrey;
}
/* Changed styling */
body.changed::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px orange;
background-color: teal;
}
body.changed::-webkit-scrollbar-thumb {
background-color: lime;
}
<button type='button' class='change-btn'>Change</button>
Bonus with CSS variables
const changeBtn = document.querySelector('.change-btn');
changeBtn.addEventListener('click', () => {
document.body.classList.toggle('changed');
});
body {
height: 500vw; /* For demo purposes */
--track-color: rgb(131, 69, 69);
--thumb-color: rgb(185, 115, 115);
--shadow-color: rgba(180, 88, 88, 0.473);
}
/* Default styling */
body::-webkit-scrollbar {
width: 1em;
}
body::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px var(--shadow-color);
background-color: var(--track-color);
}
body::-webkit-scrollbar-thumb {
background-color: var(--thumb-color);
outline: 1px solid slategrey;
}
/* Changed styling */
body.changed {
--track-color: teal;
--thumb-color: lime;
--shadow-color: orange;
}
<button type='button' class='change-btn'>Change</button>
You can select elements on jquery without it's ID by using classNames, data-attributes, etc.
$('button').on('click', function(){
$('body::-webkit-scrollbar').css({
'width' : '1em',
...
})
$('body::-webkit-scrollbar-track').css({
'background-color' : 'DIFFERENT COLOR',
'another-property' : 'another-value'
...
})
$('.class-name').css({
'width' : '1em',
...
})
$('[data-foo="bar"]').css({
'width' : '1em',
...
})
$('.class-name.with-another-classname').css({
'width' : '1em',
...
})
$('.class-name .with-children').css({
'width' : '1em',
...
})
})
JavaScript does not require ID's. The alternative to getElementByIdis the usage of querySelector. querySelector can be used to target classes, Id's or tags.
In your case the best solution however would be to target the body tag and to add a class to the body that applies your changes you predefine in CSS like the sample below:
function addClass() {
document.querySelector('body').classList.add('red');
}
html {
color: white;
}
body {
background-color: blue;
}
body.red {
background-color: red;
}
<button onclick="addClass()">Turn background red</button>
You can use querySelector for that
document.querySelector('body')
I think your best option is to do it like this:
function toggleBodyActive(){
document.body.classList.toggle('active');
}
/* set bodyheight for scrolling */
body{ height:200vh; }
body::-webkit-scrollbar {
width: 1em;
}
body::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(180, 88, 88, 0.473);
background-color: rgb(131, 69, 69);
}
body::-webkit-scrollbar-thumb {
background-color: rgb(185, 115, 115);
outline: 1px solid slategrey;
}
/* same but when body has .active class */
body.active::-webkit-scrollbar {
width: 1em;
}
body.active::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 188, 88, 0.473);
background-color: rgb(31, 169, 69);
}
body.active::-webkit-scrollbar-thumb {
background-color: blue;
outline: 1px solid slategrey;
}
<div onclick="toggleBodyActive();">toggle 'active'</div>
I'm working on a custom video player using the HTML5 video element and I'm having trouble getting the full screen button to work with the Fullscreen API.
When I click it, I get the error message:
Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture.
However, I am initiating the call to requestFullscreen with a user gesture... Unless I'm misunderstanding what constitutes a user gesture. A click on an element is a user gesture, isn't it?
I realize that there are a lot of questions about the Fullscreen API on SO, but it looks like many people want to initiate full screen mode without user interaction.
What am I doing wrong?
There is a pen with this code, but I'm likely to change that when I find a solution. I won't change the code here.
Here's the code:
/* Get our elements. */
const player = document.querySelector('.player');
const video = player.querySelector('.viewer');
const progress = player.querySelector('.progress');
const progressBar = player.querySelector('.progress__filled');
const toggle = player.querySelector('.toggle');
const skipButtons = player.querySelectorAll('[data-skip]');
const ranges = player.querySelectorAll('.player__slider');
const fullscreen = player.querySelector('.fullscreen');
let isFullScreen = false;
/* Build our functions */
function togglePlay() {
const action = video.paused ? 'play' : 'pause';
video[action]();
}
function updatePlayIcon() {
toggle.classList.toggle('playing');
}
function skip() {
video.currentTime += parseFloat(this.dataset.skip);
}
function handleRangeUpdate() {
video[this.name] = this.value;
}
function handleProgress() {
const percent = (video.currentTime / video.duration) * 100;
progressBar.style.flexBasis = percent + '%';
}
function scrub(e) {
const seconds = (e.offsetX / progress.offsetWidth) * video.duration;
video.currentTime = seconds;
}
function toggleFullScreen() {
if (isFullScreen) {
console.log("exiting fullscreen");
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
console.log('removing fullscreen class');
player.classList.remove('fullscreen');
} else {
console.log("entering fullscreen");
if (player.requestFullscreen) {
console.log('requestFullScreen');
player.requestFullscreen(); // standard
} else if (player.webkitRequestFullscreen) {
console.log('webkitRequestFullscreen');
player.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
} else if (player.mozRequestFullScreen) {
console.log('mozRequestFullScreen');
player.mozRequestFullScreen();
} else if (player.msRequestFullscreen) {
console.log('msRequestFullscreen');
player.msRequestFullscreen();
} else {
console.error('Unable to find a fullscreen request method');
}
console.log('adding fullscreen class');
player.classList.add('fullscreen');
}
isFullScreen = !isFullScreen;
}
/* Hook up the event listeners */
video.addEventListener('click', togglePlay);
toggle.addEventListener('click', togglePlay);
video.addEventListener('play', updatePlayIcon);
video.addEventListener('pause', updatePlayIcon);
video.addEventListener('timeupdate', handleProgress);
skipButtons.forEach(button => button.addEventListener('click', skip));
ranges.forEach(range => range.addEventListener('change', handleRangeUpdate));
ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate));
let mousedown = false;
progress.addEventListener('click', scrub);
progress.addEventListener('mousemove', (e) => mousedown && scrub(e));
progress.addEventListener('mousedown', () => mousedown = true);
progress.addEventListener('mouseup', () => mousedown = false);
fullscreen.addEventListener('click', toggleFullScreen);
document.addEventListener('fullscreenchange', toggleFullScreen);
document.addEventListener('mozfullscreenchange', toggleFullScreen);
document.addEventListener('webkitfullscreenchange', toggleFullScreen);
document.addEventListener('msfullscreenchange', toggleFullScreen);
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
html, body {
height: 100%;
}
body {
margin: 0;
display: flex;
background: #7A419B;
background: linear-gradient(135deg, #7c1599 0%, #921099 48%, #7e4ae8 100%);
background-size: cover;
align-items: center;
justify-content: center;
}
.player {
max-width: 750px;
max-height: 100%;
border: 5px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
position: relative;
font-size: 0;
overflow: hidden;
}
button.toggle.fullscreen::before {
font-family: "FontAwesome";
content: "\f065";
}
.player.fullscreen .player__controls .toggle.fullscreen::before {
content: "\f066";
}
/* This css is only applied when fullscreen is active. */
.player.fullscreen {
max-width: none;
max-height: none;
width: 100%;
height: 100%;
background-color: black;
}
.player.fullscreen video {
width: 100%;
}
.player__video {
max-width: 100%;
max-height: 100%;
}
.player__button {
background: none;
border: 0;
line-height: 1;
color: white;
text-align: center;
outline: 0;
padding: 0;
cursor: pointer;
max-width: 50px;
}
.player__button:focus {
border-color: #ffc600;
}
.toggle::before {
font-family: "FontAwesome";
content: "\f04b";
}
.toggle.playing::before {
font-family: "FontAwesome";
content: "\f04c";
}
.player__slider {
width: 10px;
height: 30px;
}
.player__controls {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
transform: translateY(100%) translateY(-5px);
transition: all .3s;
flex-wrap: wrap;
background: rgba(0, 0, 0, 0.1);
}
.player:hover .player__controls {
transform: translateY(0);
}
.player:hover .progress {
height: 15px;
}
.player__controls > * {
flex: 1;
}
.progress {
flex: 10;
position: relative;
display: flex;
flex-basis: 100%;
height: 5px;
transition: height 0.3s;
background: rgba(0, 0, 0, 0.5);
cursor: ew-resize;
}
.progress__filled {
width: 50%;
background: #ffc600;
flex: 0;
flex-basis: 0%;
}
.player__slider {
position: relative;
}
.player__slider::after {
content: attr(name);
position: absolute;
top: -2px;
text-shadow: 1px 1px 1px 0 rgba(0,0,0,0.5);
font-size: 0.8em;
}
/* unholy css to style input type="range" */
input[type=range] {
-webkit-appearance: none;
background: transparent;
width: 100%;
margin: 0 5px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8.4px;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);
background: rgba(255, 255, 255, 0.8);
border-radius: 1.3px;
border: 0.2px solid rgba(1, 1, 1, 0);
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(13, 13, 13, 0);
height: 15px;
width: 15px;
border-radius: 50px;
background: #ffc600;
cursor: pointer;
-webkit-appearance: none;
margin-top: -3.5px;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
}
input[type=range]:focus::-wefbkit-slider-runnable-track {
background: #bada55;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8.4px;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);
background: #ffffff;
border-radius: 1.3px;
border: 0.2px solid rgba(1, 1, 1, 0);
}
input[type=range]::-moz-range-thumb {
box-shadow: 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(13, 13, 13, 0);
height: 15px;
width: 15px;
border-radius: 50px;
background: #ffc600;
cursor: pointer;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="player">
<video class="player__video viewer" src="https://player.vimeo.com/external/194837908.sd.mp4?s=c350076905b78c67f74d7ee39fdb4fef01d12420&profile_id=164"></video>
<div class="player__controls">
<div class="progress">
<div class="progress__filled"></div>
</div>
<button class="player__button toggle" title="Toggle Play"></button>
<input type="range" name="volume" class="player__slider" min="0" max="1" step="0.05" value="1">
<input type="range" name="playbackRate" class="player__slider" min="0.5" max="2" step="0.1" value="1">
<button data-skip="-10" class="player__button"><i class="fa fa-step-backward"></i> 10s</button>
<button data-skip="25" class="player__button">25s <i class="fa fa-step-forward"></i></button>
<button class="player__button toggle fullscreen"></button>
</div>
</div>
The problem was that my toggleFullScreen function was being called twice when I clicked on the full screen button. I saw it while I was replying to Bibek Khadka's answer. The first time was when I clicked the button and the second time was when the full-screen mode actually changed because of these event listeners...
document.addEventListener('fullscreenchange', toggleFullScreen);
document.addEventListener('mozfullscreenchange', toggleFullScreen);
document.addEventListener('webkitfullscreenchange', toggleFullScreen);
document.addEventListener('msfullscreenchange', toggleFullScreen);
It would go to fullscreen mode, then back so quick that I didn't see the change. I believe the second time called the Fullscreen API method (technically) without a user gesture and that's why I got the error message.
The solution (for now at least) is to create a separate function for changing classes and the variable I'm using to track whether or not I'm in full screen mode ...
function toggleFullScreenClasses() {
player.classList.toggle('fullscreen');
isFullScreen = !isFullScreen;
}
... then I don't use that to handle the click on the button. I only use it to handle the actual fullscreenchange event...
document.addEventListener('fullscreenchange', toggleFullScreenClasses);
document.addEventListener('mozfullscreenchange', toggleFullScreenClasses);
document.addEventListener('webkitfullscreenchange', toggleFullScreenClasses);
document.addEventListener('msfullscreenchange', toggleFullScreenClasses);
I know this is sloppy, but it solves the problem for now. I previously tried using the :fullscreen pseudo-class, but I had some difficulty and I switched to the more familiar method of toggling classes and variables. I need to take another look at that.
I am no expert...just someone with free time :)
your const player = document.querySelector('.player'); is an element and trying to player.requestFullscreen(); gives you the errror. Modify your code so that the api call is made from something like player.onclick().requestFullscreen(); maybe. Sorry if I wasn't that helpful.
I am using the following css code:
html {
background: #2B2B2B url(images/bg.gif) repeat;
}
body {
max-width: 1000px;
margin: 0px auto;
font-family: sans-serif;
margin: 0 auto;
}
header,
footer,
aside {
display: block;
}
h1 {
text-align: center;
color: rgba(0, 0, 0, 0.6);
text-shadow: 2px 8px 6px rgba(0, 0, 0, 0.2), 0px -5px 35px rgba(255, 255, 255, 0.3);
text-decoration: underline;
}
label {
display: block;
}
fieldset {
border: 0px dotted red;
width: 400px;
margin: 0 auto;
}
input,
select {
width: 400px;
height: 30px;
border-radius: 5px;
padding-left: 10px;
font-size: 14px;
}
select {
line-height: 30px;
background: #f4f4f4;
}
button {
font-size: 14px;
padding: 5px;
background: #333333;
color: #FFFCEC;
float: right;
width: 100px;
}
button:hover {
font-size: 16px;
}
#edit {
background: #DC5B21;
}
#delete {} #course,
#name,
#profesor,
#subject {
background: #ABDCD6;
}
label {
font-size: 15px;
font-weight: bold;
color: #282827;
}
table {
border-spacing: 0.5rem;
border-collapse: collapse;
margin: 0 auto;
background: #ABDCD6;
}
th {
background: #E9633B;
}
th,
td {
border: 2px solid black;
padding: 10px;
}
td {
font-weight: bold;
font-style: oblique;
}
tr:nth-child(even) {
background: #ABDCD6
}
tr:nth-child(odd) {
background: #DCD8CF
}
.container {
width: 1000px;
margin: 0 auto;
}
.headerbar {
width: 988px;
float: left;
}
.headerbar.top {
background: linear-gradient(45deg, rgba(255, 102, 13, 1) 3%, rgba(255, 109, 22, 1) 32%, rgba(255, 121, 38, 1) 77%, rgba(255, 121, 38, 1) 100%);
min-height: 100px;
border-radius: 19px 30px 0px 0px;
box-shadow: #938D94 7px 7px 5px;
}
.headerbar.bottom {
background: linear-gradient(45deg, rgba(255, 102, 13, 1) 3%, rgba(255, 109, 22, 1) 32%, rgba(255, 121, 38, 1) 77%, rgba(255, 121, 38, 1) 100%);
min-height: 60px;
border-radius: 25px;
border-radius: 0px 0px 37px 34px;
box-shadow: #938D94 7px 1px 5px;
}
.leftbar {
width: 50%;
background: #EB593C;
min-height: 605px;
float: left;
border-radius: 4px;
border: 3px dashed #282827;
}
.rightbar {
width: 47%;
background: #221E1D;
min-height: 595px;
float: left;
padding: 5px;
border: 2px solid #EB593C;
box-shadow: #938D94 5px 5px 5px;
}
#submit,
#clear {
border-radius: 25px;
}
input:focus {
border: 1px solid #FF9933;
}
#media screen and (max-width: 700px) {
.leftbar,
.rightbar {
float: none;
}
.headerbar.top h1 {
margin-left: 50px;
text-align: center;
float: left;
}
and here is my HTML page very simple
<!DOCTYPE html>
<html>
<head>
<title>My web app</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="mystyle2.css" rel="stylesheet"/>
<script>
var studentsArray = [];
var selectedIndex = -1;
function init() {
document.getElementById("tablerows").innerHTML = "";
if (localStorage.studentsRecord) {
studentsArray = JSON.parse(localStorage.studentsRecord);
for (var i = 0; i < studentsArray.length; i++) {
prepareTableCell(i, studentsArray[i].course, studentsArray[i].name, studentsArray[i].profesor, studentsArray[i].subject);
}
}
}
function onRegisterPressed() {
if(validate()){
var course = document.getElementById("course").value;
var name = document.getElementById("name").value;
var profesor = document.getElementById("profesor").value;
var subject = document.getElementById("subject").value;
var stuObj = {course: course, name: name, profesor: profesor, subject: subject};
if (selectedIndex === -1) {
studentsArray.push(stuObj);
} else {
studentsArray.splice(selectedIndex, 1, stuObj);
}
localStorage.studentsRecord = JSON.stringify(studentsArray);
init();
onClarPressed();
}else{
}
}
function prepareTableCell(index, course, name, profesor, subject) {
var table = document.getElementById("tablerows");
var row = table.insertRow();
var courseCell = row.insertCell(0);
var nameCell = row.insertCell(1);
var profesorCell = row.insertCell(2);
var subjectCell = row.insertCell(3);
var actionCell = row.insertCell(4);
courseCell.innerHTML = course;
nameCell.innerHTML = name;
profesorCell.innerHTML = profesor;
subjectCell.innerHTML = subject;
actionCell.innerHTML = '<button id="edit" onclick="onEditPressed(' + index + ')">Edit</button><br/><button id="delete" onclick="deleteTableRow(' + index + ')">Delete</button>';
}
function deleteTableRow(index) {
studentsArray.splice(index, 1);
localStorage.studentsRecord = JSON.stringify(studentsArray);
init();
}
function onClarPressed() {
selectedIndex = -1;
document.getElementById("course").value = "";
document.getElementById("name").value = "";
document.getElementById("profesor").value = "";
document.getElementById("subject").value = "Math";
document.getElementById("submit").innerHTML = "Register";
}
function onEditPressed(index) {
selectedIndex = index;
var stuObj = studentsArray[index];
document.getElementById("course").value = stuObj.course;
document.getElementById("name").value = stuObj.name;
document.getElementById("profesor").value = stuObj.profesor;
document.getElementById("subject").value = stuObj.subject;
document.getElementById("submit").innerHTML = "Update";
}
function validate(){
var errors = [];
var re = /^[\w]+$/;
var id = document.getElementById("course");
if(id.value==="" ){
errors.push("Course name is empty");
}else if(id.value.length<3){
errors.push("Course name is to shoort");
}else if(!re.test(id.value)){
errors.push("Input contains invalid characters");
}
var name = document.getElementById("name");
var regEx = /^[a-zA-Z ]+$/;
if(name.value===""){
errors.push("Name cannot be empty");
}else if(!regEx.test(name.value)){
errors.push("Name contains invalid characters");
}
var profesor = document.getElementById("profesor");
if(profesor.value===""){
errors.push("Professor field cannot be empty");
}else if(!regEx.test(profesor.value)){
errors.push("Professor field contains invalid characters");
}
if(errors.length>0){
var message = "ERRORS:\n\n";
for(var i = 0;i<errors.length;i++){
message+=errors[i]+"\n";
}
alert(message);
return false;
}
return true;
}
</script>
</head>
<body onload="init()">
<header class="headerbar top"><h1>ITEC3506: Assignment#2</h1></header>
<aside class="leftbar">
<div>
<fieldset>
<label for="course"><span>Course Name</span></label>
<input type="text" placeholder="enter name of course" id="course">
</fieldset>
<fieldset>
<label for="name">Your Name</label>
<input type="text" placeholder="enter your name" id="name">
</fieldset>
<fieldset>
<label for="profesor">Course Professor</label>
<input type="text" placeholder="enter course Professor" id="profesor">
</fieldset>
<fieldset>
<label for="subject">Subject</label>
<select id="subject">
<option value="Math">Math</option>
<option value="Physics">Physics</option>
<option value="Chemistry">Chemistry</option>
<option value="English">English</option>
<option value="CS">CS</option>
</select>
</fieldset>
<fieldset>
<label for="submit"> </label>
<button id="submit" onclick="onRegisterPressed()">Submit</button>
<button id="clear" onclick="onClarPressed()">Clear</button>
</fieldset>
</div>
</aside>
<aside class="rightbar">
<table id="regtable">
<thead>
<tr>
<th>Course</th>
<th>Student</th>
<th>Professor</th>
<th>Subject</th>
<th>Action</th>
</tr>
</thead>
<tbody id="tablerows">
</tbody>
</table>
</aside>
<footer class="headerbar bottom"></footer>
</div>
</body>
</html>
My question is how can I transform this code into a responsive site.
Everything is resizing normally, except I cannot seem to resize my table and form. Could somebody help me?
A few things going on here.
First, you don't have a set width on a few of your fields, so change:
fieldset{
border: 0px dotted red;
width: 400px;
margin: 0 auto;
}
to:
fieldset{
border: 0px dotted red;
width: 400px;
margin: 0 auto;
max-width: 100%;
}
Also change .headerbar from width: 988px; to width: 100%;.
For responsive frameworks, you need to ensure that you never have a set a fixed width without ensuring there is a max-width attached to it, otherwise your content size will never drop below the size of your fixed width.
Second, I noticed the following:
.leftbar{
width: 50%;
background: #EB593C;
min-height: 605px;
float: left;
border-radius: 4px;
border: 3px dashed #282827;
}
You didn't specifically call this out, but when I check your code in a smaller view, I notice that your width: 50%; is causing the backgrounds to look off, which does not seem to be your intention. I would recommend adding .leftbar { width: 100%; } as well as .rightbar { width: 100%; } inside of #media screen and (max-width:700px){
That just leaves the table. Tables do not automatically break down, so are generally not something we want to use when developing a responsive site, but of course sometimes there is no getting around this.
There are a few ways to tackle the issue with the table. One is to set the table to display:block; and apply overflow-x: scroll; to it inside of your #media screen and (max-width:700px){, which will allow the user to scroll left/right when viewing it from smaller screens. Another is to use one of the various Javascript plugins that can achieve this.
Hope this helps get you on the right track. Best of luck!
Do not set width for these
input,select{/*width: 400px;*/}
fieldset{/*width: 400px;*/}
If you are setting width obviously you cannot obtain a responsive layout
I know CSS is "cascading", but in this case I want the effect to ascend. I'm open for either a JS or CSS solution, but honestly I'd prefer the solution with the least amount of code or overhead.
When I hover over a (child) letter, I want the entire background color to change for the ENTIRE WINDOW, not just the child element. Each letter is contained within the parent #word div which fills the whole window (or body).
It would be nice if something like the below existed in css:
#h:hover #word{
background-color: rgba(0, 102, 0, .5);
}
But it's not working. Anyone have any ideas??
HTML:
<div id="word">
<h1><a id="h" class= "letter" href=#>H</a></h1>
<h1><a class= "letter" href=#>E</a></h1>
<h1><a class= "letter" href=#>L</a></h1>
<h1><a class= "letter" href=#>L</a></h1>
<h1><a class= "letter" href=#>O</a></h1>
</div>
CSS:
body {
/*font-family: 'Sigmar One', cursive;*/
font-family: 'Chango', cursive;
font-size: 115px;
color: white;
text-shadow: 5px 5px 5px #000;
/* background-color: #0047b2 */
width: 100%;
height: 100%;
margin: 0px;
background: url(img/texture.png) repeat;
}
#word {
position:absolute;
height:100%;
width: 70%;
display: table;
padding: 0 15% 0 15%;
background: rgba(0, 71, 178, .5);
}
h1 {
display: table-cell;
vertical-align: middle;
text-align:center;
height: 1em;
}
a {
/*border: 1px solid black;*/
display: inline-block;
line-height: 100%;
overflow: hidden;
}
a:visited, a:active {
text-decoration: none;
color: white;
/*color: #E8E8E8;*/
}
a:link {
text-decoration: none;
color: white;
text-shadow: 3px -3px 0px black, -2px 2px 5px #0056b2;
}
a:hover {
text-shadow: 5px 5px 5px #000;
color: white;
}
#h:hover #word{
background-color: rgba(0, 102, 0, .5);
}
#media (max-width: 1330px){
#word {
width: 100%;
padding: 0px;
}
}
Fiddle: http://jsfiddle.net/SZ9ku/1/
The solution would probably be JS:
$(".letter").hover(function() {
$(this).closest("#word").toggleClass("hovered")
});
Here is a fiddle: http://jsfiddle.net/zT9AS/2
True;
#word #h:hover {
background-color: rgba(0, 102, 0, .5);
}
False;
#h:hover #word{
background-color: rgba(0, 102, 0, .5);
}
A without jquery solution:
onload = function()
{
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; ++i)
{
if (links[i].className == 'letter')
{
links[i].onmouseover = function() {
document.getElementById('word').style.backgroundColor="#0000FF";
};
links[i].onmouseout = function() {
document.getElementById('word').style.backgroundColor="#FFFFFF";
};
}
}
}
It can be done in pure JS, no jQuery (I assume you don't want that since it wouldn't be that light in code), this is the best I could came out with:
var word = document.getElementsByClassName("letter");
for (i=0; i<word.length; i++) {
word[i].addEventListener("mouseenter", function( event ) {
parent = event.target.parentNode.parentNode;
//whenever the mouse hovers over a letter this will be evaluated once
parent.style.backgroundColor = "green";
});
word[i].addEventListener("mouseout", function( event ) {
parent = event.target.parentNode.parentNode;
//whenever the mouse hovers over a letter this will be evaluated once
parent.style.backgroundColor = "";
});
}
Try it in this fiddle: http://jsfiddle.net/SZ9ku/17/
In POJS, add the following
CSS
.wordBg {
background: rgba(0, 102, 0, .5) !important;
}
Javascript
var changeWordBg = (function (word) {
return function (evt) {
if (evt.target.classList.contains("letter")) {
switch (evt.type) {
case "mouseover":
word.classList.add("wordBg");
break;
case "mouseout":
word.classList.remove("wordBg");
break;
default:
}
}
};
}(document.getElementById("word")));
document.body.addEventListener("mouseover", changeWordBg, false);
document.body.addEventListener("mouseout", changeWordBg, false);
On jsfiddle