//First function -> Makes a heading float when scrolled past it
if (window.matchMedia('(min-width: 767px)').matches) {
$(function(){
var topBlockheight=$('.site-header').height();
// Check the initial Position of the fixed_nav_container
var stickyHeaderTop = $('.float-h2').offset().top;
var stopFloat = $('#stop-float').offset().top;
$(window).scroll(function(){
if( ( $(window).scrollTop() > stickyHeaderTop-topBlockheight && $(window).scrollTop() < stopFloat-topBlockheight )) {
$('.float-h2').css({position: 'fixed', top: '200px'});
}
else {
$('.float-h2').css({position: 'relative', top: '0px'});
}
});
});
}
// Adds Hover effect for boxes
if (window.matchMedia('(min-width: 767px)').matches) {
$(document).ready(function(){
$(".thumb-cta").mouseover(function(){
max_value=4;
random_value= Math.floor((Math.random() * max_value) + 1);
$(this).attr("data-random",random_value);
});
})
}
These are my two only functions in jQuery from my site which i decided to try to rewrite in vanilla JS. The reason for this decision is because I dont want a 90kb file (jquery main file) to be loaded for 2 basic functions (basic but still can't do them, yes I know).
I've tryed to re write them using http://youmightnotneedjquery.com and https://www.workversatile.com/jquery-to-javascript-converter and i ended up with this code, which does not have any errors in the console, but still does not work :((
let el = document.getElementById("masthead");
let topBlockheight = parseFloat(getComputedStyle(el, null).height.replace("px", ""))
var rect = document.getElementById("float-h2").getBoundingClientRect();
var offset = {
top: rect.top + window.scrollY,
left: rect.left + window.scrollX,
};
var brect = document.getElementById("stop-float").getBoundingClientRect();
var boffset = {
top: rect.top + window.scrollY,
left: rect.left + window.scrollX,
};
window.scroll(function(){
if( ( window.scrollTop() > rect-topBlockheight && window.scrollTop() < stopFloat-topBlockheight )) {
document.getElementById("float-h2").css({position: 'fixed', top: '200px'});
}
else {
document.getElementById("float-h2").css({position: 'relative', top: '0px'});
}
});
Any ideas how I can move on, because I'm really stuck
if (window.matchMedia('(min-width: 767px)').matches) {
//Note: if "site-header" is more than one element remove [0] and create a loop
var topBlockheight=document.getElementsByClassName('site-header')[0].offsetHeight
var stickyHeaderTop = document.getElementsByClassName('float-h2')[0].offsetTop;
var stopFloat = document.getElementById('stop-float').offsetTop;
window.addEventListener("scroll", function(){
if( ( window.scrollY > stickyHeaderTop-topBlockheight && window.scrollY < stopFloat-topBlockheight )) {
document.getElementsByClassName('float-h2')[0].style.position = 'fixed'
document.getElementsByClassName('float-h2')[0].style.top = '200px'
}
else {
document.getElementsByClassName('float-h2')[0].style.position = 'relative'
document.getElementsByClassName('float-h2')[0].style.top = 0
}
});
}
// Adds Hover effect for boxes
if (window.matchMedia('(min-width: 767px)').matches) {
document.onreadystatechange = function(){
if(document.readyState === "interactive") {
document.getElementsByClassName('thumb-cta')[0].addEventListener("mouseover", function(){
max_value=4;
random_value= Math.floor((Math.random() * max_value) + 1);
this.setAttribute("data-random",random_value);
});
}
}
}
$('.element')
or $('tag')
but in Vanillajs to select elements you can use document.getElementsByClassName('elements')
or document.getElementsByTagName('elements')
which return found elements sharing the same className or tagName in an array if you want to select only one element you can write the element index like document.getElementsByClassName('elements')[0]
but if you want to select all elements you will be need to create a loopvar el = document.getElementsByClassName('elements')
for(var i = 0; i < el.length; i++) {
el[i].style.padding = '25px';
el[i].style.background = 'red';
}
and because of id is unque name for the element you don't need to any extra steps you can select it diectly select it like document.getElementById('id')
that was about selecting elements
height()
method which uses get the element height - in Vanillajs js to get the element height you can use offsetHeight
property or getComputedStyle(element, pseudo|null).cssProp
Example
element.offsetHeight
, parseInt(getComputedStyle(element, null).height)
offset()
method which uses to return coordinates of the element this method have 2 properties top
, left
in Vanillajs to get the element offset top you can use offsetTop
propery directly like element.offsetTop
jQuery provides a prototype method like css()
which provide an easy and readable way to styling elements like in normal object propery: value
- in Vanillajs to styling elements you will be need to use style
object like element.style.prop = 'value'
and you will be need to repeat this line every time you add new css property like
el.style.padding = '25px';
el.style.background = 'red';
//and they will repeated as long as you add new property
if you don't want to include jQuery into your project and need to use this method you can define it as prototype method for HTMLElement
, HTMLMediaElement
Example 1: for styling one element
//for html elements
HTMLElement.prototype.css = function(obj) {
for(i in obj) {
this.style[i] = obj[i]
}
}
//for media elements like video, audio
HTMLMediaElement.prototype.css = function(obj) {
for(i in obj) {
this.style[i] = obj[i]
}
}
//Usage
var el = document.getElementsByClassName('elements')[0]
el.css({
'padding': '25px',
'background-color':
})
if you wants to add this style for multiple elements you can define it as prototype method for Array
Example 2: for multiple elements
Array.prototype.css = function(obj) {
for(i = 0; i < this.length; i++) {
if (this[i] instanceof HTMLElement) {
for(r in obj) {
this[i].style[r] = obj[r]
}
}
}
}
//Usage
var el1 = document.getElementsByClassName('elements')[0]
var el2 = document.getElementsByClassName('elements')[1]
[el1, el2].css({
'background-color': 'red',
padding: '25px'
})
jQuery allow you to add events directly when selecting element like $('.element').click(callback)
but in Vanillajs you can add events with addEventListener()
or onevent
proprty like document.getElementById('id').addEventListener('click', callback)
, document.getElementById('id').onclick = callback
$(document).ready(callback)
this method uses to make your code start working after loading the libraries, other things it's useful to give the lib enough time to loaded to avoid errors - in Vanilla js you can use onreadystatechange
event and document.readyState
protpety which have 3 values loading
, interactive
, complete
Example
document.onreadystatechange = function () {
if (document.readyState === 'interactive') {
//your code here
}
}
parseFloat(getComputedStyle(el, null).height.replace("px", ""))
you don't need to replace any thing because parseInt()
, parseFloat
will ignore itelement.css()
id don't know how you don't get any errors in the console when this method is undefined you will be need to define it as above to make it workscroll
event is not defined you will be need to use window.onscroll = callback
like example above