Change position fixed of div if scroll - javascript

I tried to fix a div after scroll on vuejs; My code like this :
...
async created() {
window.addEventListener('scroll', this.calendarScroll);
}
methods: {
calendarScroll() {
console.log('Scroll');
const dateHeader = document.querySelector('.dates-header');
if (dateHeader) {
if (window.scrollTop() >= 200) {
dateHeader.style.top = 0;
dateHeader.style.position = 'fixed';
}
}
},
}
the error is : Calendar.vue?404a:681 Uncaught TypeError: window.scrollTop is not a function

You can add scrollTo to the Element prototype before you mount:
Element.prototype.scrollTo = () => {}
All Elements created after you add this code will have the scrollTo method.
For more detail, you can check this: https://github.com/vuejs/vue-test-utils/issues/319#issuecomment-354667621

Related

Hide an element when scroll to specific class

I Used this JQuery code to have a sticky "Go to top" button:
//sticky back-to-top button
(function (t) {
t(window).bind("scroll", function () {
500 < t(this).scrollTop()
? t(".back-to-top").fadeIn(400)
: t(".back-to-top").fadeOut(400);
}),
t(".back-to-top").click(function () {
t("html, body").animate({ scrollTop: "0px" }, 500);
});
})(jQuery);
this code works correctly.
but i want when this sticky button reaches a specific class called "go-top", disappears. sorry for my bad english.
You can use interception observer so when the target element with said class is in view, it triggers the callback to hide the button.
Example: The code might not be exact but it is meant to point in the direction to follow.
let options = {
root: document.querySelector('.go-top'),
rootMargin: '0px',
threshold: 1.0
}
let prevRatio = 0.0;
let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#back-to-top-button');
observer.observe(target);
function handleIntersect(entries, observer) {
entries.forEach((entry) => {
if (entry.intersectionRatio > prevRatio) {
entry.target.style.display = "none";
} else {
entry.target.style.backgroundColor = "block";
}
prevRatio = entry.intersectionRatio;
});
}
Let me know how it goes...
You can switch the root to null but this makes the button disappear as soon as the element with the class is in the viewport

Array of elements becomes undefined within a class when changing with and attempting to do some adjustments

I build an object and gather all elements by class name, then on changing the with I want to do some work on them. When I construct the object it works, but within WidthChecker() when do some work on a width change the become undefined.
class SlickController {
constructor () {
this.$mobileSlicksCarousels;
}
Init() {
this.$mobileSlicksCarousels = document.getElementsByClassName("slick_carousels_mobile-only"); // view in console says this is valid, I see the objects
this.WidthChecker();
}
WidthChecker() {
var width = $(window).width();
$(window).on('resize', function() {
console.log(this.$mobileSlicksCarousels); // they become undefined in here, lost and none of the content afterwords be seen
if ($(this).width() !== width) {
width = $(this).width();
if (width < 491) {
this.$mobileSlicksCarousels.forEach( carousel => {
this.SlickMobile(carousel);
});
} else if (width > 490) {
this.$mobileSlicksCarousels.forEach( carousel => {
this.UnSlickMobile(carousel);
});
}
}
});
}
SlickMobile (toSlick) {
console.log(toSlick);
toSlick.slick();
}
UnSlickMobile (unSlick) {
unSlick.slick('unslick');
}
}
// call and start width checker
slick_Controller.Init();
I assume the issue is when I called $(window).on('resize', function() { because the function doesn't see the parent variables, but I'm not sure how else to approach calling a function directly on resize.
You can store this in a variable before jumping to function or you can bind function but then you lose jquery context and cannot use $(this) expression.
Take a look at the examples
class Test {
constructor () {
this.property = 1;
}
Func() {
var width = $(window).width();
const that = this;
$(window).on('load', function() {
console.log(that.property);
console.log($(this).width());
});
}
Func1() {
var width = $(window).width();
$(window).on('load', (function() {
console.log(this.property);
console.log($(window).width());
}).bind(this));
}
Func2() {
var width = $(window).width();
$(window).on('load', this.OnResize.bind(this));
}
OnResize(event) {
console.log(this.property);
console.log($(event.target).width());
}
}
const test = new Test();
test.Func();
test.Func1();
test.Func2();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

How to unbind an event while jump to other page in NUXTjs?

I have written this code in one page. It works but how can I unbind this event when i Jump to other page?
private mounted () {
if (process.browser) {
const banner:any = document.querySelector('.banner img')
document.addEventListener('scroll', () => {
const offsetTop = window.scrollY
const INTOR_HEIGHT = document.querySelector('.intro-text').offsetHeight
if (offsetTop < INTOR_HEIGHT) {
banner.style.top = offsetTop + 'px'
}
})
}
}
when I jump to other page form this page,this error is thrown:
javascript Uncaught TypeError: Cannot read property 'offsetHeight' of
null
at HTMLDocument.eval
haha , VUE.js Instance Lifecycle Hooks also can use in nuxt.js.
so just like this
private smoothSlier () {
const banner:any = document.querySelector('.banner img')
const offsetTop = window.scrollY
const INTOR_HEIGHT:any = document.querySelector('.intro-text').offsetHeight
if (offsetTop < INTOR_HEIGHT) {
banner.style.top = offsetTop + 'px'
}
}
private mounted () {
if (process.browser) {
document.addEventListener('scroll', this.smoothSlier)
}
}
private beforeDestroy () {
document.removeEventListener('scroll', this.smoothSlier)
}
the point is bind golbal event in mounted hooks and,unbind in beforeDestroy

trying to make a sticky header stick on page load, before scrolling

I have this header that is working fine. My issue is that when you reload the page when the scroll position is passed 114, the header is not fixed until you scroll. I'm trying to get it to detect the scroll position of the page before the user scrolls.
function initHeader() {
var Header = document.querySelector(".header");
var HeaderContainer = document.querySelector(".header-container-after");
document.addEventListener('scroll', function () {
if (window.scrollY > 114) {
Header.classList.add('header--is-fixed');
HeaderContainer.classList.add('fixed-header-container');
} else {
Header.classList.remove('header--is-fixed');
HeaderContainer.classList.remove('fixed-header-container');
}
});
}
window.onload = initHeader;
thanks
There can be an even easier solution, use position: sticky; top: 0
It will act as an relative element until it hits the top (or before, change the top value) and from that point it will act as a fixed element.
In case you want to stick with JS for this, wrap it in a function and call it on load
let header;
let headerContainer;
function fixNav(){
if (window.scrollY > 114) {
header.classList.add('header--is-fixed');
headerContainer.classList.add('fixed-header-container');
} else {
header.classList.remove('header--is-fixed');
headerContainer.classList.remove('fixed-header-container');
}
}
document.addEventListener('DOMContentLoaded', ()=>{
header = document.querySelector(".header");
headerContainer = document.querySelector(".header-container-after");
document.addEventListener('scroll', fixNav);
fixNav();
})
Looks like you are only running the code when the user scrolls. Try running it when the user scrolls AND when the page loads. Like so:
function initHeader() {
var Header = document.querySelector(".header");
var HeaderContainer = document.querySelector(".header-container-after");
// extract the logic to a function
var updateNav = function () {
if (window.scrollY > 114) {
Header.classList.add('header--is-fixed');
HeaderContainer.classList.add('fixed-header-container');
} else {
Header.classList.remove('header--is-fixed');
HeaderContainer.classList.remove('fixed-header-container');
}
}
// run that function on scroll
document.addEventListener('scroll', updateNav);
// but also run it right now (page load)
updateNav();
}
window.onload = initHeader;

this.attribute is not defined after being constructed

Hi there I made a very small jquery plugin:
$mandarina = {
mainCnt: $('#main'),
header: $('header.site-header'),
init: function () {
this.onScroll();
},
onScroll: function () {
$(window).scroll(function(e){
var scrollTop = $(window).scrollTop();
if(scrollTop > this.header.height()){
this.mainCnt.addClass('fixed-header');
}else{
this.mainCnt.removeClass('fixed-header');
}
});
}
}
$(function () {
$mandarina.init();
});
But when I scroll I get this error in console:
TypeError: this.header is undefined
[Parar en este error]
if(scrollTop > this.header.height()){
Any idea why?
weird thing is that this.header in the init function it does exist..
Inside the scroll callback, this is the window element rather than your $mandarina object. You need to save a reference to $mandarina via;
onScroll: function () {
var that = this;
$(window).scroll(function(e){
var scrollTop = $(window).scrollTop();
if(scrollTop > that.header.height()){
that.mainCnt.addClass('fixed-header');
}else{
that.mainCnt.removeClass('fixed-header');
}
});
}
... i.e. store the value of this in that, and use that instead of this inside the event handler.
try this
$mandarina = {
mainCnt: $('#main'),
header: $('header.site-header'),
init: function () {
this.onScroll();
},
onScroll: function () {
var $this= $(this);
$(window).scroll(function(e){
var scrollTop = $(window).scrollTop();
if(scrollTop > $this.header.height()){
$this.mainCnt.addClass('fixed-header');
}else{
$this.mainCnt.removeClass('fixed-header');
}
});
}
}
$(function () {
$mandarina.init();
});
this.header.height
you need to remove this

Categories

Resources