Jquery detect begin scroll on element [duplicate] - javascript

This question already has answers here:
Detect when Body Scroll hits top | bottom of element
(2 answers)
Closed 6 years ago.
I have a big webpage, that has a lot of <div> elements. I want to detect when the scroll detects that element. The thing is that I have no id. I tried to do this:
$('#hexagon').scroll(function() {
alert("hi");
var currY = $(this).scrollTop();
var postHeight = $(this).height();
var scrollHeight = $('#path1').height();
// Current percentual position
var scrollPercent = (currY / (scrollHeight - postHeight)) * 100;
triangle.style.strokeDashoffset = scollPercent;
});
It doesn't display the alert box. What I am doing wrong?

Try to do this:
$(window).scroll(function() {
var hexagon = $('#hexagon').position().top;
if($(window).scrollTop() > hexagon) {
alert('scroll');
};
});

Related

Make jquery script update on window resize? [duplicate]

This question already has an answer here:
Javascript onclick function is called immediately (not when clicked)? [duplicate]
(1 answer)
Closed 5 years ago.
I have made a jquery script that relies on variables for viewport width and viewport height.
This is the script with the viewportwidth and viewportheight variables, stored in its own document:
var viewportwidth,viewportheight;"undefined"!=typeof window.innerWidth?(viewportwidth=window.innerWidth,viewportheight=window.innerHeight):"undefined"!=typeof document.documentElement&&"undefined"!=typeof document.documentElement.clientWidth&&0!=document.documentElement.clientWidth?(viewportwidth=document.documentElement.clientWidth,viewportheight=document.documentElement.clientHeight):(viewportwidth=document.getElementsByTagName("body")[0].clientWidth,viewportheight=document.getElementsByTagName("body")[0].clientHeight);
Here is the script:
function kjør() {
if ((viewportwidth / viewportheight) >= 1.33) {
$('#redline').appendTo('body');
$('#sitewrap').on('scroll', function(e) {
if ($(this).scrollTop() > (viewportheight / 100 * 40)) {
$('body').addClass('fix');
$('#headerwrap').appendTo('body');
} else {
$('body').removeClass('fix');
$('#headerwrap').appendTo('header');
}
$("#logo-top").css("opacity", 1 - $(this).scrollTop() / (viewportheight / 100 * 30));
});
} else {
$('#headerwrap').appendTo('body');
$('#redline').prependTo('#headerwrap');
$('body').removeClass('fix');
};
};
$(function() {
kjør();
$(window).resize(kjør());
});
As you can se at the bottom. I have tried making it so that the script will update once window is resized. This doesnt work, however. The script will still use the viewportwidth and viewportheight that were established on pageload.
How can I make the script reevaluate viewport height and viewport width on window resize?
Your problem is the line bellow:
$(window).resize(kjør());
Change it to:
$(window).resize(kjør);
When you use the sintax function_name() you are referencing the return value of the function, not the function itselfs.

How to fire javascript function after scrolling to certain div element [duplicate]

This question already has answers here:
jQuery when element becomes visible [duplicate]
(6 answers)
Closed 8 years ago.
How do I fire this function only at the time when I scroll down to "myTargetElement" and it becomes visible on the screen, and not immediately after page is loaded?
<script src="countUp.min.js" type='text/javascript'></script>
<script>
$(document).ready(function() {
var countOptions = {
useEasing : true,
useGrouping : true,
separator : ',',
decimal : '.'
}
var customerNumber = new countUp("myTargetElement", 0, 1635, 0, 7, countOptions);
customerNumber.start();
});
</script>
On scroll event check whether target element offset top and document scroll top is same, if same then trigger function
$(document).scroll(function(){
if($('.myTargetElement').offset().top == $(document).scrollTop()){
//Trigger function
}
});
The following script fires it as soon as it gets visible (http://jsfiddle.net/f1xbgy86/1/):
$(window).scroll(function() {
if(isElementVisible($('#yourElementID'))) {
$(window).off('scroll');
//Call From here
}
});
function isElementVisible(elem)
{
var visibleTop = $(window).scrollTop();
var visibleBottom = visibleTop + $(window).height();
return ((elem.offset().top + elem.height()) <= visibleBottom);
}

Getting scroll bar width using JavaScript [duplicate]

This question already has answers here:
How can I get the browser's scrollbar sizes?
(25 answers)
Closed 5 years ago.
The following HTML will display a scroll bar on the right inside edge of div.container.
Is it possible to determine the width of that scroll bar?
<div class="container" style="overflow-y:auto; height:40px;">
<div class="somethingBig"></div>
</div>
This function should give you width of scrollbar
function getScrollbarWidth() {
// Creating invisible container
const outer = document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.overflow = 'scroll'; // forcing scrollbar to appear
outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps
document.body.appendChild(outer);
// Creating inner element and placing it in the container
const inner = document.createElement('div');
outer.appendChild(inner);
// Calculating difference between container's full width and the child width
const scrollbarWidth = (outer.offsetWidth - inner.offsetWidth);
// Removing temporary elements from the DOM
outer.parentNode.removeChild(outer);
return scrollbarWidth;
}
Basic steps here are:
Create hidden div (outer) and get it's offset width
Force scroll bars to appear in div (outer) using CSS overflow property
Create new div (inner) and append to outer, set its width to '100%' and get offset width
Calculate scrollbar width based on gathered offsets
Working example here: http://jsfiddle.net/slavafomin/tsrmgcu9/
Update
If you're using this on a Windows (metro) App, make sure you set the -ms-overflow-style property of the 'outer' div to scrollbar, otherwise the width will not be correctly detected. (code updated)
Update #2
This will not work on Mac OS with the default "Only show scrollbars when scrolling" setting (Yosemite and up).
offsetWidth includes width of scroll bar and clientWidth doesn't. As rule, it equals 14-18px. So:
let scrollBarWidth = element.offsetWidth - element.clientWidth;
That will return 0 if the element doesn't currently have a scroll bar, so here's a simple function which computes the browser's scroll bar width by creating a temporary element that has a scroll bar:
function getScrollBarWidth() {
let el = document.createElement("div");
el.style.cssText = "overflow:scroll; visibility:hidden; position:absolute;";
document.body.appendChild(el);
let width = el.offsetWidth - el.clientWidth;
el.remove();
return width;
}
I think this will be simple and fast -
var scrollWidth= window.innerWidth-$(document).width()
If the child takes the full width of the container excluding scrollbar (the default), then you can subtract the widths:
var child = document.querySelector(".somethingBig");
var scrollbarWidth = child.parentNode.offsetWidth - child.offsetWidth;
If you use jquery.ui, try this code:
$.position.scrollbarWidth()
I've used next function to get scrollbar height/width:
function getBrowserScrollSize(){
var css = {
"border": "none",
"height": "200px",
"margin": "0",
"padding": "0",
"width": "200px"
};
var inner = $("<div>").css($.extend({}, css));
var outer = $("<div>").css($.extend({
"left": "-1000px",
"overflow": "scroll",
"position": "absolute",
"top": "-1000px"
}, css)).append(inner).appendTo("body")
.scrollLeft(1000)
.scrollTop(1000);
var scrollSize = {
"height": (outer.offset().top - inner.offset().top) || 0,
"width": (outer.offset().left - inner.offset().left) || 0
};
outer.remove();
return scrollSize;
}
This jQuery-based solutions works in IE7+ and all other modern browsers (including mobile devices where scrollbar height/width will be 0).
Here's an easy way using jQuery.
var scrollbarWidth = jQuery('div.withScrollBar').get(0).scrollWidth - jQuery('div.withScrollBar').width();
Basically we subtract the scrollable width from the overall width and that should provide the scrollbar's width. Of course, you'd want to cache the jQuery('div.withScrollBar') selection so you're not doing that part twice.
Assuming container is only on page once and you are using jQuery, then:
var containerEl = $('.container')[0];
var scrollbarWidth = containerEl.offsetWidth - containerEl.clientWidth;
Also see this answer for more details.
this worked for me..
function getScrollbarWidth() {
var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
$('body').append(div);
var w1 = $('div', div).innerWidth();
div.css('overflow-y', 'scroll');
var w2 = $('div', div).innerWidth();
$(div).remove();
return (w1 - w2);
}

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

How to change the left attribute on page resize (jQuery)

I'm having slight troubles with my code. What I'm trying to do is make these element's css property 'left' update according to the difference of it's current left value, and the amount the page resizes. This way, when the page resizes and the background moves over, the elements will move too. Take a look at the code below and I'll describe the issue:
$(window).resize(function() {
var docWidth = $(window).width();
if (docWidth < 1000) {
var difference = 1000-docWidth;
$('#headNav a,#icons div').each(function() {
var left = $(this).position().left;
var newLeft = left - difference;
$(this).css({ 'left' : newLeft });
});
}
});
So the issue that I'm getting is the elements are being given left values of wild numbers, while the value of the variable 'newLeft' is the reasonable, desired value. The each function I think is collecting the sums of these values and running them for each element x amount of times that the elements found exist (so if there's 5 elements it runs 5 times, I mean.) What I want is this code to execute uniquely for each element, but just once each, not each element 10 times! (that's how many elements are in the html).
So my question is, how can this be achieved? I hope I explained myself well enough, this was tough to iterate. Any help is extremely appreciated. Thank you!
Here's a fun trick: Include += in your .css() call:
$(this).css({left: "+=" + difference});
jQuery does the math for you to get the new value.
Try this:
$(window).resize(function() {
var docWidth = $(window).width();
if (docWidth < 1000) {
var difference = 1000-docWidth;
$('#headNav a,#icons div').each(function(iconInst) {
var left = $("#" + iconInst).position().left;
var newLeft = left - difference;
$("#" + iconInst).css({ 'left' : newLeft });
});
}
});

Categories

Resources