How to make sticky header change link colour on scroll? - javascript

Looking for a way to change link colour in JavaScript within a specific ID on scroll.
That's my CSS.
#header_nav {
transition: 0.4s;
position: fixed;
top: 0;
height: 130px;
}
#main-logo {
transition: 0.4s;
height: 52px;
width: 169.92px;
}
#main-nav a{
color: #f3f5f6;
transition: 0.4s;
}
And here is the JavaScript
function scrollFunction() {
if (document.body.scrollTop > 0 || document.documentElement.scrollTop > 0) {
document.getElementById("header_nav").style.height = "70px";
document.getElementById("main-logo").style.width = "118.944px";
document.getElementById("main-logo").style.height = "36.4px";
document.getElementById("main-logo").style.filter = "invert(0)";
document.getElementById("header_nav").style.backgroundColor = "#F1F1F3";
document.getElementById("logo").style.fontSize = "25px";
document.getElementById("main-nav a").style.color = "#223732";
} else {
document.getElementById("header_nav").style.height = "130px";
document.getElementById("header_nav").style.backgroundColor = "transparent";
document.getElementById("main-logo").style.filter = "invert(1)";
document.getElementById("main-logo").style.width = "169.92px";
document.getElementById("main-logo").style.height = "52px";
document.getElementById("logo").style.fontSize = "35px";
document.querySelectorAll(".main-nav a").style.color = "#f3f5f6";
}
}
You can see where I have the code that doesn't work:
document.getElementById("main-nav a").style.color = "#223732";
Is there a way I can select just the link in javascript D from that id as I have it in CSS?

You can first select the main-nav by id and then it's children by tag name, something like:
var mainNav = document.getElementById("main-nav");
mainNav.getElementsByTagName("a")[0].style.color = "#223732";
Not that getElementsByTagName() returns an array with all elements of that tag.

Related

In Chrome extension Manifest v3, how do i instruct manifest.json to run my extension only on certain webpages without using activeTab permission?

Whenever i hover over my ext icon, i get the tooltip "Wants access to this site" which is wrong because it should want access only on youtube.com/watch?v=* (and it's another story that Manifest 'match' refuses to accept https://www.youtube.com/watch?v=* as a valid URL)
This is what i'm currently doing:
// manifest.json
{
"name": "YouTube Overlay",
"version": "0.1",
"manifest_version" : 3,
"description": "Lays overlay on YouTube, can be used for guitar chords/lyrics.",
"background" : {
"service_worker" : "bg.js"
},
"action": {},
"permissions": ["activeTab", "scripting"],
"web_accessible_resources": [{
"resources": ["funcsTBInsertedIntoDOM.js"],
"matches": ["https://www.youtube.com/*"]
}]
}
// bg.js
chrome.action.onClicked.addListener(function (tab) {
chrome.scripting.executeScript({
target: {tabId: tab.id},
files: ['yt.js'],
});
});
yt.js when executed above, injects a bunch of HTML elems & CSS rules into DOM. It also injects funcsTBInsertedIntoDOM.js (specified in web_accessible_resources in the manifest.json above) into DOM, which contains function definitions for the injected HTML buttons.
So basically whenever the user clicks on my ext icon, bg.js executes, which in turn executes yt.js. When the user clicks while on a YouTube video, it works fine. But otherwise it throws errors in the console naturally. So how do i instruct the manifest to execute bg.js ONLY on YouTube videos? (it shouldn't even run on other YouTube pages, just only when user is on a video page).
Also, i got a rejection notice from Google Web Store for my extension:
Violation(s):
Use of Permissions:
Violation reference ID: Purple Potassium
Violation: Requesting but not using the following permission(s):
activeTab
How to rectify: Remove the above permission(s)
But if i remove activeTab permission, my extension doesn't work at all.
If someone could propose a solution with both of these problems in mind, i'd be very grateful. Thank you for reading.
Adding additional code to help make it easier:
This is yt.ts:
// all global variables are 'var' instead of let or const because the delete command works only on var
var isFullScreen = false;
var extensionActivated = false;
var resCheckerID:number;
var chordsTALeftPaddingNonFS = chordsTALeftPaddingNonFSOnExit;
var chordsTALeftPaddingFS = "0px";
var thisIsThe1stExitAfterFS = true;
var activateExtension = () => {
console.log("YouTube Overlay activated.");
let scriptElemForASBtn = document.createElement("style");
let innardsForASBtn = styleForAsBtn;
scriptElemForASBtn.innerHTML = innardsForASBtn;
document.head.appendChild(scriptElemForASBtn);
const videoElem = document.querySelector("video");
const vidBottomPanel = document.querySelector(".ytp-chrome-bottom");
const progBarPadding = document.querySelector(".ytp-progress-bar-padding");
const getIdealChordsDivStyles = (isFullScreen:boolean) => {
let vidDims = videoElem.getBoundingClientRect();
let progBarPaddingDims = progBarPadding.getBoundingClientRect();
if (isFullScreen){
console.log("fullscreen detected")
thisIsThe1stExitAfterFS = true;
chordsTALeftPaddingNonFS = chordsTA.style.paddingLeft; // saving this for next nonFS
chordsTA.style.paddingLeft = chordsTALeftPaddingFS; // assigning this from prev FS
return `overflow: hidden; position: absolute; z-index: 1111; width: 100vw; height: ${progBarPaddingDims.y - vidDims.y + (progBarPaddingDims.height/2)}px`;
} else {
try {
if(thisIsThe1stExitAfterFS)
chordsTALeftPaddingFS = chordsTA.style.paddingLeft;
chordsTA.style.paddingLeft = chordsTALeftPaddingNonFS;
thisIsThe1stExitAfterFS = false;
} catch {} // saving this for next FS. on first run it obsly won't be able to find chordsTA.
return `overflow: hidden; position: absolute; z-index: 1111; left: ${vidDims.x}px; top: ${vidDims.y}px; width: ${vidDims.width}px; height: ${progBarPaddingDims.y - vidDims.y + (progBarPaddingDims.height/2)}px`;
}
}
// creating the chords div
let chordsDiv = document.createElement('div');
chordsDiv.style.cssText = getIdealChordsDivStyles(isFullScreen);
chordsDiv.setAttribute("id", "chordsDiv");
let htmlInnards = `
<div id="chordsCtrls" onmouseover="unhideChordsCtrls();" onmouseout="hideChordsCtrls();" style="z-index: 1112; height: ${vidBottomPanel.getBoundingClientRect().height}px; position: absolute; display: inline-block;">
<a id="asBtn" onclick="toggleAutoScroll()" class="btn-flip" data-back="Turn on" data-front="Auto-Scroll Off"></a>
<a id="decTxtSize" class="btn noselect" onclick="decTxtSize();">Tᵀ</a>
<a id="incTxtSize" class="btn noselect" onclick="incTxtSize();">ᵀT</a>
<a id="decIndent" class="btn noselect" onclick="decIndent();">¶-</a>
<a id="incIndent" class="btn noselect" onclick="incIndent();">¶+</a>
</div>
<textarea onkeyup="checkTAWidth();" onclick="checkTAWidth();" id="chordsTA" spellcheck="false" style="position:absolute; left:50%; transform: translate(-50%,0); white-space: pre; overflow-wrap: normal; overflow-x: scroll; font-family: Roboto Mono,monospace; background-color: rgba(0, 0, 0, 0.35); color: white; height: 100%; min-width:10vw; font-size: ${window.screen.height*0.026}px;" placeholder="\n\nPaste\nyour\nchords/lyrics\nin\nhere!">
`
chordsDiv.innerHTML = htmlInnards;
document.body.appendChild(chordsDiv);
chordsTA.value = lyricsOnExit; // doing in convoluted way because i cant fig it out :S
if (chordsTA.value === "undefined") chordsTA.value = "";
chordsTA.scrollTop = lyricsLocOnExit;
chordsTA.style.fontSize = lyricsSizeOnExit;
chordsTA.style.paddingLeft = chordsTALeftPaddingNonFS;
console.log("Lyrics reinstated, if any.");
// hiding the scrollbar of chords div & textarea
let styleForScrollbarHiding = `#chordsDiv::-webkit-scrollbar, #chordsTA::-webkit-scrollbar {height: 0; width: 0;}`;
let styleSheet = document.createElement("style");
styleSheet.type = "text/css";
styleSheet.innerText = styleForScrollbarHiding;
document.head.appendChild(styleSheet);
// auto sizing of chords div
function resCheck() {
let vidDims = videoElem.getBoundingClientRect();
let chordsDims = chordsDiv.getBoundingClientRect();
let requisiteHtForChordsDiv = vidDims.height - vidBottomPanel.getBoundingClientRect().height- (progBarPadding.getBoundingClientRect().height/2);
if (((chordsDims.x !== vidDims.x || chordsDims.width !== vidDims.width) && chordsDims.x !== 0) || (chordsDims.x === 0 && chordsDims.x !== vidDims.x)) { // base cond's latter gets True when exiting from FS. Base's former's former checks in non fullScn mode if x or width is wrong.
if (isFullScreen && vidDims.y === 0) return;
console.log("Video dimensions changed detected, redrawing overlay.");
isFullScreen = vidDims.y === 0 ? true : false;
chordsDiv.style.cssText = getIdealChordsDivStyles(isFullScreen);
}
}
resCheckerID = setInterval(resCheck, 2000);
// addding my JS functions to the youtube HTML webpage/DOM
let s = document.createElement('script');
// TODO: add "scriptName.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('funcsTBInsertedIntoDOM.js');
(document.head || document.documentElement).appendChild(s);
}
var styleForAsBtn = `
#asBtn {
opacity: 1;
outline: 0;
color: #FFFFFF;
line-height: 40px;
position: relative;
text-align: center;
letter-spacing: 1px;
display: inline-block;
text-decoration: none;
text-transform: uppercase;
font-size: small;
font-weight: bold;
}
#asBtn:hover:after {
opacity: 1;
transform: translateY(0) rotateX(0);
}
#asBtn:hover:before {
opacity: 0;
transform: translateY(50%) rotateX(90deg);
}
#asBtn:after {
top: 0;
left: 0;
opacity: 0;
width: 100%;
color: #000000;
background: #BCBCBC;
display: block;
transition: 0.25s;
position: absolute;
content: attr(data-back);
transform: translateY(-50%) rotateX(90deg);
}
#asBtn:before {
top: 0;
left: 0;
opacity: 1;
color: #FFFFFF;
background: #323237;
display: block;
padding: 0 5px;
line-height: 40px;
transition: 0.25s;
position: relative;
content: attr(data-front);
transform: translateY(0) rotateX(0);
}
/* CSS for other buttons */
.btn{
display: inline-block;
color: #FFFFFF;
width: 40px;
height: 40px;
line-height: 40px;
border-radius: 50%;
text-align: center;
vertical-align: middle;
overflow: hidden;
font-weight: bold;
background-image: -webkit-linear-gradient(#666666 0%, #323237 100%);
background-image: linear-gradient(#666666 0%, #323237 100%);
text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.66);
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.28);
font-size: x-large;
cursor: pointer;
}
.btn:active{
color: #000000;
}
.btn:hover {
text-align: center;
opacity: 1;
background-image: -webkit-linear-gradient(#999999 0%, #323237 100%);
background-image: linear-gradient(#999999 0%, #323237 100%);
}
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome, Edge, Opera and Firefox */
}
#incTxtSize, #decTxtSize{
font-size: large;
}
#chordsCtrls>*{
transition: transform 0.1s linear;
}
textarea::placeholder {
color: white;
opacity: 0.8;
font-size: 4vh;
}
#contentContainer.tp-yt-app-drawer[swipe-open].tp-yt-app-drawer::after{
visibility: hidden;
}
`
// the last css property above is hiding a thin left side vertical area which otherwise causes chordsCtrls not to show up if mouse is on extreme left. Also causes difficulty clicking SpeedDn button.
if (!document.querySelector("#chordsDiv")){
activateExtension();
} else {
console.log("YouTube Overlay deactivated");
var lyricsOnExit = chordsTA.value;
var lyricsLocOnExit = chordsTA.scrollTop;
var lyricsSizeOnExit = chordsTA.style.fontSize;
var chordsTALeftPaddingNonFSOnExit = chordsTA.style.paddingLeft; // won't be possible to save FS padding unless i deactivate extension with an X btn. Due to scope prob.
document.querySelector("#chordsDiv").remove();
clearInterval(resCheckerID);
delete window.resCheckerID;
}
This is funcsTBInsertedIntoDOM.ts:
console.log("Loading essential funcs needed for YouTube Overlay extension.")
clearInterval(asIntervalID); // cannot clear this from yt.ts because yt.ts runs in a sandbox. So need to clear it here, if it exists, on startup. Thankfully doesn't throw error even if doesn't exist.
clearTimeout(hideChordsCtrlsTimeoutID);
var asSpeeds = {1: 250, 2: 150, 3: 100, 4: 90, 5: 75, 6: 60, 7: 50, 8: 40, 9: 30};
var chordsCtrls:HTMLDivElement = document.querySelector("#chordsCtrls");
var chordsTA:HTMLTextAreaElement = document.querySelector("#chordsTA");
var asBtn:HTMLButtonElement = document.querySelector("#asBtn");
var autoScrollSpeed = 250;
var asIntervalID = 0;
function toggleAutoScroll() {
if(asIntervalID){
clearInterval(asIntervalID);
asIntervalID = 0;
console.log("Stopped autoscroll.");
document.querySelector("#speedUp").remove(); document.querySelector("#speedDn").remove();
setAttributes(asBtn, {"data-front": `Auto-Scroll Off`, 'data-back': 'Turn On'});
return;
}
// create speed + - buttons
let speedUp = document.createElement("a");
speedUp.textContent = "+";
setAttributes(speedUp, {'id': 'speedUp', 'class': 'btn noselect', 'onclick': 'speedUpAS();'});
document.querySelector("#chordsCtrls").insertBefore(speedUp,document.querySelector("#decTxtSize"));
let speedDn = document.createElement("a");
speedDn.textContent = "-";
setAttributes(speedDn, {'id': 'speedDn', 'class': 'btn noselect', 'onclick': 'speedDnAS();'});
document.querySelector("#chordsCtrls").insertBefore(speedDn,asBtn);;
setAttributes(asBtn, {"data-front": `Speed: ${getKeyByValue(asSpeeds,autoScrollSpeed)}`, 'data-back': 'Turn Off'});
asIntervalID = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
console.log("Started autoscroll.")
}
var speedUpAS = () => {
console.log("Speeding up autoscroll")
let asBtnText = asBtn.getAttribute('data-front');
let newSpeed:number = parseInt(asBtnText.charAt(asBtnText.length - 1))+1;
if (newSpeed in asSpeeds){
clearInterval(asIntervalID);
autoScrollSpeed = asSpeeds[newSpeed];
asIntervalID = 0;
asBtn.setAttribute('data-front', `Speed: ${getKeyByValue(asSpeeds, autoScrollSpeed)}`);
asIntervalID = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
}
}
var speedDnAS = () => {
console.log("Speeding down autoscroll")
let asBtnText = asBtn.getAttribute('data-front');
let newSpeed:number = parseInt(asBtnText.charAt(asBtnText.length - 1))-1;
if (newSpeed in asSpeeds){
clearInterval(asIntervalID);
autoScrollSpeed = asSpeeds[newSpeed];
asIntervalID = 0;
asBtn.setAttribute('data-front', `Speed: ${getKeyByValue(asSpeeds, autoScrollSpeed)}`);
asIntervalID = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
}
}
var incTxtSize = () => {
let currFontSize = parseFloat(chordsTA.style.fontSize);
let newFontSize = currFontSize += 1;
chordsTA.style.fontSize = `${newFontSize}px`;
qickSizeUp();
}
var decTxtSize = () => {
let currFontSize = parseFloat(chordsTA.style.fontSize);
let newFontSize = currFontSize -= 1;
chordsTA.style.fontSize = `${newFontSize}px`;
qickSizeDn();
}
var unhideChordsCtrls = () => {
clearTimeout(hideChordsCtrlsTimeoutID);
let childrenOfchordsCtrlsDiv:any = chordsCtrls.getElementsByTagName("*");
for (let index = 0; index < childrenOfchordsCtrlsDiv.length; index++) {
childrenOfchordsCtrlsDiv[index].style.transform = "translate(0,0)";
}
}
var hideChordsCtrlsTimeoutID = 0;
var hideChordsCtrls = () => {
hideChordsCtrlsTimeoutID = setTimeout(() => {
let childrenOfchordsCtrlsDiv:any = chordsCtrls.getElementsByTagName("*");
for (let index = 0; index < childrenOfchordsCtrlsDiv.length; index++) {
childrenOfchordsCtrlsDiv[index].style.transform = "translate(0,-100%)";
}
}, 2000);
}
hideChordsCtrlsTimeoutID = setTimeout(() => { //hide the controls after initially showing them for 4 secs
hideChordsCtrls();
}, 4000);
var decIndent = () => {
let newLeftPadding = (parseInt(chordsTA.style.paddingLeft) - 50);
if (!newLeftPadding) newLeftPadding = 0; // this catches NaN on first run, as it is not set. Also doesn't allow to go less than 0 somehow, luckily.
chordsTA.style.paddingLeft = `${newLeftPadding}px`;
}
var incIndent = () => {
let newLeftPadding = (parseInt(chordsTA.style.paddingLeft) + 50);
if (!newLeftPadding) newLeftPadding = 50; // this catches NaN on first run, as it is not set.
if (newLeftPadding > document.querySelector("#chordsDiv").getBoundingClientRect().width) return;
chordsTA.style.paddingLeft = `${newLeftPadding}px`;
}
// following funcs stolen from SO for finding a key by its value & setting attributes multiple at a time.
function getKeyByValue(object:object, value:Number) {
return Object.keys(object).find(key => object[key] === value);
}
function setAttributes(el:HTMLElement, attrs:object) {
for(var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
Or you may prefer to read the code over at GitHub: https://github.com/XtremePwnership/YoutubeOverlay
Since YouTube video pages are hosted at youtube.com/watch, specifying that in your manifest is the way to go:
{
"name": "YouTube Overlay",
"version": "0.1",
"manifest_version" : 3,
"description": "Lays overlay on YouTube, can be used for guitar chords/lyrics.",
"background" : {
"service_worker" : "bg.js"
},
"action": {},
"permissions": ["activeTab", "scripting"],
"web_accessible_resources": [{
"resources": ["funcsTBInsertedIntoDOM.js"],
"matches": ["https://www.youtube.com/watch?v=*"]
}]
}

How to link two if statements

I am learning JS and have created a carousel with a caption underneath.
How do I get the Prev/Next buttons to affect the caption as well as the image? I've tried combining the if statements in several ways but have failed miserably.
Relevant HTML:
<span id="prev" class="arrow">❮</span>
<div class="karussell" id="karussell">
<img class="karu" name="esislaid">
</div>
<span id="next" class="arrow">❯</span>
<div class="caption">
<h3 id="esikiri"></h3>
</div>
JS:
var p = 0;
var s = 0;
var esileht = [];
var aeg = 5000;
var kiri = [];
//Image List
esileht[0] = 'img/tooted/raamat/graafvanalinn2016.jpg';
esileht[1] = 'img/tooted/kaart/kaart_taskus_esipool.jpg';
esileht[2] = 'img/tooted/kaart/graafkaart_esikylg.jpg';
//Captions
kiri[0] = 'Raamat "Tallinn. Graafiline vanalinn"';
kiri[1] = 'Tallinna vanalinna graafiline kaart (suur formaat)';
kiri[2] = 'Tallinna vanalinna graafiline kaart (väike formaat)';
// Left and Right arrows
//Eelmine
function eelmine(){
if (p === 0){
p = esileht.length;
}
p = p - 1;
return esileht[p];
}
//Jargmine
function jargmine(){
p = p + 1;
p = p % esileht.length;
return esileht[p];
}
document.getElementById('prev').addEventListener('click', function (e){
document.querySelector('#karussell img').src = eelmine();
}
);
document.getElementById('next').addEventListener('click', function (e) {
document.querySelector('#karussell img').src = jargmine();
}
);
//Change Image
function changePilt (){
document.esislaid.src = esileht[p];
if(p < esileht.length -1){
p++;
} else {
p = 0;
}
setTimeout("changePilt()", aeg);
}
//Change Caption
function changeKiri(){
document.getElementById('esikiri').innerHTML = kiri[s];
if(s < kiri.length - 1){
s++;
}
else {
s = 0;
}
setTimeout('changeKiri()', aeg);
}
document.body.onload = function(){
changePilt();
changeKiri();
};
CSS, just in case:
.karussell {
position: relative;
width: 100%;
max-height: 600px;
overflow: hidden;
}
.arrow {
cursor: pointer;
position: absolute;
top: 40%;
width: auto;
color: #00A7E0;
padding: 16px;
font-weight: bold;
font-size: 18px;
border-radius: 3px;
transition: 0.6s ease;
}
#next {
right: 0;
}
#prev {
left: 0;
}
.arrow:hover {
background-color: rgba(0,0,0,0.8);
}
.caption {
text-align: center;
color: #00A7E0;
padding: 2px 16px;
}
.karu {
max-width: 75%;
animation-name: fade;
animation-duration: 2s;
}
#keyframes fade {
from {opacity: 0.4}
to {opacity: 1}
}
#media (max-width:767px){.karu{max-width: 95%;}}
I made a fiddle to try to illustrate (had to paste the js into the html tab to gt it to work for some reason): Fiddle
Really you just need to use the .innerHTML() feature and do exactly what you already have. Either create a eelmine2() function (or something like that) and call it again, grabbing the content from kiri[] or instead just return the p and use it in two places:
document.getElementById('prev').addEventListener('click', function (e){
document.querySelector('#karussell img').src = eelmine();
document.querySelector('#esikiri').innerHTML = eelmine2();
});
function eelmine2(){
if (p === 0){
p = kiri.length;
}
p = p - 1;
return kiri[p];
}
or
document.getElementById('prev').addEventListener('click', function (e){
var change = eelmine();
document.querySelector('#karussell img').src = esileht[change];
document.querySelector('#esikiri').innerHTML = kiri[change];
});
function eelmine(){
if (p === 0){
p = kiri.length;
}
p = p - 1;
return p;
}
This assumes your code is using the same global vars inside public functions that you have set up in your Fiddle. You should fix that to have variables passed into the functions before going live with all of this, but I'm not addressing that any further here.

Javascript only add a class to an element on an interval after it's come into viewport

I have a series of images I want to transition from 0 opacity to 1 opacity when they come into the view port. I have the viewport check part done and the adding classes, however I would like them to be on an interval, so once the first 3 images come into the view port they appear 1, 2, 3 every .5seconds or so. Instead of all 3 at the same time.
here's a JS fiddle of how it works currently
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
reveal[i].classList.add("fade");
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
https://jsfiddle.net/u04sy7jb/
I've modified your code to add a transition-delay of an additional .5 seconds for each element after the first one, in each "group" that is revealed as you scroll. I left comments in the JavaScript so you can understand the changes.
Let me know if you have any questions!
Live demo:
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
// start a new count each time user scrolls
count = 0;
for (var i = 0; i < reveal.length; i++) {
// also check here if the element has already been faded in
if (checkVisible(reveal[i]) && !reveal[i].classList.contains("fade")) {
// add .5 seconds to the transition for each
// additional element currently being revealed
reveal[i].style.transitionDelay = count * 500 + "ms";
reveal[i].classList.add("fade");
// increment count
count++;
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
.container {
width: 100%;
height: 1200px;
background-color: orange;
}
.reveal {
display: inline-block;
width: 32%;
margin: 0 auto;
height: 400px;
background-color: pink;
border: 1px solid black;
opacity: 0;
}
.fade {
opacity: 1;
transition: 1s;
}
<div class="container">
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
</div>
You could be able to stick your reveal[i].classList.add("fade"); inside of a setTimeout that executes as a function of your ith element so they show up how you're describing. Here is an example of adding short function to add the class and using it in a setTimeout to make this happen, although you could change it up to meet any additional needs.
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
addMyFadeClass(reveal[i], i)
}
}
}
};
function addMyFadeClass(element, i) {
setTimeout(function() {
element.classList.add("fade");
}, i * 500)
}
You can also use :nth-child CSS selectors without the need to change the JS:
.reveal:nth-child(3n+1).fade {
opacity: 1;
transition: 1s;
}
.reveal:nth-child(3n+2).fade {
opacity: 1;
transition: 1.5s;
}
.reveal:nth-child(3n).fade {
opacity: 1;
transition: 2s;
}
JSFiddle: https://jsfiddle.net/u04sy7jb/8/

start a transition event after loaded a image

I have a problem doing a transition, the div that contains the image should be going from "right: 200px;" to "400px" making the transition in 2s and the transition should start when the image is loaded in the document, here is the css code:
div.contenedor {
width: 300px;
height: 257px;
position: fixed;
right: 200px;
bottom: 0px;
z-index: 100;
-webkit-transition: right 2s;
-moz-transition: right 2s;
transition: right 2s;
}
and here the js code:
function transi() {
var id = "L" + Math.floor(Math.random() * 10000);
function open() {
var eOpen = document.getElementById(id + "_container");
eOpen.style.right = "400px";
};
var dContenedor = document.createElement("div");
dContenedor.id = id + "_container";
dContenedor.className = "contenedor";
var ima = document.createElement("img");
ima.src = "XXXX.jpg";
ima.width = "300";
ima.height = "250";
dContenedor.appendChild(ima);
document.onreadystatechange = function(){
var rsw = this.readyState;
console.log(rsw);
if (rsw) if (rsw != 'complete') if (rsw != 'loaded') {return;}
document.body.appendChild(dContenedor);
console.log(ima.complete);
if (ima.complete) {
open();
};
}
};
transi();
For some reason is not making the transition, and the div is going direct to "400px", if someone have some ideas i would apreciate it, thank you in avance
Maybe call function on load event of image?
UPD
Added work example
function transi() {
var id = "L" + Math.floor(Math.random() * 10000);
var dContenedor = document.createElement("div");
dContenedor.id = id + "_container";
dContenedor.className = "contenedor";
function open() {
// we already have ref to needed element
dContenedor.style.right = "400px";
};
var ima = document.createElement("img");
ima.width = "300";
ima.height = "250";
dContenedor.appendChild(ima);
document.body.appendChild(dContenedor);
// when image is loaded fire event
ima.onload = function() {
open();
}
ima.src = "https://v1.std3.ru/32/9b/1455811008-329b55c554efcec3988dc8ab44eb972f.jpeg";
};
transi();
div.contenedor {
width: 300px;
height: 257px;
position: fixed;
right: 200px;
bottom: 0px;
z-index: 100;
-webkit-transition: right 2s;
-moz-transition: right 2s;
transition: right 2s;
background: #333;
}

CodePen Content Slider

I am trying to create something similar.
http://codepen.io/eka0210/pen/rjalx
Does anyone know what kind of jQuery plugin has been used in it.
It seems pretty straight forward and I can't seem to figure it out. Right now I'm using this for plugin
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
and the given js code in addition to that.
My problem is that I can't seem to make it animate to the other page.
Thanks for the response.
The animation is done via css translate , and little script controls behaviour during animation that is all , no plugins are used !
css:
html {
overflow-y: hidden;
}
html, body, #wrapper {
height: 100%;
width: 100%;
margin: 0;
}
nav {
position: fixed;
z-index: 100;
}
.main-container {
position: relative;
width: 100%;
height: 100%;
}
#wrapper {
position: absolute;
top: 0;
-webkit-transition: -webkit-transform 1.5s cubic-bezier(.8,0,.2,1);
}
.slide0 {-webkit-transform: translateY(0%);}
.slide1 {-webkit-transform: translateY(-100%);}
.slide2 {-webkit-transform: translateY(-200%);}
.slide3 {-webkit-transform: translateY(-300%);}
.slide4 {-webkit-transform: translateY(-400%);}
JS:
var slider = $('.slider'),
wrapper = $('#wrapper'),
animating = false,
current = 0,
lengthDiv = slider.length,
delay = 1500;
slider.on('click', function(e){
var anchor = $(this);
if(!animating){
animating = true;
current = anchor.parent().index();
wrapper.removeClass().addClass('slide'+current);
setTimeout(function(){
animating = false;
}, delay);
e.preventDefault();
}
});
$(document).keydown(function(e){var key = e.keyCode;if(key == 38 || key == 40)e.preventDefault();});
$(document).keyup(function(e){
if(!animating){
var key = e.keyCode;
if(key == 38 && current > 0){
$(slider[current - 1]).trigger('click');
}else if(key == 40 && current < lengthDiv - 1){
$(slider[current + 1]).trigger('click');
}
}
});
$(document).mousewheel(function(e, deltaY){
if(!animating){
if(deltaY > 0 && current > 0){
$(slider[current - 1]).trigger('click');
}else if(deltaY < 0 && current < lengthDiv - 1){
$(slider[current + 1]).trigger('click');
}
}
return false;
});

Categories

Resources