Making a webapp, I need a loading div in between pages - javascript

I'm looking everywhere, but I cant find how to do it!
I have a webapp, and one page is very heavy with data and it takes a long time to load. Is it possible to make a loading div appear when its loading the next page? Maybe like this;
Make a loading div, set style to visiblilty: hidden
When a user click a link, the div is set to visibilty: visible
Starts loading the data of the next page
When data loads, the page is shown.

Like I said, this is just a basic version of what you are looking for.
http://jsfiddle.net/sheriffderek/CbF9M/
HTML (just some stuff)
<img src="http://placehold.it/500x500" alt="">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Autem amet earum sapiente aspernatur optio aliquid officia veritatis quaerat eaque ex fugiat maiores iure! Fugit deserunt enim cumque eum veniam eius.</p>
<div class="cover"></div>
CSS
.cover {
position: fixed;
top: 0; right: 0;
bottom: 0; left: 0;
width: 100%;
height: 100%;
background-color: red;
}
jQuery
$(window).ready( function() {
$(".cover").delay(3000).fadeOut();
});
So, when the window is loaded... fade out the covering div... but really - you would want to be much more specific about what is loaded. The delay is just for effect, because we don't have any real data being transferred.

Related

Toggle text inserted with innerHTML from Javascript

As an exercise I am trying to create a small quiz app and a part of it are the question cards. On these cards I have a question and then a button to show the answer. When the button is clicked, then the answer (which doesn't exist in the HTML DOM yet, therefore not visible) will show up and with the next click, the answer should be hidden again. Basically it will look something like this:
Before Show Answer is clicked
After Show Answer is clicked
Here is the HTML code:
<section class="question-card">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsam vitae
labore repudiandae tenetur. Qui maiores animi quibusdam voluptatum
nobis. Nam aperiam voluptatum dolorem quia minima assumenda velit libero
saepe repellat. Tempore delectus deleniti libero aliquid rem velit illum
expedita nostrum quam optio maiores officiis consequatur ea, sint enim
cum repudiandae inventore ab nemo?
</p>
<div class="bookmark">
<i class="fa-regular fa-bookmark fa-lg"></i>
</div>
<button class="answer-button" data-js="answer-button">Show Answer</button>
<ul class="answer-container" data-js="answer-container">
</ul>
<div class="container-categories">
<button class="category-button category-html">#html</button>
<button class="category-button category-flexbox">#flexbox</button>
<button class="category-button category-css">#css</button>
<button class="category-button category-js">#js</button>
</div>
</section>
I have added an EventListener for the Show Answer button that adds a list item in the already existing ul when it is clicked. I have done this with innerHTML:
const answerButton = document.querySelector(".answer-button");
const answerContainer = document.querySelector(".answer-container");
const answer1 = "Lorem ipsum dolor sit amet consectetur adipisicing elit.";
answerButton.addEventListener("click", () => {
answerContainer.innerHTML = `<li class="show-answer">${answer1}</li>`;
});
Now what I can't seem to manage is to hide the answer when the button is clicked again (the next challenge will be that the button will change the text to "Hide Answer" after the first click, but I have no idea how to approach that yet). The closest I got was this:
answerButton.addEventListener("click", () => {
answerContainer.innerHTML = `<li class="show-answer">${answer1}</li>`;
answerContainer.classList.toggle("hide-answer");
});
However, this method displays the .hide-answer class first, after which the 2 classes are toggled and everything is as it should be. So after the first click, the answer is still hidden and only after the 2nd click the button behaves the way I want it to.
I have tried this as well:
answerButton.addEventListener("click", () => {
answerContainer.innerHTML = `<li class="hide-answer">${answer1}</li>`;
answerContainer.classList.toggle("show-answer");
});
But for some reason this shows the container with all the CSS properties, but there is no text:
Answer Container is there, but no text
This is the CSS for the 2 classes (show-answer and hide-answer):
.show-answer {
background-color: hotpink;
border-radius: 7px;
border: none;
list-style: none;
width: 50%;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px;
}
.hide-answer {
display: none;
}
If anybody has any idea how I could get the result I need, I would be extremely grateful...
You're mixing up the answer-container with the answer-container's child (the innerHtml <li> element).
initially there's a visible, but empty <ul class="answer-container"></ul>.
Next on click of the button, you add the content into the answer-container expecting it to be visible with a show-answer class
Immediately after, you add the hide-answer class to the <ul class="answer-container"> parent element which hides the newly added content.
Click the button again and you finally see your answer because the container element has the hide-answer class toggled off. From here it works as you're expecting.
You can fix this by having the answer-container be hidden initially and then continue to toggle the display of the container. You can also just use a DOM element's hidden attribute to do this as I do in this code snippet below where I've taken your exact example and just modified the answer-container to start with hidden and toggle the hidden attribute on click. You can do the same thing w/ a CSS display: none class too.
const answerButton = document.querySelector(".answer-button");
const answerContainer = document.querySelector(".answer-container");
const answer1 = "Lorem ipsum dolor sit amet consectetur adipisicing elit.";
answerButton.addEventListener("click", () => {
answerContainer.innerHTML = `<li class="answer">${answer1}</li>`;
answerContainer.hidden = !answerContainer.hidden;
});
.answer {
background-color: hotpink;
border-radius: 7px;
border: none;
list-style: none;
width: 50%;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<section class="question-card">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsam vitae
labore repudiandae tenetur. Qui maiores animi quibusdam voluptatum
nobis. Nam aperiam voluptatum dolorem quia minima assumenda velit libero
saepe repellat. Tempore delectus deleniti libero aliquid rem velit illum
expedita nostrum quam optio maiores officiis consequatur ea, sint enim
cum repudiandae inventore ab nemo?
</p>
<div class="bookmark">
<i class="fa-regular fa-bookmark fa-lg"></i>
</div>
<button class="answer-button" data-js="answer-button">Show Answer</button>
<ul class="answer-container" hidden data-js="answer-container">
</ul>
<div class="container-categories">
<button class="category-button category-html">#html</button>
<button class="category-button category-flexbox">#flexbox</button>
<button class="category-button category-css">#css</button>
<button class="category-button category-js">#js</button>
</div>
</section>
Would something like this work?
You just use if the container has the class show-answer to determine if the answer needs to be shown or hidden
answerButton.addEventListener("click", () => {
if (answerContainer.classList.contains('show-answer')) {
// container has `showing` class
// hide the answer
answerContainer.innerHTML = ``; // ? - my guess, not sure how to want to hide it
}else{
// container doesn't have `showing` class
// show the answer
answerContainer.innerHTML = `<li class="hide-answer">${answer1}</li>`;
};
// update class
answerContainer.classList.toggle("show-answer");
});

Spacing between long amount of text lines css/html/js

Let's say that i have lots of text that i dont want to be in one single huge line, how could i put some white spacings after a certain amount of words? And should i do this in the CSS file or somewhere else?
So for example: this: "You have succesfully looted the house, as the house was empty you didnt run into any trouble." to: "You have succesfully looted the house, as the house was empty you
didnt run into any trouble."
Might not look as great on this site but i think you will get the idea. The string is empty at first and will be filled by some action that happens on the page.
Specify a width on the container where your text is inside. It is better to use the max-width property since your text may be smaller than the maximal width you want. In this case it is not essential though, since the paragraph is a block element and is full width.
p {
border: 1px solid lightcoral;
}
.ch-wrap {
max-width: 60ch;
}
.px-wrap {
max-width: 200px;
}
<h1>This has no width set</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam, doloremque nihil. Illo, veritatis est ipsa cumque culpa praesentium dolor error.</p>
<h1>This has a width of 60 characters</h1>
<p class="ch-wrap">Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam, doloremque nihil. Illo, veritatis est ipsa cumque culpa praesentium dolor error.</p>
<h1>This has a width of 200px set</h1>
<p class="px-wrap">Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam, doloremque nihil. Illo, veritatis est ipsa cumque culpa praesentium dolor error.</p>
You can use <br> tag to write in a new line. If you want to put white spaces you have to move the text via CSS. For example:
HTML:
<font id="moving">Some text</font>
CSS: #moving { float: right; }
but if it not works you can try with:
#moving { position: absolute !important; float: right; }
The !important attribute makes sure that the position tag will be set on absolute.

Scroll up after click a href in page

I have a footnote system. When I click sup number it scroll down to footnote. But It didn't show because of sticky header.
I need to scroll up around 60px after href scrolling.
I tried to add window.scrollBy(0, 60); in onclick of "sup a" object. It didn't work when I add it as function as well.
Full code:
$(document).ready(function() {
// make a link out of any <sup> with class .footnoted
$('sup').each(function(i){
var superscript = i+1;
$(this).html('<a>' + superscript + '</a>');
});
// give <sup class="footnoted"> an id to scroll back to
$('sup').each(function(i){
this.id = "reading-position-"+(i+1);
});
// tell the superscripts where to go
$('sup a').each(function(i){
this.href = "#footnote-"+(i+1);
});
// set a target for the superscripts to scroll to
// if you're not using a list for your footnotes, change li to the correct selector
$('ol li').each(function(i){
this.id = "footnote-"+(i+1);
});
// add return to reading position link at the end of the footnote
$('ol li').append('<a rel="nofoot"> ↑ Okuma Alanına Geri Dön</a>');
// give the return to position url an href of the target ID
$('ol li a').each(function(i){
this.href = "#reading-position-"+(i+1);
});
// make a back to top link at the end of your footnotes
// if you're not using a list for your footnotes, change li to the correct selector
// smooth scroll between reading position and footnotes
$('sup a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top - 60
}, 500, 'swing', function () {
window.location.hash = target;
});
// remove class and link to previous reading position from other <li> if you scrolled to a footnote previously
{#$('.current-footnote span').remove();#}
{#$('ol li').removeClass('current-footnote');#}
// add return to reading position link and give the current footnote a class for additional styles
$(target).addClass('current-footnote');
$('.current-footnote span').css('display', 'inline');
});
scrollBy(0, 60) scrolls down, not up. You need to use negative numbers to reverse the direction. So, window.scrollBy(0, -60).
If that still doesn't work, something is probably wrong with how you're registering the click handler. It would be useful if you could show your full code.
You can create references using the DATA attribute.
Example link: <span class="reference" data="#one">ONE</span>
This script will collect all elements with class class="reference" and add a listener to them. When the element is clicked, the script will take the DATA information which is the ID of the element to which the page should be scrolled.
In this line you can change the value 60 so that the information remains in the visible part
window.scrollTo(0, top - 60);
In this example, 60px is the height of the sticky navigation
var navLinks = document.querySelectorAll('.reference');
for (let i = 0; i < navLinks.length; i++) {
navLinks[i].addEventListener("click", function () {
var elId = this.getAttribute('data');
var top = document.querySelector(elId).offsetTop;
window.scrollTo(0, top - 60);
});
}
body {
margin: 0px;
}
nav {
height: 60px;
background: orangered;
position: fixed;
width: 100%;
top: 0px;
}
.reference {
cursor: pointer;
color: orangered;
}
#wrap {
margin-top: 60px;
}
<nav>Navigation...</nav>
<div id="wrap">
<div>
Lorem ipsum dolor, <span class="reference" data="#one">ONE</span> sit amet consectetur adipisicing elit. Cum nihil vero voluptatibus tempora repellendus <span class="reference" data="#two">TWO</span> aperiam quidem debitis, totam consequuntur ex aspernatur quasi quod molestias rem quibusdam? Facilis adipisci asperiores iste. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Cum nihil vero voluptatibus tempora repellendus aperiam quidem debitis, totam consequuntur ex aspernatur quasi quod molestias rem quibusdam? Facilis adipisci asperiores iste. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Cum nihil vero voluptatibus tempora repellendus aperiam quidem debitis, totam consequuntur ex aspernatur quasi quod molestias rem quibusdam? Facilis adipisci asperiores iste.
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
<p id="one">
ONE - Reference One
<br><br><br><br><br><br><br><br><br><br><br>
</p>
<p id="two">
TWO - Reference Two
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</p>
</div>

How to create auto popup when I access a website

I was trying to create an auto popup when I access a web store that is developed in Shopif
<SCRIPT TYPE="text/javascript">
function popup(mylink, windowname) {
if (! window.focus)return true;
var href;
if (typeof(mylink) == 'string') href=mylink;
else href=mylink.href;
window.open(href, windowname, 'width=400,height=200,scrollbars=yes');
return false;
}
</SCRIPT>
<BODY onLoad="popup('autopopup.html', 'ad')">
I have the above code for Popup Windows Opening Automatically. However, I need assistance on how to make this work on and this is the website that I am trying to work it on https://petit-tapis.co.uk
Thank you in Advance
As #Scopey said, modern browsers prevent this behavior from auto occurring. You can however add a click or if you want people to take action first before doing anything else, you can for example add an overlay that blocks any other functionality (but I can tell you that this kills user experience).
Maybe say more what your goal is. Why do you want this extra window to open? What benefit is there in doing this (what do you and what does the user get out of it)?
edit: See my comment below. I also slapped together a very simple version of what I am talking about: https://jsfiddle.net/uthhvu8d/
HTML:
<div class="wrapper">
<div class="overlay">
<form action="">
<input type="text">
<input type="text">
<button>Submit</button>
</form>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maxime, inventore esse aliquam nostrum? Cupiditate provident, delectus, minus voluptatum natus fugiat.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minus temporibus vitae quibusdam maxime natus fugiat quis amet sed perferendis quod.</p>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam nostrum consequatur animi quod rem eos nihil obcaecati repellat. At, accusamus.</p>
</div>
CSS:
.wrapper {
position: relative;
}
.overlay {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
color: #fff;
display: none;
}
JS:
function showOverlay() {
$('.overlay').show()
}
setTimeout(showOverlay, 2000)
Thankfully, modern browsers prevent this behaviour from happening.
Any window.open must occur only as a direct result of a user triggered event - such as a mouse click or similar.
As #Scopey said browsers stop you opening a pop up window however you could use the HTML5 Dialog and the dialog overlays in the browser have a play you can even open it model if you wanted will take a little longer to get it to work but it's anotion for you
<dialog id="dialog">
<iframe src="autopopup.html" />
</dialog>

Show one or more elements and their content that have been hidden

I'm stuck and not sure how to move on. I want to be able to click a tab to reveal its content. With the code I currently have, when I click a single tab, it reveals the content for all the tabs. But I just want the click to reveal the content that's associated with that single tab. I'm looking for a vanilla javascript solution.
Here's the code: http://codepen.io/anon/pen/KCJAc (inline below)
CSS:
.tab-content {
display: block;
height: 0;
opacity: 0;
overflow: hidden;
transition: all 1s ease-out;
}
.tab-active {
height: auto;
opacity: 1;
}
JavaScript:
var tabHeaders = document.getElementsByClassName('tab-header');
for (var i = 0; i < tabHeaders.length; i++) {
tabHeaders[i].addEventListener('click', activateTab);
}
function activateTab() {
var tabContents = document.getElementsByClassName('tab-content');
for (var i = 0; i < tabContents.length; i++) {
tabContents[i].classList.add('tab-active');
}
}
HTML:
<div>
<h3 class="tab-header">Tab1</h3>
<p class="tab-content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium odio iste aliquam molestias corporis blanditiis nihil soluta sint illum quibusdam reprehenderit sed quaerat iusto maiores error iure ducimus dicta ipsum.</p>
</div>
<div>
<h3 class="tab-header">Tab2</h3>
<p class="tab-content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium odio iste aliquam molestias corporis blanditiis nihil soluta sint illum quibusdam reprehenderit sed quaerat iusto maiores error iure ducimus dicta ipsum.</p>
</div>
You're adding tab-active to all of the tab-content elements. You just want to add it to the one following the header that's clicked: Updated Pen
var tabHeaders = document.getElementsByClassName('tab-header');
for (var i = 0; i < tabHeaders.length; i++) {
tabHeaders[i].addEventListener('click', activateTab);
}
function activateTab() {
var tabContents = this.nextElementSibling;
while (tabContents && (!tabContents.classList || !tabContents.classList.contains("tab-content"))) {
tabContents = tabContents.nextElementSibling;
}
if (tabContents) {
tabContents.classList.toggle("tab-active");
}
}
Notes:
I'm using nextElementSibling to get the next sibling that's an element since you used classList in the original, so I figure you're only using this code on fairly up-to-date browsers. If you intend to use it on older browsers, you can use nextSibling instead (and also use className rather than classList.
This is because by using document.getElementsByClassName you are getting all tab-content tabs in your page, rather than the DOM level of the clicked tab-header element. You can use the nextSibling property of tab-header to get the next DOM node beside tab-header:
function activateTab() {
this.nextSibling.classList.add("tab-active");
}
Or, if you are not sure if tab-content will definitely appear directly after tab-header you can query parentNode using querySelector:
function activateTab() {
this.parentNode.querySelector(".tab-content").classList.add("tab-active");
}
Note this last method won't work in anything lower than IE8, but then again neither will the classList property in your original question.

Categories

Resources