Javascript page enter event - javascript

I want an event this should load everytime the site is typed in the browser example : http://localhost/ is typed in the url and the first page should show is my overlay. After they read the information they can close it but if they wanna read it again they can click the button. Also if the site is getting refreshed the overlay should be popup again.
My current code and where I stuck :
const doc = document;
const menuOpen = doc.querySelector(".menu");
const menuClose = doc.querySelector(".close");
const overlay = doc.querySelector(".overlay");
menuOpen.addEventListener("click", () => {
overlay.classList.add("overlay--active");
});
menuClose.addEventListener("click", () => {
overlay.classList.remove("overlay--active");
});

to do this in javascript you can achieve this using window.load like this:
window.onload = function() {myFunction()};
function myFunction() {
overlay.classList.add("overlay--active");
}
but for the best solution i would think adding the overlay--active by default as #Keith mentioned would be nicer as this requires less javascript for the webpage.

You could do it by using if-else structure in javascript. Like the code I posted here. In this method you don’t need the “onload” event. And the “overlay” popped up again when the page is refreshed.
var menuOpen = document.getElementById("menu");
var overlay = document.querySelector(".overlay");
menuOpen.addEventListener("click", () => {
if(overlay.classList.contains("active")){
overlay.classList.add("deactive");
overlay.classList.remove("active");
menuOpen.innerHTML = "show";
} else {
overlay.classList.add("active");
overlay.classList.remove("deactive");
menuOpen.innerHTML = "hide";
}
});
.active {
opacity: 1;
}
.deactive {
opacity: 0;
}
#menu {
margin-top: 15px;
margin-left: 100px;
width: 100px;
height: 60px;
background-color: #fff;
border: 1px solid #5522dd;
color: #5522dd;
cursor: pointer;
}
#menu:hover {
color: #fff;
background-color: #5522dd;
}
.overlay {
border: 2px solid #000;
margin-top: 25px;
-webkit-transition: 2s;
transition: 2s;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Javascript page enter event</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="overlay active">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui modi quasi, quam deleniti, placeat expedita nostrum quae quaerat? Id, velit iste saepe dolore, consequuntur vel quis iure excepturi ut aut fugit dignissimos ea magni repudiandae nihil, assumenda deleniti nostrum tenetur minima aperiam doloribus. Quaerat sunt nam distinctio! Suscipit nostrum vel, sunt, eos esse fugit.
</div>
<button id="menu">hide</button>
<script src="javasc.js"></script>
</body>
</html>

You can use jquery and use it in the loading of document.
like
document.ready(()=>{
$(".overlay").addClass("overlay--active");
})

Related

How to apply a class to a div based on div width?

I am trying to add a class to a specific div based on its width, so it is dynamically added or removed as the overall window (and therefore the div, which has a percentage width) resizes.
I've tried using javascript querySelector and offsetWidth to identify the div, but so far it's not working. My method is inspired by this codepen (which gets the window width, so slightly different from what I'm trying to do).
Here's what I have so far:
var addWideClass = function() {
var width = document.querySelector('.v65-productGroup-product').offsetWidth;
if (width < 141) {
$('.v65-productGroup-product').removeClass('wide');
} else if (width >= 415) {
$('.v65-productGroup-product').addClass('wide');
};
};
$(window).resize(function(){
addWideClass();
});
addWideClass();
What do I need to change to have .wide added to .v65-productGroup-product when .v65-productGroup-product > 414px wide?
The offsetWidth may be cashed or have missed a reflow. Browser vendors may choose how to handle DOM calculations like offsetWidth.
As you say: the overall window (and therefore the div, which has a percentage width) resizes. You can change this row to detect window width instead of div width:
var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || screen.width
Then you can have typical device breakpoints. If you really need it to change when div is 141 and 415 pixels you need to use yor mathematic skills to calculate how wide the window has to be from one of these values added to the rest of widths and procentual factors you know of the neigbouring elements.
maybe this pen helps:
https://codepen.io/anon/pen/zQXMoz
I basically modified the pen you referred to and added the functionality you wanted to. change the page size to see the effect.
P.S. in your own code, did you mean:
if (width < 414) {
instead of
if (width < 141) {
?
additionally, if you just want to toggle the class on 414px, then this should suffice:
if (width < 414) {
// remove class
}
else {
// add class
}
I made this demonstration: See it in full page view and change browser width
"use strict";
console.clear();
const addWideClass = function() {
Array.from(document.getElementsByTagName('span')).forEach(el => {
const w = el.offsetWidth
el.style.setProperty('--w', `'${w}'`);
if (w < 141) {
el.classList.remove("wide");
} else if (w >= 415) {
el.classList.add("wide");
}
})
};
window.addEventListener('resize', addWideClass)
addWideClass()
div {
display: flex;
}
div span {
box-sizing: border-box;
padding: 10px;
--w: '213232';
}
div span:nth-child(1) {
flex-grow: 2;
flex-basis: 0;
background-color: gold;
}
div span:nth-child(2) {
flex-grow: 3;
flex-basis: 0;
background-color: silver;
}
div span:nth-child(3) {
flex-grow: 4;
flex-basis: 0;
background-color: goldenrod;
}
div span.wide {
border: 10px solid #000;
}
div span:before {
content: var(--w);
display: block;
}
<div>
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempora similique vitae accusantium repellat nobis architecto unde, exercitationem soluta placeat voluptatum nostrum beatae tenetur ad deleniti voluptate quia quis officia voluptatem.</span>
<span>At ex velit eligendi ipsam doloribus doloremque laudantium, minus mollitia dicta quis sit nostrum commodi incidunt autem provident vero! Rem distinctio, optio harum deserunt aperiam corporis. Quod maxime eos porro!</span>
<span>Quaerat, quo adipisci voluptas dolores odio maxime maiores obcaecati repellendus ducimus a cupiditate placeat, fugiat nostrum distinctio quidem nemo rem error laborum ipsam eos dicta corrupti. Nobis iure suscipit saepe.</span>
</div>
P.S. you might want to consider a debounce on the resize event (I used a second as debounce delay to make the effect more ovious. You would rather want a debounce delay of 100 milliseconds or the like)
"use strict";
console.clear();
const addWideClass = function() {
Array.from(document.getElementsByTagName('span')).forEach(el => {
const w = el.offsetWidth
el.style.setProperty('--w', `'${w}'`);
if (w < 141) {
el.classList.remove("wide");
} else if (w >= 415) {
el.classList.add("wide");
}
})
};
// From: https://davidwalsh.name/javascript-debounce-function
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
window.addEventListener('resize', debounce(addWideClass, 1000))
addWideClass()
div {
display: flex;
}
div span {
box-sizing: border-box;
padding: 10px;
--w: '213232';
}
div span:nth-child(1) {
flex-grow: 2;
flex-basis: 0;
background-color: gold;
}
div span:nth-child(2) {
flex-grow: 3;
flex-basis: 0;
background-color: silver;
}
div span:nth-child(3) {
flex-grow: 4;
flex-basis: 0;
background-color: goldenrod;
}
div span.wide {
border: 10px solid #000;
}
div span:before {
content: var(--w);
display: block;
}
<div>
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempora similique vitae accusantium repellat nobis architecto unde, exercitationem soluta placeat voluptatum nostrum beatae tenetur ad deleniti voluptate quia quis officia voluptatem.</span>
<span>At ex velit eligendi ipsam doloribus doloremque laudantium, minus mollitia dicta quis sit nostrum commodi incidunt autem provident vero! Rem distinctio, optio harum deserunt aperiam corporis. Quod maxime eos porro!</span>
<span>Quaerat, quo adipisci voluptas dolores odio maxime maiores obcaecati repellendus ducimus a cupiditate placeat, fugiat nostrum distinctio quidem nemo rem error laborum ipsam eos dicta corrupti. Nobis iure suscipit saepe.</span>
</div>

Scrolling to the bottom of a span automatically with javascript

I have a span defined, to which I am occasionally adding text and I am trying to get it to scroll to the bottom of the "box" but without success.
I have the span defined as:
<tr>
<td style="height:130px; border: 1px solid black;">
<div class="scrollable">
<span id="infoWindow"></span>
</div>
</td>
</tr>
With
div.scrollable
{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
And I am adding to it as follows:
document.getElementById("infoWindow").innerHTML+="Just some blurb<hr>";
var objDiv = document.getElementById("infoWindow");
I have tried two different approaches:
objDiv.scrollTop = objDiv.scrollHeight - objDiv.clientHeight;
and
objDiv.scrollTop = objDiv.scrollHeight;
But neither work. What am I doing wrong? Many thanks!
scrollHeight and clientHeight are properties which are calculated when DOM has been fully painted. You should subscribe to event DOMContentLoaded to be sure the calculations are done.
There is a function scrollIntoView which you can use on any element which does exactly the name suggests. MDN - scrollIntoView. You can also define some options for scrolling like smoothness and position where to scroll exactly on element.
Here is an example I wrote to test this.
Keep in mind that scrollIntoView triggered by code example will impact SO scroll behavior.
const paragraphs = ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliter enim nosmet ipsos nosse non possumus. Sin dicit obscurari quaedam nec apparere, quia valde parva sint, nos quoque concedimus; Quis autem de ipso sapiente aliter existimat, quin, etiam cum decreverit esse moriendum, tamen discessu a suis atque ipsa relinquenda luce moveatur? Duo Reges: constructio interrete. Quem enim ardorem studii censetis fuisse in Archimede, qui dum in pulvere quaedam describit attentius, ne patriam quidem captam esse senserit? Id quaeris, inquam, in quo, utrum respondero, verses te huc atque illuc necesse est.',
'Nec vero sum nescius esse utilitatem in historia, non modo voluptatem. Hanc in motu voluptatem -sic enim has suaves et quasi dulces voluptates appellat-interdum ita extenuat, ut M. Hunc ipsum Zenonis aiunt esse finem declarantem illud, quod a te dictum est, convenienter naturae vivere. Suo enim quisque studio maxime ducitur. Manebit ergo amicitia tam diu, quam diu sequetur utilitas, et, si utilitas amicitiam constituet, tollet eadem.',
'Partim cursu et peragratione laetantur, congregatione aliae coetum quodam modo civitatis imitantur; Hic nihil fuit, quod quaereremus. Stoici restant, ei quidem non unam aliquam aut alteram rem a nobis, sed totam ad se nostram philosophiam transtulerunt; Deinde disputat, quod cuiusque generis animantium statui deceat extremum. Tibi hoc incredibile, quod beatissimum. Sed haec ab Antiocho, familiari nostro, dicuntur multo melius et fortius, quam a Stasea dicebantur. Quid enim necesse est, tamquam meretricem in matronarum coetum, sic voluptatem in virtutum concilium adducere? Ne vitationem quidem doloris ipsam per se quisquam in rebus expetendis putavit, nisi etiam evitare posset.'
];
const container = document.getElementById('infoWindow');
const paragraphElements = paragraphs.map((paragraphText, index) => {
const newParagraph = document.createElement('p');
newParagraph.innerHTML = paragraphText;
newParagraph.style.animationDelay = `${.8 * index + 1}s`;
return newParagraph;
});
const demostrateScrolling = () => {
const scroller = document.getElementById('scroller');
const scrollerOptions = {
behavior: 'smooth',
block: "start",
inline: "nearest"
};
scroller.addEventListener('click', () => {
container.querySelector('p:last-child').scrollIntoView(scrollerOptions);
});
paragraphElements.map(p => {
container.appendChild(p);
});
}
document.addEventListener('DOMContentLoaded', demostrateScrolling);
body {
font-family: 'Tahoma';
}
#infoWindow {
height: 200px;
overflow-y: auto;
margin: 10px;
}
#infoWindow p {
padding: 10px;
margin: 10px;
background-color: navy;
color: white;
border-radius: 5px;
animation-name: FadeIn;
animation-duration: .4s;
animation-fill-mode: backwards;
}
#keyframes FadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#scroller {
width: auto;
background-color: lightblue;
border-radius: 24px;
padding: 5px;
margin: 5px;
font-size: 10px;
cursor: pointer;
}
<h2>Scroll To Bottom</h2>
<div id="infoWindow"></div>
<span id="scroller">Scroll to bottom</span>
refer this https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop
scrolling is applicable only to scrollable elements
var i= 0;
while(i<10){
document.getElementById("infoWindow").innerHTML+="Just some blurb<hr>";
i++;
}
//get the total height of your element
var bottomPosition = document.getElementById("infoWindow").offsetHeight;
//set scroll of container element
document.querySelector(".scrollable").scrollTop = bottomPosition;
div.scrollable
{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
/* height is no defined for inline-elements so make span inline-block or block*/
#infoWindow{
display:inline-block;
}
<table>
<tr>
<td style="height:130px; border: 1px solid black;">
<div class="scrollable">
<!-- added style for span element -->
<span id="infoWindow"></span>
</div>
</td>
</tr>
</table>

Is it okay to store an Object on a DOM element in a vanilla JS plugin?

I'm converting jQuery plugins to Vanilla Javascript. I've adopted a Bootstrap-style plugin structure in my example. Once I've instantiated the Accordion object I save it to the dom element so I can later use various methods on the object. Is this an anti-pattern? I would really appreciate any suggestions on how to handle this if it's not correct.
const Accordion = function(element, options){
this.$element = element;
this.target = this.$element.getAttribute('href') || this.$element.dataset.target;
this.$target = document.getElementById(this.target);
this.$header = document.querySelector(`.accordion-header[data-target='${this.target}']`) || document.querySelector(`.accordion-header[href='${this.target}']`);
this.options = {...Accordion.defaults, ...options};
}
Accordion.defaults = {
closeOthers: false
}
Accordion.prototype.open = function(){
this.$header.classList.add('active');
this.$target.classList.add('active');
};
Accordion.prototype.close = function(){
this.$header.classList.remove('active');
this.$target.classList.remove('active');
};
Accordion.prototype.toggle = function(){
if(this.$target.classList.contains('active')){
this.close();
} else {
this.open();
}
};
function Plugin(options){
let accordion = this.Accordion;
if(!accordion){
accordion = new Accordion(this, options);
// Is it okay to store an object on the DOM element?
this.Accordion = accordion;
}
}
const $accordions = [...document.querySelectorAll('[data-toggle="accordion"]')];
const options = {
closeOthers: true
};
/* Call the plugin */
$accordions.forEach($acc => {
Plugin.call($acc, options);
});
$accordions.forEach($acc => {
$acc.addEventListener('click', e => {
e.target.Accordion.toggle();
e.preventDefault();
});
});
const $toggle1 = document.getElementById('toggle1');
const $toggle2 = document.getElementById('toggle2');
const $acc1 = document.getElementById('acc1');
const $acc2 = document.getElementById('acc2');
$toggle1.addEventListener('click', e =>{
$acc1.Accordion.toggle();
});
$toggle2.addEventListener('click', e =>{
$acc2.Accordion.toggle();
});
body {
max-width: 500px;
margin: 0 auto;
padding: 10px;
}
.accordion {
border: 1px solid #ccc;
border-bottom: 0;
margin-bottom: 10px;
}
.accordion-header {
display: block;
padding: 10px;
text-decoration: none;
color: #000;
border-bottom: 1px solid #ccc;
}
.accordion-header.active {
background: #eee;
}
.accordion-body {
padding: 10px;
display: none;
border-bottom: 1px solid #ccc;
}
.accordion-body.active {
display: block;
}
<div class="accordion">
<a id="acc1" href="#1" class="accordion-header" data-toggle="accordion">Header1</a>
<div id="#1" class="accordion-body">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Consequatur aliquid et ipsam cupiditate. Omnis iste quas nostrum aliquid facilis ut natus excepturi deleniti nobis in similique, ex, voluptatibus commodi dolores.
</div>
</div>
<div class="accordion">
<a id="acc2" href="#2" class="accordion-header" data-toggle="accordion">Header2</a>
<div id="#2" class="accordion-body">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Consequatur aliquid et ipsam cupiditate. Omnis iste quas nostrum aliquid facilis ut natus excepturi deleniti nobis in similique, ex, voluptatibus commodi dolores.
</div>
</div>
<button id="toggle1">
Toggle 1
</button>
<button id="toggle2">
Toggle 2
</button>
I wouldn’t worry about it. The only potential problem is name collisions (some other code also tries to assign to element.Accordion and overwrites it). You could also do it with a Map.
var accordions = new Map()
function Accordion ( element ) {
accordions.set( element, this )
}
Accordion.get = element => accordions.get( element )
...
var accordion = Accordion.get( element )

Render only selected element, React JS

I am trying to toggle class in one of my react component.
The idea is to add class when the mouse enter and to remove the class when the mouse leave only in the element only the element in where the user perform the actions. However this is not the case as when the action is being performed all the element with the function are behaving equally.
This is my code so far:
export default class Projects extends Component{
constructor(){
super();
this.state = {
isHovered : false
}
}
//handle mouse enter
handleMouseEnter = () =>{
this.setState({
isHovered : true
});
}
//handle mouse leave
handleMouseLeave = () =>{
this.setState({
isHovered : false
});
}
//render component
render(){
let display = "";
if(this.state.isHovered === true){
display = "active";
}else{
display = "disable";
}
return(
<section className="projects">
{/*section project wrapper*/}
<div className="p-wrapper">
<h1 className="title">Projects</h1>
<hr/>
{/*projet wrapper*/}
<div className="projects-wrapper">
{/*project item wrapper*/}
<div className="project-item" onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>{/*FMA Web development*/}
<div className={"p-description " + display}>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure quos dolorem, ipsa eaque minima saepe fugit hic libero recusandae! Obcaecati esse odit id incidunt vitae aperiam dicta atque blanditiis sint?</p>
</div>
<div className="p-image">
<img src="asset/img/fma_web.png" alt="FMA Web Development"/>
</div>
</div>
<div className="project-item" onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>{/*Web development using php*/}
<div className={"p-description " + display}>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure quos dolorem, ipsa eaque minima saepe fugit hic libero recusandae! Obcaecati esse odit id incidunt vitae aperiam dicta atque blanditiis sint?</p>
</div>
<div className="p-image">
<img src="asset/img/web_dev_php.png" alt="FMA Web Development Using PHP"/>
</div>
</div>
<div className="project-item" onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>{/*Movie Catalog*/}
<div className={"p-description " + display}>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure quos dolorem, ipsa eaque minima saepe fugit hic libero recusandae! Obcaecati esse odit id incidunt vitae aperiam dicta atque blanditiis sint?</p>
</div>
<div className="p-image">
<img src="asset/img/movie_catalog.png" alt="Movie Catalog"/>
</div>
</div>
</div>
</div>
</section>
);
}
}
I have read the use of key in the documentation and read other question especially this one LINK,however when I try to implement I do not get the desired result.
===========================
EDIT
This is what I get now.
As you can see when I hover both of the element triggers.
This is my CSS Code:
/*Projects Start*/
.projects{
width: 100%;
}
.p-wrapper{
margin: 0 auto;
width: 90%;
height: 100%;
}
.projects-wrapper{
margin-top: 2rem;
width: 100%;
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.project-item{
margin: 1rem;
width: 30%;
position: relative;
box-shadow: 2px 3px 37px -5px rgba(0,0,0,0.84);
}
.p-description{
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(43, 40, 40, 0.61);
color: white;
}
.p-description p {
margin: 1rem;
}
.p-title{
margin: 1rem;
}
.active{
display: block;
transition: all 2s ease-in;
}
.disable {
display: none;
}

JQuery "click" not triggering function

I'm trying to trigger a JQuery function when you click on a div (i've tried making it a button as well) to no avail. Google Chrome Inspector does not even recognize an event handler being created behind the scenes.
<!DOCTYPE>
<html>
<head>
<meta charset="UTF-8">;
<script type = "text/javascript" src = "http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
<div id = "main" style = "width: 500px; height: 500px; background-color: black; color: white;">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eius aliquam nobis optio ut ratione a eligendi excepturi cumque est commodi? Sed, odit, culpa deserunt distinctio at commodi modi architecto aliquam.
</div>
<button class = "button" href="#" style = "width: 50px; height: 50px; background-color: black;"></button>
<script type = "text/javacsript">
$(document).ready(function(){
$(".button").click(function(){
$("main").val("IT WORKED");
});
};
</script>
</html>
You forgot to use # for id selector, also use text() or html() instead of val() for div and you also missed the closing parenthesis of document.ready.
Live Demo
$(document).ready(function(){
$(".button").click(function(){
$("#main").text("IT WORKED");
});
});

Categories

Resources