Vue.js style working on wrong element - javascript

It's really strange.
I'm making floating sidebar in the Vue component, so need to change the css position value between fixed and relative.
so what I did is giving an ID for the sidebar element, and on scroll event, check the position on the page and changed some css values.
Here is my code.
created() {
document.addEventListener('scroll', this.handleScroll);
},
destroyed() {
document.addEventListener('scroll', this.handleScroll);
}
/* ... */
handleScroll(e) {
var doc = document.documentElement;
var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
var originWidth = $("#fields-to-move").width() + 2;
if(this.screen_no == 2){
if (280 <= top) {
document.getElementById("fields-to-move").style.position = "fixed";
document.getElementById("fields-to-move").style.top = 10 + 'px' ;
document.getElementById("fields-to-move").style.width = originWidth + 'px';
} else {
document.getElementById("fields-to-move").style.position = "relative";
document.getElementById("fields-to-move").style.top = 'auto' ;
document.getElementById("fields-to-move").style.width = originWidth + 'px';
}
}
}
"fields-to-move" is the ID of DOM element I'm going to change css.
It's working well.
But the problem is that above css ( position: fixed, top:10px and width) also applied on other element without the ID.
There's one thing more need to mention.
The element with the ID is a child element of another one which is mounted with v-if condition.
After the parent element dismounted, the css is applied to the wrong element that's mounted after it.
I'm not sure my explanation is enough. Please let me know if you have any questions above my problem.
Thanks in advance.

If you can provide separeted example in jsfiddle it would be easier to help...
But I belive that this behaviour can caused by some Vue optimizations described here: documentation
edit:
Try to execute entire logic of "handleScroll" in vues nextTick.

Related

Sticky block on JS

helloi want to make a sticky block using this script
$(window).scroll(function() {
var sb_m = 80; /* top and bottom padding */
var mb = 300; /* footer height with a margin */
var st = $(window).scrollTop();
var sb = $(".loginform");
var sbi = $(".loginform #loginform");
var sb_ot = sb.offset().top;
var sbi_ot = sbi.offset().top;
var sb_h = sb.height();
if(sb_h + $(document).scrollTop() + sb_m + mb < $(document).height()) {
if(st > sb_ot) {
var h = Math.round(st - sb_ot) + sb_m;
sb.css({"paddingTop" : h});
}
else {
sb.css({"paddingTop" : 0});
}
}
});
on naked HTML all work fine
if add a script to site (use wordpress) appears an infinite scroll
here can see problem
problem appears if add an element to footer through widgets
please tell me what is problem?
Honestly it's not ideal to work with padding-top, you should use top (with the element set as position:relative or absolute);
If you don't care about supporting IE, the easiest way is to use position:sticky; which does all the work for you: https://developer.mozilla.org/en-US/docs/Web/CSS/position
If you prefer to do it yourself, I'd suggest working this way:
store in variables the current offset().top and .left of the soon-to-be sticky element, outside any onScroll handlers.
When this condition is true:
$(window.scrollTop() >= theElementOffsetTopValueYouStored)
set the element as position: fixed and set the left: and top: properties of the element that should become sticky with the values you stored before. Then add your condition to make sure it stops when it reaches the end of the document, checking if element.offset().top + element.height > document.height
Please consider this is from memory, you might need to tweak a few things here and there to make it work properly.

Add class using script

function init() {
window.addEventListener('scroll', function(e) {
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 70,
header = document.querySelector(".nb-navbar");
if (distanceY > shrinkOn) {
classie.add(header, "smaller");
} else {
if (classie.has(header, "smaller")) {
classie.remove(header, "smaller");
}
}
});
Hi guys, I need to do something what, when we scroll, when it reach center of the screen we need to add a class on a div. And we need to calculate from the bottom. That is from bottom when it reach a center or at certain position the div need to add a class it's self. I have tried but it didn't work. Is there any other way or can you guys help with my script. Thanks :)
Not sure where classie is defined but if your just trying to add a class to the header
header = document.querySelector(".nb-navbar");
header.classList.add('smaller')
or perhaps
let hasClass = header.classList.contains('smaller');
header.classList.toggle('smaller', hasClass);

How to make an element become fixed when 50px from the top of the screen

I have a html div element that scrolls with the page but I would like it to become fixed once it reaches 50px from the top of the screen...
How is this done?
My div id is #box
Thanks!
-Ina
If you want it to be fixed at the top of the page at some distance from the top, you can check the top offset of the element and change the class when it reach the distance you want.
Here is the jquery code for your reference
jQuery(document).scroll(function() {
var documentTop = jQuery(document).scrollTop();
console.log('this is current top of your document' + documentTop );
//box top is 891
if (documentTop > 841) {
//change the value of the css at this point
jQuery("#box").addClass("stayfix");
}
else
{
jQuery("#box").removeClass("stayfix");
}
});
You need to be more specific about what have you done so far. For eg, how did you make the div element to scrolls inside the page. using css or js/jquery animation features?That will help us to give more specific answer.
**Edited According to your fiddle.
They are right, this question is duplicate. Here is a code I made with answers from the forum.
var box_top = $("#box").offset().top;
$(window).scroll(function (event) {
if ($(window).scrollTop() >= (box_top - 50)) {
$("#box").css({position:"fixed",top:"50px"});
} else {
$("#box").css({position:"relative"});
}
});
Hope it helps anyway.
https://jsfiddle.net/ay54msd5/1/
Try something like this. It's a solution using jquery (hopefully not a problem) that checks the scrollHeight of the page every time the page scrolls. If the scrollHeight is greater than a certain threshold, the element becomes fixed. If not, the element is positioned relatively (but you can do whatever you want in that case.
$(document).ready(function() {
var navFixed = false;
var $box = $("#box");
var topHeight = 50;
$(document).scroll(function() {
if ($(document).scrollTop() >= topHeight && !navFixed) {
$box.css("position", "fixed");
navFixed = true;
}
else if ($(document).scrollTop() < topHeight && navFixed) {
$box.css("position", "relative");
navFixed = false;
}
});
});
You would have to write some additional CSS targeting the #box element that tells it what coordinates you'd like it to be fixed to.

How might I tell if an HTML element is being rendered on the screen?

I'd like an element to do a CSS3 animation once the page is scrolled down enough for it to be visible, and I'm wondering if there's any way to accomplish this. Anything involving JavaScript or CSS would work. I've done many Google searches and Stackoverflow searches and can't find exactly what I need.
Depending on the complexity of your layout, it could be as simple as finding the scroll position, the height of the window, and where the element is on the page.
function scrollEvent() {
var el = document.getElementsByTagName('a')[0];
var body = document.getElementsByTagName('body')[0];
var posY = (window.innerHeight + body.scrollTop) - el.offsetTop;
var onScreen = (posY > 0 && posY < window.innerHeight) ? true : false;
}
window.onscroll = scrollEvent;
Use the same technique if you're worried about horizontal positioning, as well.
It depends on what you want to do specifically. I would look at these resources:
http://daneden.github.io/animate.css/
http://www.w3schools.com/css/css3_animations.asp
http://css-tricks.com/almanac/properties/a/animation/
Put your CSS3 animation style in a class, but don't assign it to your element until it has been scrolled completely into view.
Assuming your element has an id of sprite, this should get you going:
<style>
.animate {
//CSS3 animation style
}
</style>
window.onscroll= function() {
var sprite = document.getElementById('sprite');
if(sprite.getBoundingClientRect().top>=0 && sprite.getBoundingClientRect().bottom<=window.innerHeight) {
sprite.className= 'animate';
}
}

Getting Coordinates of an element on page scroll

I am having this problem where i have a set of 6 UL's having a common class x.Each of them consist of a specific section of the page.Now i have 6 menus that are related to each of the section.What i have to do is highlight the menu when its related section is in users view.
For this i thought that may be jQuery position(); or offset(); could have helped but they give the top and left of the element.I also tried using jQuery viewport plugin but apparently view port is big it can show more than one UL at a time hence i cant apply element specific logic here.I am not familliar to this but does anything changes of an element on scrolling?If yes then how to access it?
Please share your views.
Regards
Himanshu Sharma.
Is very easy to do it using jQuery and a dummy fixed HTML block that helps you find the current position of the viewport.
$(window).on("scroll load",function(){
var once = true;
$(".title").each(function(ele, index){
if($(this).offset().top > $("#viewport_helper").offset().top && once){
var index = $(this).index(".title");
$(".current").removeClass('current')
$("#menu li").eq(index).addClass('current')
once = false;
}
});
})
Check out a working example: http://jsfiddle.net/6c8Az/1/
You could also do something similar with the jQuery plugin, together with the :first selector:
$(window).on("scroll load",function(){
$(".title:in-viewport:first").each(function(){
var index = $(this).index(".title");
$(".current").removeClass('current')
$("#menu li").eq(index).addClass('current')
});
})
You can get the viewport's width and height via $(document).width() and $(document).height()
You can get how many pixels user scrolls via $(document).scrollTop() and $(document).scrollLeft
Combining 1 and 2, you can calculate where the viewport rectangle is
You can get the rectangle of an element using $(element).offset(), $(element).width() and $(element).height()
So the only thing left to you is to determine whether the viewport's rectangle contains (or interacts) the elements's rectangle
So the whole code may look like:
/**
* Check wether outer contains inner
* You can change this logic to matches what you need
*/
function rectContains(outer, inner) {
return outer.top <= inner.top &&
outer.bottom >= inner.bottom &&
outer.left <= inner.left &&
outer.right >= inner.right;
}
/**
* Use this function to find the menu related to <ul> element
*/
function findRelatedMenu(element) {
return $('#menu-' + element.attr('id'));
}
function whenScroll() {
var doc = $(document);
var elem = $(element);
var viewportRect = {
top: doc.scrollTop(),
left: doc.scrollLeft(),
width: doc.width(),
height: doc.height()
};
viewportRect.bottom = viewportRect.top + viewportRect.height;
viewportRect.right = viewportRect.left + viewportRect.width;
var elements = $('ul.your-class');
for (var i = 0; i < elements.length; i++) {
var elem = $(elements[i]);
var elementRect = {
top: elem.offset().top,
left: elem.offset().left,
width: elem.width(),
height: elem.height()
};
elementRect.bottom = elementRect.top + elementRect.height;
elementRect.right = elementRect.left + elementRect.width;
if (rectContains(viewportRect, elementRect)) {
findRelatedMenu(elem).addClass('highlight');
}
}
}
$(window).on('scroll', whenScroll);
Let's see if i understood well. You have a page long enough to scroll, and there is an element that when it appears in the viewport, you wanna do something with it. So the only event that's is triggered for sure on the time the element gets in the viewport is the 'scroll'. So if the element is on the page and the scroll is on the viewport, what you need to do is bind an action to the scroll event to check if the element is in the view each time the event is trigger. Pretty much like this:
$(window).scroll(function() {
check_element_position();
});
Now, in order for you to know if the element is in the viewport, you need 3 things. The offset top of that element, the size of the viewport and the scroll top of the window. Should pretty much look like this:
function check_element_position() {
var win = $(window);
var window_height = win.height();
var element = $(your_element);
var elem_offset_top = element.offset().top;
var elem_height = element.height();
var win_scroll = win.scrollTop();
var pseudo_offset = (elem_offset_top - win_scroll);
if (pseudo_offset < window_height && pseudo_offset >= 0) {
// element in view
}
else {
// elem not in view
}
}
Here, (elem_offset_top - win_scroll) represent the element position if there was no scroll. Like this, you just have to check if the element offset top is higher then the window viewport to see if it's in view or not.
Finally, you could be more precise on you calculations by adding the element height (variable already in there) because the code i just did will fire the event even if the element is visible by only 1 pixels.
Note: I just did that in five minutes so you might have to fix some of this, but this gives you a pretty darn good idea of what's going on ;)
Feel free to comment and ask questions

Categories

Resources