Lightning Components & window.addEventListener() - javascript

I am attempting to detect when a device changes it's orientation and update my component to reflect the new orientation.
The problem with my approach is that my event lives outside of the components life-cycle which in turn makes the component variable is undefined thus rendering the code inside the event absolutely useless.
Anyone that has some insight into what I could do to achieve this would great.
afterRender: function(component,helper){
this.superAfterRender();
window.addEventListener("orientationchange", function() {
window.setTimeout(function(){
if(window.innerWidth <= 768) {
component.set('v.deviceWidth','small');
} else if(window.innerWidth > 768 && window.innerWidth < 1440) {
component.set('v.deviceWidth','medium');
} else if(window.innerWidth >= 1440) {
component.set('v.deviceWidth','large');
}
},500);
});
}

Good solution for you:
https://github.com/ReactiveX/RxJS
Example here: https://golosay.net/rxjs-subjects/
Just create subject, and:
const sub = new Rx.Subject();
window.addEventListener("orientationchange", function() {
sub.next(window.innerWidth)
});
In component:
sub.subscribe((value)=>{
if(value <= 768) {
c.set('v.deviceWidth','small');
} else if(value > 768 && value < 1440) {
c.set('v.deviceWidth','medium');
} else if(value >= 1440) {
c.set('v.deviceWidth','large');
}
})
And don't forget unsubscribe when component will be destroy;

Related

How do I make auto fontSize in Javascript?

I was trying to use the same function of fontSize() in mobile view to make it responsive but I don't know to do it. This is what I'm using in window view
document.getElementById('hakdog').onload = function () {func()};
function func() {
var str = document.getElementById("voter").innerHTML;
var a = str.length;
if(a >= 40) {
voter.style.fontSize = "18px";
} else if(a >=30) {
voter.style.fontSize = "22px";
} else {
voter.style.fontSize = "27px";
}
}
Is there any same function for mobile view? I only know some function but I know its not responsive
$(document).ready(function(){
if($(window).width() < 480) {
$('h1').css('font-size','10px');
$('h2').css('font-size','8px');
$('h3').css('font-size','6px');
$('h4').css('font-size','4px');
}
});
EDIT
I was trying to make it responsive using java just like on the first code I given, normal .css is not gonna work since its only going to give for h1, h2, h3, etc. I was pointing out that I wanted to make the responsive if the full name reached 40 letters then the fontSize would be 18px same with other functions given
EDIT 5:30pm MARCH 29
This is what I tried so far but didn't work as what I expected.
document.getElementById('hakdog').onload = function () {func()};
function func() {
$(document).ready(function() {
function resizes() {
if($(window).width() < 480) {
var str = document.getElementById("voter").innerHTML;
var a = str.length;
if(a >= 40) {
voter.style.fontSize = "9px";
} else if(a >=30) {
voter.style.fontSize = "10px";
} else {
voter.style.fontSize = "15px";
}
}
}
resizes();
$(window).resize(resizes);
})
}
Edit: Made changes to include the font size based on the length of the content.
This should work. You can check this out on the full page in the below code snippet.
$(document).ready(function() {
function resizeMe() {
if ($(window).width() < 480) {
if ($("#name").text().length < 5) {
$('h1').css('font-size', '46px');
} else {
$('h1').css('font-size', '10px');
}
$('h2').css('font-size', '8px');
$('h3').css('font-size', '6px');
$('h4').css('font-size', '4px');
} else {
$('h1').css('font-size', '20px');
$('h2').css('font-size', '18px');
$('h3').css('font-size', '16px');
$('h4').css('font-size', '14px');
}
}
resizeMe();
$(window).resize(resizeMe);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 id="name">Helo</h1>
<h2>Yes</h2>
<h3>Nooooooooooooooooooooooooooo</h3>
<h4>okkkkkk</h4>
Do you try to change 'px' to 'rem', 'rem' resize in relation to the size of the screen.
This is what i meant for auto sizing for every device
var wid = $(window).width();
if(wid < 320) {
var str = document.getElementById("voter").innerHTML
var a = str.length;
if(a >= 40) {
voter.style.fontSize = "9px";
} else if(a >= 25) {
voter.style.fontSize = "11px";
} else {
voter.style.fontSize = "15px";
}
}
Thanks for everyone commented out!

Issue with checking if item is in DOM and the executing the javascript function

I'm making a webpage that has two different navbars... Lets say I named them navbar1 and navbar2.. soo the navbar1 is being used on the home page of the web site and navbar2 on all other sub pages... I have written a pure Javascript function that checks if the navbar1 exists in DOM and if it does then it does something... if navbar1 doesent exist in DOM it should ignore that part of code and move forward with the rest...
so now I have this issue that I spent several hours now trying to resolve... and I just can figure it out... When I go to the home page the code works... everything that should happen to navbar1 happens... but if I go to a subpage that doesn't use navbar1 I get this error in the console: "Cannot read properties of null (reading 'getBoundingClientRect')"
I would apreciate some help... and if it matters I don't have much experience with javascript so :)
So here's my JS code...
function docReady(fn) {
if (document.readyState === "complete" || document.readyState === "interactive") {
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
docReady(function() {
var className = "scroll";
var scrollTrigger = 60;
var navTogler = document.getElementById('navbar-toggler');
var navbar1 = document.getElementById('navbar1');
var isInViewport = function (elem) {
var bounding = elem.getBoundingClientRect();
return (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
);
};
if (isInViewport(navbar1)) {
navTogler.addEventListener('click', classToggle);
function classToggle() {
navbar1.classList.toggle('has-bg');
if (navbar1.classList.contains('has-bg')) {
document.getElementsByClassName("logo")[0].src="./assets/images/Logo_blue.svg";
document.getElementsByClassName("search")[0].src="./assets/images/search-blue.svg";
}
if (navbar1.classList.contains('scroll') && navbar1.classList.contains('has-bg')) {
document.getElementsByClassName("logo")[0].src="./assets/images/Logo_blue.svg";
document.getElementsByClassName("search")[0].src="./assets/images/search-blue.svg";
}
if (!navbar1.classList.contains('scroll') && !navbar1.classList.contains('has-bg')) {
document.getElementsByClassName("logo")[0].src="./assets/images/Logo_White.svg";
document.getElementsByClassName("search")[0].src="./assets/images/search.svg";
}
else {
// console.log("something");
}
}
window.onscroll = function() {
if (window.scrollY >= scrollTrigger || window.pageYOffset >= scrollTrigger) {
document.getElementById("navbar1").classList.add(className);
document.getElementsByClassName("logo")[0].src="./assets/images/Logo_blue.svg";
document.getElementsByClassName("search")[0].src="./assets/images/search-blue.svg";
}
else {
document.getElementById("navbar1").classList.remove(className);
document.getElementsByClassName("logo")[0].src="./assets/images/Logo_White.svg";
document.getElementsByClassName("search")[0].src="./assets/images/search.svg";
}
};
}
var swiper = new Swiper(".mySwiper", {
slidesPerView: 3,
grid: {
rows: 2,
},
spaceBetween: 30,
pagination: {
el: ".swiper-pagination",
clickable: true,
},
});
console.log("hello swiper");
});
isInViewport() should return false if the element doesn't exist.
var isInViewport = function (elem) {
if (!elem) {
return false;
}
var bounding = elem.getBoundingClientRect();
return (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
);
};

How to control the interval of time between triggering of mousewheel event

I'm currently writing a website for a movie making company, which shows their different movies in full-screen.
I put each video in a list, and wrote a function that takes the user to the next video everytime a mousewheel event is triggered. The problem is that when the user is mousewheeling with a trackpad, it triggers multiple events at once, so I figured, I just had to set an interval between each triggering, depending on a variable "animating" that would be either true or false.
So here's my code :
let animating = false
$(window).bind('mousewheel', function (event) {
if (event.originalEvent.wheelDelta >= 0 && actuallyPlaying === false && animating === false) {
animating = true;
goToPreviousVideo();
setInterval(function () {
animating = false
}, 2000)
}
else {
if (actuallyPlaying === false && animating === false) {
animating = true;
goToNextVideo();
setInterval(function () {
animating = false
}, 2000)
};
}
});
And this piece of code works fine, but only for a few video "swipes". I noticed that after two or three times, this function stops working, and many events get triggered at the same time, which results in skipping all the videos and going from the top of the page straight to the bottom.
Do you guys have any idea why this isn't working ?
I'm also adding the code of goToNextVideo() and goToPreviousVideo() in case the problem is with them :
let i = 1 //
const goToNextVideo = function () {
if (i === 4) { // because I've got 4 videos
return;
} else {
$('html, body').animate({
scrollTop: $(`.video-${i + 1}`).offset().top
}, 500);
$(`.video-${i + 1}`).get(0).play();
i += 1
$(`.video-${i - 1}`).get(0).pause();
}
};
const goToPreviousVideo = function () {
if (i === 1) {
return
} else {
$('html, body').animate({
scrollTop: $(`.video-${i - 1}`).offset().top
}, 500);
$(`.video-${i}`).get(0).pause();
i -= 1
$(`.video-${i}`).get(0).play();
}
};
Thanks for your help !
Wish you all a great day
its seems your error is coming from the fact you dont clear the setInterval,
let animating = -1;
$(window).bind('mousewheel', function (event) {
if (event.originalEvent.wheelDelta >= 0 && actuallyPlaying === false && animating < 0) {
animating = setInterval(function () {
clearInterval(animating);
animating = -1;
}, 2000)
goToPreviousVideo();
}
else {
if (actuallyPlaying === false && animating < 0) {
animating = setInterval(function () {
clearInterval(animating);
animating = -1;
}, 2000)
goToNextVideo();
}
}
});
I am not able to understand where the problem is lying but
I have a cleaner and better approach to doing this Please tell if it works
var lastVideoChangeAnimation = Date.now()-2001;
$(window).bind('mousewheel', function (event) {
if (event.originalEvent.wheelDelta >= 0 && actuallyPlaying === false && Date.now()-lastAlertTime>2000) {
lastVideoChangeAnimation = Date.now();
goToPreviousVideo();
}
else if (actuallyPlaying === false && Date.now()-lastAlertTime>2000) {
lastVideoChangeAnimation = Date.now();
goToNextVideo();
};
});
THERE CAN ALSO BE A PROBLEM THAT THERE OCCURS SOME SORT OF ERROR AND YOUR CODE STOPS EXECUTING.
SO JUST CHECK IF THE CONSOLE IS GIVING SOME ERROR WITH POINTING TOWARDS THE FILE WHERE THESE TWO CODES ARE SAVED.
Also please tell in the comment that did it worked

Getting my function to re-execute whenever the browser window screen size is adjusted

I'm trying to make my simple javascript function (no jQuery) log a message to the console when the browser is resized to over or under 890px. This code works on load, but only states the starting width when the page is loaded:
if (window.innerWidth < 890) {
console.log('Less than 890px');
} else {
console.log('890px or more');
}
But my code below using a window event doesn't work:
if (window.attachEvent) {
window.attachEvent('onresize', function() {
if (window.innerWidth < 890) {
console.log('Less than 890px');
} else {
console.log('890px or more');
}
})};
Can someone explain what I'm doing wrong here? I'm relatively new to javascript. Thanks for any help here.
window.addEventListener('resize', () => {
if (window.innerWidth < 890) {
console.log('Less than 890px');
} else {
console.log('890px or more');
}
});
try this
if(window.attachEvent) {
window.attachEvent('onresize', function() {
if (window.innerWidth < 890) {
console.log('Less than 890px');
} else {
console.log('890px or more');
}
});
}
else if(window.addEventListener) {
window.addEventListener('resize', function() {
if (window.innerWidth < 890) {
console.log('Less than 890px');
} else {
console.log('890px or more');
}
}, true);
}
else {
console.log('browser does not support Javascript event binding');
}
onresize is to be used as an attribute in your html. e.g. <body onresize="resizePage()"></body>
The correct event is resize. Try following
if (window.attachEvent) {
window.attachEvent('resize', function() {
if (window.innerWidth < 890) {
console.log('Less than 890px');
} else {
console.log('890px or more');
}
})
}
Please note, you can also consider using addEventListener. For details, refer to another answer here
Just try the following code
window.onresize = resize;
function resize()
{
if(document.body.clientWidth < 890)
{
alert("resize event detected!");
}
}
const on = (e, i, t = window) => typeof t.addEventListener === 'function'
? t.addEventListener (e, i)
: t.attachEvent ('on' + e, i)
const test = () => console.log (window.innerWidth < 890 ? '< 890' : '>= 890')
on ('resize', test)
Just use:
window.onresize = function(event) {
//your code here
};

How can I write this code more elegantly?

I'm writing the same code three times for the different pages of my WordPress site. I feel that it could be written more elegantly but unfortunately I'm not at the skill level yet to achieve this. Is there any way to combine all of this into something more concise? It would also probably help me learn more about what can and can't be done with JavaScript.
if (jQuery(document.body).hasClass("home")) {
jQuery(window).scroll(function () {
var threshold = 654;
if (jQuery(window).scrollTop() >= 654)
jQuery('#sidebar').addClass('fixed');
else
jQuery('#sidebar').removeClass('fixed');
});
} else if (jQuery(document.body).hasClass("single") || jQuery(document.body).hasClass("page")) {
jQuery(window).scroll(function () {
var threshold = 20;
if (jQuery(window).scrollTop() >= 20)
jQuery('#sidebar').addClass('fixed');
else
jQuery('#sidebar').removeClass('fixed');
});
} else {
jQuery(window).scroll(function () {
var threshold = 236;
if (jQuery(window).scrollTop() >= 236)
jQuery('#sidebar').addClass('fixed');
else
jQuery('#sidebar').removeClass('fixed');
});
}
var threshold = 236;
if (jQuery(document.body).hasClass("home")) {
threshold = 654;
} else if (jQuery(document.body).hasClass("single") || jQuery(document.body).hasClass("page")) {
threshold = 20;
}
var scrolled = false;
jQuery(window).scroll(function () {
if (!scrolled && jQuery(window).scrollTop() >= threshold){
jQuery('#sidebar').addClass('fixed');
scrolled = true;
} else if (scrolled && jQuery(window).scrollTop() < threshold) {
jQuery('#sidebar').removeClass('fixed');
scrolled = false;
}
});
UPDATE: I was created a simple demo to show how to implement sidebar scrolls within his parent.
Demo on CodePen
Damn.. I got beat. Well, I'm still posting this anyway.
var scrollTopFn = function(amount){
$(window).scroll(function(){
// this is a ternary statement, basically a shorthand for writing if else statements
$(window).scrollTop() >= amount
? $('#sidebar').addClass('fixed')
: $('#sidebar').removeClass('fixed');
});
}
if ($(document.body).hasClass('home')) {
scrollTopFn(654);
} else if ($(document.body).hasClass('single')){
scrollTopFn(20);
} else {
scrollTopFn(236);
}
Could be:
var threshold = 236;
switch (jQuery(document.body).attr("class")) {
case "home":
threshold = 654
break;
case "single":
case "page":
threshold = 20
break;
}
$(window).scroll(function () {
if (jQuery(window).scrollTop() >= threshold )
jQuery('#sidebar').addClass('fixed');
else
jQuery('#sidebar').removeClass('fixed');
});
Your code could be simplified to:
var $body = jQuery(document.body),
threshold = $body.hasClass("home") ? 654
: $body.hasClass("single") || $body.hasClass("page") ? 20
: 236;
jQuery(window).on('scroll', function() {
jQuery('#sidebar').toggleClass('fixed', state);
});
But this one should have better performance:
var $body = jQuery(document.body),
state = false,
threshold = $body.hasClass("home") ? 654
: $body.hasClass("single") || $body.hasClass("page") ? 20
: 236;
jQuery(window).on('scroll', function() {
if(state != (state = jQuery(window).scrollTop() >= threshold))
jQuery('#sidebar').toggleClass('fixed', state);
});

Categories

Resources