Floating, scrolling element is changing scroll position - javascript

JSFiddle
I have a page, broken up into 3 sections. A header, a sidebar, and a content section. I'm trying to get the sidebar to scroll with the page until it hits the top, then stick there until we scroll back down, at which point it sticks to the bottom of the header. Relevant snippet:
var Sidebar = $("#Dock"), pos = Sidebar.offset();
$(window).scroll(function () {
console.log('pre ' + Sidebar.hasClass('fixed') + ' | ' + $(this).scrollTop() + ' | ' + (pos.top + 10));
if ($(this).scrollTop() > (pos.top + 10) && Sidebar.hasClass('notFixed')) {
Sidebar.removeClass('notFixed');
Sidebar.addClass('fixed');
} else if ($(this).scrollTop() <= (pos.top + 10) && Sidebar.hasClass('fixed')) {
Sidebar.removeClass('fixed');
Sidebar.addClass('notFixed');
}
console.log('pos ' + Sidebar.hasClass('fixed') + ' | ' + $(this).scrollTop() + ' | ' + (pos.top + 10));
});
So here's what actually happens: We scroll down, we remove the notFixed class from our floating element, give it the fixed class, and then immediately jump to $(this).scrollTop() = 23. Finally, any built up scroll events resolve, moving from our last position, and resetting to 23. On the Fiddle, instead of 23 it's 0.
Why is it jumping back, and what can I do to fix it?

edit: updated fiddle http://jsfiddle.net/WHLHW/4/
The reason it wasn't working is because you had height: 1000px on #dock, and no height for body. So because the page was the height of #dock, you couldn't scroll past #dock.
So I did the following and it works now.
#dock {
height:300px;
}
body {
height: 1000px;
}

Related

Add a Class to some items depending on inner html

I'm working on a leaflet js map atm.
There are some items that I want to apply a class to, depending on their inner text. Seems as though two circles at a certain size just overlap. Adding some CSS in that case so they're no longer overlapping.
//function searches for all <text> elements within svg tags for the queryText
// and then appends them with the appendText
function addClasserino() {
let elements = document.querySelectorAll('map-marker marker-bg-condition'); // get all circle elements as a NodeList
elements.forEach(el => { // go through each text element
if (el.innerText < 10) { // if the innerHTML matches the query HTML then
elements.addClass('updated'); // add the class
}
})
}
document.addEventListener("DOMContentLoaded", function(){
//pass in the search text and the appending text as arguments
addClasserino();
});
This is what I got so far. Doesn't seem to be working.
.map-marker.marker-bg-condition needs to be moved across a bit. Got the CSS here:
.map-marker.marker-bg-condition.updated{
margin-top: -19px;
margin-left: -19px;
}
With Leaflet JS, the zoom level changes and items are updated accordingly. This of my map showing all details at the world view, and then breaking down to state as you zoom in.
The unexpected behavior is that the css isn't applying and where bubbles are overlapping is because of this. This is the original code but I can't change it and get it to work even with an if statement.
getMarkerHtml: function(count, color) {
var size = this.getMarkerSize(count);
var hsize = (size / 2) - 6;
var font = count < 1000 ? Math.ceil(size / 3) : Math.ceil(size / 4);
if(count < 100) {
font = font + 3;
}
var cluster_classes = [
'map-marker',
'marker-bg-' + (Filters.colors.profile === color ? 'profile' : 'condition')
];
if(this.zoomLevel !== 'zip') {
size = size * 1.5;
if(petMapFilters.colors.profile !== color) {
hsize = size / 2;
}
}
if(this.zoomLevel === 'zip') {
var cluster_styles = [
'margin-left: -' + hsize + 80 + 'px;', NOTE: I tried this to offset on zip zoom bit it's not working END OF NOTE
'margin-top: -' + hsize + 80 +'px;',
'width: ' + size + 'px;',
'height: ' + size + 'px;',
'font-size: ' + font + 'px;'
];
} else {
var cluster_styles = [
'margin-left: -' + hsize + 'px;',
'margin-top: -' + hsize + 'px;',
'width: ' + size + 'px;',
'height: ' + size + 'px;',
'font-size: ' + font + 'px;'
];};
var div_style = [
'line-height: ' + (size - (size * 0.3)) + 'px;'
];
count = this.formatCount(count);
return '<div class="' + cluster_classes.join(' ') + '" tabindex="0" style="' + cluster_styles.join(' ') + '"><div style="' + div_style.join(' ') + '">' + count + '</div></div>';
},
Please let me know what I am doing wrong here as I am not able to identify this myself.
The issue at hand:
Thanks.

Event when window scrolled to footer in all resolutions - jquery

I have html which has header footer and divs between. I am trying to create an event when the window is scrolled to footer. As the footer appears immediately an alert must popup which shows a message.
Here is my HTML content
http://jsfiddle.net/q4bw82gy/
I have tried the below jquery code, but it is not working for resolutions other than desktop
$(window).scroll(function() {
var scrollPosition = $(window).height() + $(window).scrollTop();
var theight = ($('.banner-section').height()+$('.section-one').height()+$('.section-two').height()+$('.read-one').height()+$('.read-two').height()+$('.next-program').height())-($('.navbar-dark').height()+
($('.main-navigation').height()));
var height1 = $(window).scrollTop();
var height2 = $('.main').height()-$('.expand-section').height()-$('.ftr').height();
if(height1 >= theight){
alert('message 1');
}
else{
alert('message 2');
}
});
Please help with a better solution
Do you want something like this?
$(function() {
$(window).scroll(function() {
var footerTop = $('.ftr').position().top; // or .offset().top
var scrollTop = $(window).scrollTop();
var viewportHeight = $(window).height();
if (footerTop <= scrollTop + viewportHeight) {
console.log("true|" + footerTop + "|" + scrollTop + "|" + viewportHeight);//alert
} else {
console.log("false|" + footerTop + "|" + scrollTop + "|" + viewportHeight);//alert
}
});
});

Jquery Css Function slow to add property to div?

So basically I am trying to scale a div (starts from 0) when another is clicked but the scale origin should start from where the click happened. Sort of what apple does when you click on an app (the app opens up from where you clicked it).
The problem is trying to set the property of the scale origin which I do successfully but when i click on the div, this has no effect ! It only works when I set a timeout function to when I add the class that scales it fully
Class appeared to have been added before css is applied:
var xPosSTR = 30+'px';
var yPosSTR = 30+'px';
$('.box-detail').css({
'transform-origin': '' + xPosSTR + ' ' + yPosSTR + ' 0px',
'-webkit-transform-origin': '' + xPosSTR + ' ' + yPosSTR + ' 0px'
});
$(".box-detail").addClass("box-reveal-prop");
Class is applied with a delay (which scales from the origin specified but takes time)
var xPosSTR = 30+'px';
var yPosSTR = 30+'px';
$('.box-detail').css({
'transform-origin': '' + xPosSTR + ' ' + yPosSTR + ' 0px',
'-webkit-transform-origin': '' + xPosSTR + ' ' + yPosSTR + ' 0px'
});
setTimeout(function(){
$(".box-detail").addClass("box-reveal-prop");
}, 2000);
css: {
.box-detail {
display: inline-block;
position: absolute;
height: 100%;
width: 100%;
transition: 0.3s;
z-index: 1000;
transform:scale(0,0);
}
.box-reveal-prop {
transform:scale(1,1);
}
Can I achieve the same thing without the timeout function, Thanks !
You would want to bind to transitionend
$('.box-detail')
.bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd",
function(){
$(".box-detail").addClass("box-reveal-prop");
});
You may see the js fiddle here

Switch Positions of Tablerows only work once

I have made a jsfiddle
I have a table with articlepositions. And I would made it able that the User can change the position sort by clicking up or down arrows.
But when I swap once the position, i could not change the position of the changed row anymore.
Here is the function:
function switchPosition( data, direction )
{
var tableName = "artikelposition";
currentPosition = parseInt( data['position'] );
if( direction == "up" )
{
newPosition = currentPosition - 1;
}
else if( direction == "down" )
{
newPosition = currentPosition + 1;
}
var otherTr = $("tr[data-position='" + newPosition + "']").data("artikelid");
console.log("clicked object" + data['artikelid'] + " : current position " + data['position'] + " : new position " + newPosition);
console.log("other objekt" + $("#" + otherTr).data("artikelid") + " : current position " + $("#" + otherTr).data("position") + " : new Position " + currentPosition);
$( "#" + data['artikelid'] )
.data({
"position": newPosition
});
$( "#" + data['artikelid'] + " td.tdArticleNumber span.spanPositionNummer" )
.html( newPosition );
$( "#" + otherTr )
.data({
"position": currentPosition
});
$( "#" + otherTr + " td.tdArticleNumber span.spanPositionNummer" )
.html( currentPosition );
sortTable( tableName );
}
As ASGM has already mentioned, problem is with otherTr. In this line:
var otherTr = $("tr[data-position='" + newPosition + "']").data("artikelid");
I still don't know why this expression always returns data-artikelid of first tr, but if you somewhy want to save your code, than you can use replace this line with something like:
$("#artikelposition tr").each(function()
{
var that = $(this);
if (that.data("position") == newPosition)
{
otherTr = that.data('artikelid');
}
});
As Pawel said there in comments, problem is that data-position is set dynamically. But even his idea to use $("...").attr("data-...", value) seems not to work there.
You can probably accomplish this with a lot less code (see jsfiddle):
$(document).ready(function(){
$(".rowUp,.rowDown").click(function(){
var row = $(this).parents("tr:first");
if ($(this).is(".rowUp")) {
row.prev().find(".spanPositionNummer").html(row.index() + 1);
row.insertBefore(row.prev());
} else {
row.next().find(".spanPositionNummer").html(row.index() + 1);
row.insertAfter(row.next());
}
row.find(".spanPositionNummer").html(row.index() + 1);
});
});
You can attach a click handler to the images and user insertBefore() to move the rows. You can also use the built-in index() function (rather than fiddling with data-position) to set the position number span.
(Based on the answer from How to move table row in jQuery?)
Or if you want to do this with your existing code, the bug seems to be that you're selecting the wrong otherTr.
When you first click the down arrow on the top row, you can see in the console that the selected row is moved from position 1 to 2, and the middle row is moved from 2 to 1:
Angeklicktes Objekt2445 : aktuelle Position 1 : neue Position 2 (index):59
Anderes Objekt2501 : aktuelle Position 2 : neue Position 1 (index):60
But when you click the bottom arrow on what's now the top row, this is what the console logs:
Angeklicktes Objekt2501 : aktuelle Position 1 : neue Position 2 (index):59
Anderes Objekt2501 : aktuelle Position 1 : neue Position 1 (index):60
Note that the top row is (correctly) being moved from position 1 to 2. But immediately afterwards, the same row (Objekt2501, referenced by the same position) is instructed to move from 1 to 1.

how to show two div only at onetime?

can you please tell me how to show two div one at time ?
Actually I make one demo where I scroll to top it create one div and prepend to main div.But I want only two div show at one time.Now it will create new divs whenever user goes to top.I want user remove below div.
Example on starting : it show On div id="page_5"
when user scroll up it create div id="page_4" .It is fine
But when user scroll again it create div id="page_3" but that time I need user delete that div id="page_5" from below.again user go up it remove div id="page_4".
if user come down it remove upper div and show below div .remove remove div id="page_1" or remove div id="page_2" and show div id="page_5" or div id="page_4"
http://jsfiddle.net/Gbd3z/2/
var pages = [page_1, page_2, page_3, page_4,page_5];
var totalPage = "page_" + pages.length;
$("<div id='" + totalPage + "'>" + pages.pop() + "</div>").prependTo($("#fullContainer"));
$("#fullContainer").scroll(function () {
// top
if ($(this).scrollTop() === 0 && pages.length) {
console.log("up");
var stringLoad = "page_" + pages.length;
$("<div id='" + stringLoad + "'>" + pages.pop() + "</div>").prependTo($("#fullContainer"));
}
if ($(this).scrollTop() >= $(this)[0].scrollHeight - document.body.offsetHeight) {
console.log("down");
}
});
Try
$("#fullContainer").scroll(function () {
// top
if ($(this).scrollTop() === 0 && pages.length) {
console.log("up");
var stringLoad = "page_" + pages.length;
$("<div id='" + stringLoad + "'>" + pages.pop() + "</div>").prependTo($("#fullContainer"));
//remove element at 2nd index
$('#fullContainer').children().slice(2).remove()
}
if ($(this).scrollTop() >= $(this)[0].scrollHeight - document.body.offsetHeight) {
console.log("down");
}
});
Demo: Fiddle

Categories

Resources