I am rather new to javascript and am attempting to code a series of buttons on my webpage that function to change the overall brightness of the page. I've coded 3 buttons in my page responsible for increasing, decreasing and resetting the brightness of the body. Then I've coded some javascript which is supposed to increase/decrease the brightness by 10% with each button click. I've done the following:
var $ = function (id) {
return document.getElementById(id);
};
function modifyBrightness(val) {
var brightness = 1.0;
brightness = brightness + val;
brightness = parseInt(brightness, 10);
$("body_id").style.filter = "brightness(brightness)";
return brightness;
}
function resetBrightness() {
$("body_id").style.filter = "brightness(1.00)";
}
$("decrease_brightness").onclick = modifyBrightness(-0.1);
$("increase_brightness").onclick = modifyBrightness(0.1);
$("reset_brightness").onclick = resetBrightness();
#body_id{
height: 100px;
background-color: blue;
}
<body id="body_id>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tincidunt pharetra dui, non efficitur mauris scelerisque sed. Donec auctor ut sem vitae bibendum. Aliquam dignissim aliquet augue et condimentum. Aliquam non dui velit. Aenean egestas ligula eget urna malesuada imperdiet. Vivamus vel velit dapibus, sollicitudin dolor at, elementum quam. Aenean eu libero vel velit faucibus convallis. Nullam et velit a ipsum sagittis malesuada. <p>
<body>
<form id="brightness_change_form">
<label for="decrease_brightness" id="change_brightness_label">Change Brightness:</label>
<input type="button" id="decrease_brightness" value="Decrease Page Brightness">
<input type="button" id="increase_brightness" value="Increase Page Brightness">
<input type="button" id="reset_brightness" value="Reset Page Brightness">
</form>
However, I simply am not knowledgeable enough to figure out what I've got wrong in my javascript. I would greatly appreciate any advice.
As Nicholas pointed out, you're missing the closing quote on the body id which is why you're getting a syntax error.
Change <body id="body_id> to <body id="body_id">.
var current = 50;
const $ = (id) => document.getElementById(id);
function modifyBrightness(val) {
current += val;
//$("body_id").style.backgroundColor = `hsl(240, 100%, ${current}%)`;
$("body_id").style.filter = `brightness(${current}%)`;
}
$("decrease_brightness").addEventListener('click', () => {
modifyBrightness(-10);
});
$("increase_brightness").addEventListener('click', () => {
modifyBrightness(10);
});
$("reset_brightness").addEventListener('click', () => {
modifyBrightness(50);
});
#body_id{
height: 100px;
background-color: blue;
}
<body id="body_id">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tincidunt pharetra dui, non efficitur mauris scelerisque sed. Donec auctor ut sem vitae bibendum. Aliquam dignissim aliquet augue et condimentum. Aliquam non dui velit. Aenean egestas ligula eget urna malesuada imperdiet. Vivamus vel velit dapibus, sollicitudin dolor at, elementum quam. Aenean eu libero vel velit faucibus convallis. Nullam et velit a ipsum sagittis malesuada. <p>
<body>
<form id="brightness_change_form">
<label for="decrease_brightness" id="change_brightness_label">Change Brightness:</label>
<input type="button" id="decrease_brightness" value="Decrease Page Brightness">
<input type="button" id="increase_brightness" value="Increase Page Brightness">
<input type="button" id="reset_brightness" value="Reset Page Brightness">
</form>
You can also try using HSL (Hue, Saturation, Lightness) to change only the background color lightness which won't affect the buttons. I left a comment in the above code for you to try yourself.
Related
I want to show a div only if the page has scrollbars, and hide it if not. I want to do this in either pure CSS or JavaScript (if impossible in CSS).
I've found a question on Stack Exchange, but it's infested with that garbage jQuery cancer, so it's useless. I'm talking about pure JavaScript -- not jCancer.
Here's a pure JS solution, using this function:
const isScrollable = elem => elem.scrollHeight > elem.clientHeight;
Edit (description):
The function returns true if the element is scrollable, false otherwise.
Example:
const isScrollable = elem => elem.scrollHeight > elem.clientHeight;
// make scrollable divs have a red border
document.querySelectorAll("div").forEach(div => {
if (isScrollable(div)) div.style.borderColor = "red";
});
div {
border: 1px solid grey;
width: 200px;
overflow: auto;
margin-bottom: 1rem;
}
div#div1 {
height: 100px;
}
div#div2 {
height: 170px;
}
<div id="div1">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras maximus arcu quis mi eleifend tristique. Curabitur convallis tellus eget volutpat luctus. Fusce molestie molestie ante, vel fermentum erat. Fusce tempor erat eget dolor ultrices interdum. Pellentesque sed placerat nulla. Duis consequat, lorem quis vehicula lacinia, libero leo tincidunt odio, et porta ex turpis malesuada lorem. Proin sapien metus, facilisis sed urna non, vehicula commodo velit. Etiam venenatis laoreet neque vel sollicitudin. Suspendisse lacinia, lectus hendrerit dapibus laoreet, dui lorem condimentum enim, a vulputate ex ipsum ut nibh.
</div>
<div id="div2">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras maximus arcu quis mi eleifend tristique. Curabitur convallis tellus eget volutpat luctus. Fusce molestie molestie ante, vel fermentum erat.
</div>
Considering that components such as dialogs, modals, tooltips, etc. should be of higher stacking index than any other elements in an HTML page, I placed these components in an immediate sibling of root element where all the other elements are placed. React developers will quickly recognize this and they'll know that I'm trying to use React Portals. You can visualize it here:
<body>
<div id="root">
// ----- other elements -----
<div id="supposed-parent" />
// ----- other elements -----
</div>
<div id="dialog-container">
<div id="supposed-child" />
</div>
</body>
So, how can I position #supposed-child next or beside #supposed-parent? Any help would be appreciated.
I don't think this is possible with a pure css. But with a little script we can achieve this. Take the offset-left and top of the supposed-parent and apply the same to the supposed-child. The child should be absolute positioned element. Check the below sample and It hope this will be useful for you.
Even though the supposed-child(yellow box) is independent of the supposed-parent, It will be always align with the top-left of the supposed-parent.
function offsetCalculate(){
var parentTop = $('#supposed-parent').offset();
var parentLeft = $('#supposed-parent').offset();
$('#supposed-child').css({
'top':parentTop.top,
'left': parentLeft.left
});
}
$(document).ready(function () {
offsetCalculate();
});
$(window).resize(function(){
offsetCalculate();
});
#supposed-child{
position: absolute;
background: yellow;
border-radius: 5px;
padding: 10px;
z-index: 999;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="root">
<h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer dolor libero, euismod et nisl eu, imperdiet elementum neque. Praesent aliquet non tellus sed blandit. Ut vitae velit eget turpis ornare convallis. Quisque nec felis eget mi vestibulum luctus eu non dui.</h1>
<div id="supposed-parent">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer dolor libero, euismod et nisl eu, imperdiet elementum neque. Praesent aliquet non tellus sed blandit. Ut vitae velit eget turpis ornare convallis. Quisque nec felis eget mi vestibulum luctus eu non dui. Pellentesque eget commodo tellus. Curabitur a dolor est. Integer dapibus lectus nec mi luctus, ac ornare ex auctor. Donec vel nisi nulla. Mauris maximus egestas nunc ut egestas. Suspendisse id leo nec elit consectetur interdum. Ut purus nibh, tristique quis est vel, ultrices blandit nibh. Aenean nibh justo, mattis sed vulputate quis, efficitur eu mauris. Sed vel vulputate metus, et dictum arcu. In ornare nisl vitae purus elementum, quis egestas dolor volutpat. In velit nisi, posuere in urna non, feugiat luctus enim.
</div>
</div>
<div id="dialog-container">
<div id="supposed-child" >This is a popup</div>
</div>
When I change select it will scroll accordingly to the div and it is working fine, But how to I change select on document scroll ?
$("select").change(function(){
var divid = $(this).val();
$('html, body').animate({
scrollTop: $("." + divid).offset().top
}, 2000);
});
div{
height:300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select>
<option value="div1">div1</option>
<option value="div2">div2</option>
<option value="div3">div3</option>
<option value="div4">div4</option>
</select>
<div class="div1">
div1
</div>
<div class="div2">
div2
</div>
<div class="div3">
div3
</div>
<div class="div4">
div4
</div>
You can put all the options into array and check it with the window scroll, this way you can have dynamic divs and also you can check them all at once.
$("select").change(function() {
var divid = $(this).val();
$('html, body').animate({
scrollTop: $("." + divid).offset().top
}, 2000);
});
var output = [];
$.each($("select option"), function(key, value) {
output.push(value.value);
});
$(window).on('scroll', function() {
//checking if it is already in animation mode or not
if (!$("html,body").is(':animated')) {
var filtered = output.filter(a => {
return $(this).scrollTop() >= $("." + a).position().top
});
//checking which options are meeting with the requirement
if (filtered.length > 0) {
//selecting the last one.
$("select").val((filtered[filtered.length - 1]))
}
}
});
div {
height: 300px;
}
select {
position: fixed;
top: 0
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select>
<option value="div1">div1</option>
<option value="div2">div2</option>
<option value="div3">div3</option>
<option value="div4">div4</option>
</select>
<div class="div1">
div1
</div>
<div class="div2">
div2
</div>
<div class="div3">
div3
</div>
<div class="div4">
div4
</div>
You could use the Intersection Observer API to change your select when the div enters the viewport.
UPDATE: A good valid answer has already been provided to solve the problem, I am just providing the example below for educational purpose for people interested in examples of Intersection Observer and scrollIntoView.
Be cautious that the example provided is not fully supported by all browsers and should not be used on production environment (current snippet has been tested with Chrome 71):
https://caniuse.com/#feat=intersectionobserver
https://caniuse.com/#feat=scrollintoview
var dropdown = document.querySelector('#dropdown');
var targets = document.querySelectorAll('.target');
var options = {
root: document.querySelector('#scrollable'),
rootMargin: '0px',
threshold: 0
}
var callback = function(entries, observer) {
entries.forEach(entry => {
// If the element enters the viewport...
if (entry.isIntersecting) {
// ... then update the dropdown.
dropdown.value = entry.target.id;
}
});
};
var observer = new IntersectionObserver(callback, options);
targets.forEach(target => observer.observe(target));
dropdown.addEventListener('change', () => {
var element = document.getElementById(dropdown.value);
element.scrollIntoView(true);
});
#scrollable {
border: 1px solid #ccc;
height: 150px;
overflow: auto;
width: 300px
}
<select id="dropdown">
<option value="div1">div1</option>
<option value="div2">div2</option>
<option value="div3">div3</option>
<option value="div4">div4</option>
</select>
<div id="scrollable">
<div class="target" id="div1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc et dolor a leo semper suscipit. Donec quis lobortis mauris, quis finibus neque. Integer justo mi, faucibus vel fermentum at, convallis eget dui. Quisque pharetra velit in lacus ornare, a blandit tortor tempus. Nulla sit amet sapien turpis. Morbi ut dapibus lacus, id tristique ligula. Phasellus vel neque vitae metus congue vulputate. Cras laoreet euismod nisl sed aliquet. Maecenas eu facilisis magna. Etiam et tempor justo, vel dictum sem.</div>
<div class="target" id="div2">Pellentesque gravida, massa ac venenatis volutpat, erat neque ornare risus, convallis dignissim ante erat a felis. Suspendisse erat ligula, egestas non ante eu, iaculis aliquam ante. Aliquam vestibulum mattis erat, sed convallis quam rutrum fringilla. Nulla hendrerit libero sed nibh faucibus, nec pharetra felis tempor. Vestibulum in sem augue.</div>
<div class="target" id="div3">Suspendisse potenti. Nullam blandit dapibus eros, sed semper quam eleifend in. Nunc elementum ligula eget volutpat imperdiet. Sed cursus rhoncus semper. Pellentesque dignissim nibh a facilisis viverra. Sed eu dictum quam. Suspendisse consectetur libero orci, quis ornare metus tincidunt eget. Fusce congue lectus ligula, non aliquet urna ullamcorper non. Aliquam leo ipsum, scelerisque ut tortor sodales, vestibulum aliquet mauris. Pellentesque sit amet sapien pulvinar diam malesuada euismod in at sapien. Mauris eleifend laoreet nibh vitae interdum. Suspendisse eget velit a tortor egestas fermentum. Nunc in libero felis.</div>
<div class="target" id="div4">Integer rhoncus fringilla viverra. Vivamus tempor mi quis laoreet porta. In maximus tincidunt tincidunt. In viverra a est dictum vulputate. Curabitur eu sagittis odio, sed molestie massa. Donec ac neque vel mauris pellentesque blandit id non nisl. Curabitur egestas, enim semper viverra aliquam, nunc orci pretium diam, egestas dictum elit purus eu nisl. Cras aliquet dignissim fringilla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id viverra tellus, sit amet gravida orci. Aliquam elementum posuere augue.</div>
</div>
Even if I recommend to use a plugin to avoid any inconsistencies, a quick solution is shown below. It extracts the index of the focused div, and changes the value of the select dropdown. However, this solution is only limited to focus events.
$('div[value^="div"]').on('focus',function(e){
let selectedIndex = $(this).prop('class').match(/\d+/g)[0] - 1;
$('select').prop('selectedIndex', selectedIndex);
});
I'm building a website that is heavily built on ajax. Some of my JS comes as part of the pages that I load through ajax. The functions from the JS cannot be called from other JS scripts that has been loaded earlier. As I have understand it, it has to with the code not being really declared and that I could use eval() on the code. But that feels like waste of resources since the code runs and works aslong it don't need to work with code that is already declared.
My little short ajax page loader.
$(document).ready(function(){
var old = "home"
$("#topMenu a").on("click",function(){
if(typeof edit_menu !== 'undefined' && edit_menu){
return;
}
var link = $(this).attr("data-link");
//Load Ajax
LoadPage(link, old);
});
});
function LoadPage(link, old){
$.ajax({
url: "pages/" + link + ".php",
}).done(function(data){
$("#content").html(data);
});
Hide();
history.pushState(old,null,"?page=" + link);
}
If I login as admin I will then also have an admin JS file loaded as part of the DOM. The script calls a function in another JS file thats is loaded dynamically. The function doesn't run because the admin JS file is not aware of the new funciton.
The dynamically added JS file is a script tag part of other HTML code.
Example of dynamically added code.
<script src="/javascript/projects.js"></script>
<header>Projects</header>
<article>
<h1>First project</h1>
<section class="summary">
Lorem ipsum is da shit
</section>
<section class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed diam orci, hendrerit a justo sit amet, egestas ullamcorper orci. Aliquam quis facilisis urna. Fusce blandit pellentesque elit. Vivamus ullamcorper luctus felis in rutrum. Nam quis facilisis mauris. Nunc iaculis sagittis sollicitudin. Ut imperdiet, purus et fermentum tempor, leo mauris feugiat libero, eu pulvinar odio felis sed tortor. Mauris vel libero orci. Suspendisse a mollis turpis. Maecenas egestas felis eget ultrices porta. Nulla non metus ut augue faucibus ultrices. Phasellus arcu magna, vulputate eget sollicitudin a, ullamcorper a ipsum. Suspendisse potenti. Pellentesque eget vulputate ipsum.</p> <p>Ut ultricies faucibus sapien, ut sodales turpis rhoncus molestie. Vivamus luctus auctor pellentesque. Phasellus ut ex vulputate, congue felis nec, pharetra odio. Ut ligula ante, luctus nec enim ac, lobortis ultrices elit. Quisque sed justo a nibh congue tempor sit amet ut mauris. In non enim nulla. Nulla et dolor sollicitudin, finibus ante eu, egestas purus. Phasellus sit amet eros dignissim, pellentesque elit tempor, sagittis eros. Donec sollicitudin velit ipsum, semper ultrices sapien blandit non. Phasellus vehicula orci in ipsum blandit hendrerit. Vestibulum facilisis dolor ac tincidunt fermentum.</p>
</section>
<span>Update text</span> <input type="checkbox" class="update_projects" data-id="First project" /><br /><button class="update_text">Update</button><input type="hidden" class="token" value="4926dd431992894a8364ca4d89733038be0cb0ec4897eb2a417637685554b6df40149522a858b5bfaaa91526b84718cdd54b301229371841dc2f022bbd0f804eaf31abb51caef55b26cca3209cc3b0838f194176f78f0931b2217669cd2912faa25a3c3e469ce686d79ac7a7852fbfee9d6d4dc5da18b499e703b4ef57fc88c1a99ccf8943af5853433f911ce276ff13e9ecbfb074d747f1a07f26c141f80383a149902dfe7469262724e2f67aae48d9919d486855a892b17681660ab3e0d25f98e714c3d98cc903" /><input type="hidden" class="id" value="1" /><br /><input type="text" name="tag" class="tag" value="php" />
</article><article>
<h1>Secons project</h1>
<section class="summary">
And I'm not lying
</section>
<section class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed diam orci, hendrerit a justo sit amet, egestas ullamcorper orci. Aliquam quis facilisis urna. Fusce blandit pellentesque elit. Vivamus ullamcorper luctus felis in rutrum. Nam quis facilisis mauris. Nunc iaculis sagittis sollicitudin. Ut imperdiet, purus et fermentum tempor, leo mauris feugiat libero, eu pulvinar odio felis sed tortor. Mauris vel libero orci. Suspendisse a mollis turpis. Maecenas egestas felis eget ultrices porta. Nulla non metus ut augue faucibus ultrices. Phasellus arcu magna, vulputate eget sollicitudin a, ullamcorper a ipsum. Suspendisse potenti. Pellentesque eget vulputate ipsum.</p>
<p>Ut ultricies faucibus sapien, ut sodales turpis rhoncus molestie. Vivamus luctus auctor pellentesque. Phasellus ut ex vulputate, congue felis nec, pharetra odio. Ut ligula ante, luctus nec enim ac, lobortis ultrices elit. Quisque sed justo a nibh congue tempor sit amet ut mauris. In non enim nulla. Nulla et dolor sollicitudin, finibus ante eu, egestas purus. Phasellus sit amet eros dignissim, pellentesque elit tempor, sagittis eros. Donec sollicitudin velit ipsum, semper ultrices sapien blandit non. Phasellus vehicula orci in ipsum blandit hendrerit. Vestibulum facilisis dolor ac tincidunt fermentum.</p>
</section>
<span>Update text</span> <input type="checkbox" class="update_projects" data-id="Secons project" /><br /><button class="update_text">Update</button><input type="hidden" class="token" value="4926dd431992894a8364ca4d89733038be0cb0ec4897eb2a417637685554b6df40149522a858b5bfaaa91526b84718cdd54b301229371841dc2f022bbd0f804eaf31abb51caef55b26cca3209cc3b0838f194176f78f0931b2217669cd2912faa25a3c3e469ce686d79ac7a7852fbfee9d6d4dc5da18b499e703b4ef57fc88c1a99ccf8943af5853433f911ce276ff13e9ecbfb074d747f1a07f26c141f80383a149902dfe7469262724e2f67aae48d9919d486855a892b17681660ab3e0d25f98e714c3d98cc903" /><input type="hidden" class="id" value="2" /><br /><input type="text" name="tag" class="tag" value="" />
</article></section>
UPDATE
After some more testing I have found the JS can't find any of my added HTML while the js added on the same time can.
I am trying to understand the question but as i can't comment for the moment some parts of it are not enugh clear, i work with jsfiddle if it can help, is it possible to make a little example not all the code to help me understand what's going on. Starting with
this function for example :
function LoadPage(link, old){
$.ajax({
url: "pages/" + link + ".php",
}).done(function(data){
$("#content").html(data);
});
Hide();
history.pushState(old,null,"?page=" + link);
}
https://jsfiddle.net/3z62n8c2/
Try the following script, this will remove the script from the loaded HTML and load them on to the page before adding the content. Also it makes sure that the same javascript file does not get added multiple times.
function LoadPage(link, old){
$.ajax({
url: "pages/" + link + ".php",
}).done(function(data){
$loadedData = $("<div>"+data+"</div>");
$loadedData.find('script[src]').each(function(i,v){
var jsPath = $(this).attr('src');
if($('[src="'+jsPath+'"]').length == 0){
var tag = document.createElement('script');
tag.src = jsPath;
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
});
$loadedData.find('script[src]').remove();
$("#content").html($loadedData.html());
});
Hide();
history.pushState(old,null,"?page=" + link);
}
To load the script you must append it as an HTML element, like this :
}).done(function(data) {
var el = $(document.createElement('div')).html(data);
var scripts = el.find('script');
for(var i = 0; i < scripts.length; i++) {
window.eval(scripts[i].innerHTML);
scripts[i].remove();
}
$('#content').html(el.html());
});
How can I change the height value from 100 pixels to a percentage value? Lets say 50%. I'm fairly new to javascript...
<script language="javascript" type="text/javascript">
$(document).ready(function(){
$(".item-info-overlay p").dotdotdot({
ellipsis:"...",
wrap:"word",
height: 100,
after:"a.readmore",})
});
</script>
Rather than modifying the dotdotdot code, it might be simpler to calculate a pixel value based on your percentage and pass that pixel value to dotdotdot.
For example:
// define your desired percentage
var percentage = 50;
jQuery(function() {
// calculate pixel height based on your percentage
var dot_height = jQuery('div#container').height() * (percentage / 100);
jQuery("div#text").dotdotdot({
ellipsis: "...",
height: dot_height,
wrap: "word",
after: "a.readmore",
watch: "window"
});
});
div#container {
height: 150px;
background-color: #CCC;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery.dotdotdot/1.7.2/jquery.dotdotdot.min.js"></script>
<div id="container">
<div id="text">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat
volutpat. Sed quis velit. Nulla facilisi. Nulla libero. Vivamus pharetra posuere sapien. Nam consectetuer. Sed aliquam, nunc eget euismod ullamcorper, lectus nunc ullamcorper orci, fermentum bibendum enim nibh eget ipsum. Donec porttitor ligula eu
dolor. Maecenas vitae nulla consequat libero cursus venenatis. Nam magna enim, accumsan eu, blandit sed, blandit a, eros. Quisque facilisis erat a dui. Nam malesuada ornare dolor.
Read More
</div>
</div>
If you're building a responsive site or your container is fluid, you can apply this same logic inside of a throttled resize handler.