How to lazy load html div tags using intersection-observer? - javascript

Is it possible to lazy-load the entire div-tag using Intersection Observer API?
I have lazy loaded images using the intersection observer api approach. Not sure how to do it for html elements.

Yes, you can lazy load content into divs. The example below simply uses html() to populate the div with a random string on intersect. If the content you want is a separate html page, you could use load() instead.
function lazyDivs() {
let lis = [].slice.call(document.querySelectorAll("div.lazy")),
items = ["Aruba", "Jamaica", "Bermuda", "Bahama", "Key Largo", "Montego"];
if (!lis.length) {
//do nothing
} else if ("IntersectionObserver" in window) {
let o = new IntersectionObserver(function(es, obs) {
es.forEach(function(e) {
if (e.isIntersecting) {
let li = $(e.target);
li.html(items[Math.floor(Math.random() * items.length)]);
//li.load('/path/to/html/fragment'); //option to load content from a separate page
li.removeClass("lazy");
o.unobserve(e.target);
}
});
});
lis.forEach(function(li) {
o.observe(li);
});
} else {
lis.forEach(function(li) {
let l = $(li);
l.html(items[Math.floor(Math.random() * items.length)]);
//l.load('/path/to/html/fragment'); //option to load content from a separate page
l.removeClass("lazy");
});
}
}
$(document).ready(function() {
lazyDivs();
});
div {
border: 1px solid blue;
width: 100px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
margin: 10px auto;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="lazy"></div>
<div class="lazy"></div>
<div class="lazy"></div>
<div class="lazy"></div>
<div class="lazy"></div>
<div class="lazy"></div>
<div class="lazy"></div>
<div class="lazy"></div>
<div class="lazy"></div>
</body>
</html>

Related

After adding a non-case sensitive search and clickable pictures, script stopped working

Trying to make my first project with bunch of pictures, with a filter/search bar at the top that would filter the pictures depending on the input. For example if the input would be "Aatrox", it would show "Aatrox" and not "Jayce" and or "Senna" and so on. Script was working fine, I added a .toLowerCase() so its not case sensitive and then I added to the pictures so they are clickable and each lead to their own page. After adding these two the search bar stopped working.
Here is the snippet of the script
<script>
function search(){
var searchText = (document.getElementById("searchInput").value).toLowerCase();
var images = document.querySelectorAll(".image_container > img");
if(searchText.length > 0){
images.forEach((image) => {
image.classList.add("hide");
if((image.dataset.tags).toLowerCase().indexOf(searchText) > -1){
image.classList.remove("hide");
}
});
}else{
images.forEach((image) => {
image.classList.remove("hide");
});
}
}
</script>
Here is the HTML part
<head>
<title> Counterpicks </title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1> Counterpicks pro debily </h1>
<div class="container">
<div class="searchbox_container">
<div class="searchbox">
<input type="text" name=" " placeholder="Search" class="search" id="searchInput" onkeyup="search()">
</div>
</div>
<div class="image_container">
<img data-tags="aatrox" src="aatrox.webp" alt="Aatrox" class="actionimages">
<img data-tags="ahri" src="ahri.webp" alt="Ahri" class="actionimages">
</div>
I input only few of the lines because they are just repeating for 130 lines.
And here is the CSS
.container {
background: rgba(0,0,0,0);
text-align: center;
margin-left: 20%;
margin-right: 20%;
}
.searchbox {
text-align: center;
margin-left: 20%;
margin-right: 20%;
margin-bottom: 20px;
}
.image_container {
clear:both;
}
.hide {
display:none;
This is my first project with JavaScript so I will be happy for any constructive criticism.
Replace:
var images = document.querySelectorAll(".image_container > img");
with:
var images = document.querySelectorAll(".image_container > a > img");

detect if cursor is inside a link and get its href attribute

inside a contenteditable div need to detect if a cursor is inside a <a></a> range
if so in console I need href attribute
in the example below - if the cursor is on google console should be https://google.com/
any help, using jquery or plain js
document.onselectionchange = () => {
var selection = window.getSelection();
var parent = selection.parentNode;
console.log(parent); // why undefined
// if(parent is a link){console.log(parent.attr('href'));}
};
.ed{width:50%; margin:0 auto; height:100vh; padding:9px; background:orange;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='ed' id='ed' contenteditable>
<div>lorem</div>
<div><a href='https://google.com/'>google</a></div>
</div>
And BTW parent is JS reserved word.
https://www.w3schools.com/js/js_reserved.asp
document.querySelectorAll('#ed a').forEach(link => {
link.addEventListener("mouseover", function(event) {
console.log(event.target.href)
});
})
.ed {
width: 50%;
margin: 0 auto;
height: 100vh;
padding: 9px;
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='ed' id='ed' contenteditable>
<div>lorem</div>
<div><a href='https://google.com/'>google</a></div>
<div><a href='https://test.com/'>test.com</a></div>
</div>
If you want to check the href attr only on focusing the cursor on the text instead of mouse over you can make use of focusNode and instance type on selection.
.ed{width:50%; margin:0 auto; height:100vh; padding:9px; background:orange;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='ed' id='ed' contenteditable>
<div>lorem</div>
<div><a href='https://google.com/'>google</a></div>
</div>
document.onselectionchange = () => {
var selection = window.getSelection();
var parentElement = selection.focusNode.parentElement;
if(parentElement instanceof HTMLAnchorElement){
console.log(parent.href);
}
};

How to blur the whole body except a list item?

I wanted to create an effect where the whole body gets blurred or dimmed and only a particular list item appears clear. However when I set the z-index to the list item, it doesn't work. And when I set the z-index of the whole un-ordered list, it works but the all the list items appear clear (which I don't want).
Let me show you my html code:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ashish Toppo</title>
<link href="https://fonts.googleapis.com/css?family=Oxanium&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
</head>
<body >
<!-- the html for the top bar starts here -->
<div class="top_bar" id="topBar">
<div class="logo_name" id="logoName">Ashish Toppo</div>
<ul class="menu">
<li class="menu_items currently_active_menuItem" id="home">home</li>
<li class="menu_items" id="about">about</li>
<li class="menu_items" id="education">education</li>
</ul>
</div>
<!-- the html for the top bar ends here -->
<!-- the html for the intro starts here -->
<div class="intro" id="intro">
<div class="profile_pic" id="profilePic">
<img id="profileImg" src="images/ashish-toppo-green.jpg" width="100%" height="100%" alt="a picture of mine">
</div>
<div class="intro_box" id="introBox">
<!-- some introduction text here -->
<center id="aboutPointer">To know more about me, go to the about section!</center>
</div>
</div>
<!-- the html for the intro ends here -->
<script src="js/uiversal.js"></script>
<script src="js/index.js"></script>
</body>
</html>
Now, the Universal javaScript file:
/* this is a reusable js file universal to all web pages */
/* Ashish Toppo */
"use strict";
function get(id_or_class){
var obj = {
element: ( document.getElementById(id_or_class) ) ? document.getElementById(id_or_class) :
( document.getElementsByClassName(id_or_class) ) ? document.getElementsByClassName(id_or_class) :
( document.querySelector(id_or_class) ) ? document.querySelector(id_or_class) :
console.error("The provided HTML element could not be found"),
html: () => { return obj.element; },
changeText: (text) => { obj.html().innerHTML = text; },
appendText: (text) => {
let appendOn = obj.html().innerHTML;
obj.html().innerHTML = appendOn + text;
},
previousDisplayMode: "block",
hide: () => {
obj.previousDisplayMode = obj.html().style.display;
obj.html().style.display = "none";
},
show: () => {
obj.html().style.display = obj.previousDisplayMode;
},
on: (event, callBack) => {
obj.html().addEventListener(event, callBack);
},
previousZIndex: 1,
focusOn: () => {
let blur = document.createElement("div");
blur.className = "theDivThatBlurs";
blur.style.width ="100vw";
blur.style.height ="100vh";
blur.style.display ="block";
blur.style.position ="fixed";
blur.style.top ="0";
blur.style.left ="0";
blur.style.zIndex ="9";
blur.style.backgroundColor ="rgba(0, 0, 0, 0.9)";
blur.innerHTML = "";
document.body.appendChild(blur);
obj.html().style.zIndex = "100";
}
}
return obj;
}
and the index.js file was as followed:
/* my css wasn't working as i wanted, so i had to fix it using js */
"use strict";
(function(d){
const active = d.getElementsByClassName("currently_active_menuItem");
active[0].style.textDecoration = "none";
})(document);
var about = get("about");
var aboutPointer = get("aboutPointer");
aboutPointer.on("click", function(){
console.log("the about pointer has been clicked");
focus(about);
});
function focus(theElement){
console.log("the focus is working");
theElement.focusOn();
}
You can use the box-shadow property to achieve the dimming effect. Quick and easy :)
Just toggle a class programmatically and it should work for any element you have.
Code
function focusAndDim() {
document.getElementById("maindiv").classList.toggle("visible");
// if you want to get more fancy ;)
document.getElementsByTagName("body")[0].classList.toggle("blur");
}
.visible {
box-shadow: 0 0 0 10000px #ccc;
/* this code below make everything else hidden */
/* box-shadow: 0 0 0 10000px #fff; */
position: relative;
}
.btn {
height: 20px;
line-height: 1.4;
border: 2px solid #999;
padding: 12px 24px;
margin-bottom: 10px;
border-radius: 2px;
cursor: pointer;
}
body {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
height: 100vh;
}
body.blur div {
filter: blur(2px);
}
body.blur div.visible {
filter: blur(0);
}
<div class="btn" onclick="focusAndDim()" id="maindiv">Click Me</div>
<div>Other elements</div>

Highlighting Elements on Scroll (jquery)

I have 3 divs on the page and I want them to change the color if they are scrolling. For example, all divs are blue, if they scroll to the first diva, change to green, change to green to the second diva, but the first will be blue again. I do not know how to go about it. I count on your help and tips. Maybe you've seen a similar example somewhere :)
According to your div color change dynamicaly bellow is the code
<!DOCTYPE HTML>
<html>
<head>
<style>
.divblue {
width: 100%;
height: 400px;
background-color: blue;
color: white;
}
.divgreen {
width: 100%;
height: 400px;
background-color: green;
color: white;
}
</style>
</head >
<body>
<div id="maindiv" style="width:100%;height:300px;overflow-y:scroll;">
<div id="fstdiv" class="divblue">
Hi test for first div
</div>
<div id="snddiv" class="divblue">
Hello test for second div
</div>
<div id="thrdiv" class="divblue">
Sir test for Third div
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$('#maindiv').scroll(function () {
var hT = $('#fstdiv').outerHeight();
var hH = $('#snddiv').outerHeight();
var tH = $('#thrdiv').outerHeight();
var wS = $(this).scrollTop();
$('#fstdiv').removeClass('divgreen').addClass('divblue');
$('#snddiv').removeClass('divgreen').addClass('divblue');
$('#thrdiv').removeClass('divgreen').addClass('divblue');
if (wS < 100) {
$('#fstdiv').removeClass('divblue').addClass('divgreen');
}
else if (wS > 400 && wS < 700) {
$('#snddiv').removeClass('divblue').addClass('divgreen');
}
else {
$('#thrdiv').removeClass('divblue').addClass('divgreen');
}
});
});
</script>
</body>
</html >

On div scroll activate another div's scroll

Jsfiddle
I trying to activate my current scroll while I am outside that scroll, specifically in #DivDet
here is what I tried:
$("div#DivDet").scroll(function () {
// I don't know what i should have here
// something like $("div#scrlDiv").scroll();
});
It sounds like you want to respond to a scroll on one div by scrolling another.
You've already determined how to hook the scroll event. To set the scroll position of an element (the other div), you set the element's scrollTop and scrollLeft values (which are in pixels). If you want two divs to scroll in near-unison, for instance, you'd assign the source div's scrollTop and scrollLeft to the target div.
Example: Live Copy | Source
Relevant JavaScript:
(function() {
var target = $("#target");
$("#source").scroll(function() {
target.prop("scrollTop", this.scrollTop)
.prop("scrollLeft", this.scrollLeft);
});
})();
or alternately (source):
(function() {
var target = $("#target")[0]; // <== Getting raw element
$("#source").scroll(function() {
target.scrollTop = this.scrollTop;
target.scrollLeft = this.scrollLeft;
});
})();
Full page:
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset=utf-8 />
<title>Scroll Example</title>
<style>
.scroll-example {
display: inline-block;
width: 40%;
border: 1px solid black;
margin-right: 20px;
height: 100px;
overflow: scroll;
}
</style>
</head>
<body>
<p>Scroll the left div, watch the right one.</p>
<div id="source" class="scroll-example">
1
<br>2
<br>3
<br>4
<br>5
<br>6
<br>7
<br>8
<br>9
<br>10
<br>11
<br>12
<br>13
<br>14
<br>15
<br>16
<br>17
<br>18
<br>19
<br>20
</div>
<div id="target" class="scroll-example">
1
<br>2
<br>3
<br>4
<br>5
<br>6
<br>7
<br>8
<br>9
<br>10
<br>11
<br>12
<br>13
<br>14
<br>15
<br>16
<br>17
<br>18
<br>19
<br>20
</div>
<script>
(function() {
var target = $("#target");
$("#source").scroll(function() {
target.prop("scrollTop", this.scrollTop)
.prop("scrollLeft", this.scrollLeft);
});
})();
</script>
</body>
</html>
Solution with Vanilla JavaScript
const multiElementScroll = ( elem1, elem2 ) => {
elem1.onscroll = function() {
elem2.scrollTop = this.scrollTop;
};
}
multiElementScroll( div1, div2 )
section {
display: flex;
justify-content: space-between;
}
.scroll-box {
width: 200px;
height: 200px;
overflow-y: scroll;
border: 1px solid #d99;
}
.scroll-box h2 { margin-top: 50px; }
<section>
<div class="scroll-box" id="div1">
<h1>A</h1>
<h2>B</h2>
<h2>C</h2>
<h2>D</h2>
<h2>E</h2>
<h2>F</h2>
<h2>G</h2>
<h2>H</h2>
</div>
<div class="scroll-box" id="div2">
<h1>1</h1>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
<h2>5</h2>
</div>
<section>

Categories