JS function causes shift of all elements on page - javascript

There is bottom bar, with CSS:
#bottom_nav {
position: absolute;
bottom: 0;
left: 0;
border-top: solid 1px lightgray;
background: url('http://localhost:3000/assets/font-try.jpg');
height: 70px;
width: 100%;
font-family: "ProximaNova", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12px;
font-weight: 400;}
And on some AJAX actions there is Jquery function, to prevent elements сover bottom bar:
var $beforeBar= $('#bottom_nav').prev().offset().top;
var $beforeBarPosition=$beforeBar+ $('#bottom_nav').prev().height();
if($beforeBarPosition+50>=$('#bottom_nav').offset().top){
$('#bottom_nav').css({'top':$(document).height()+100});
}
Problem is that each time this function called, all elements on the page are shifted left slightly. Looks really ugly. If I disable function, no shift.
Also, jsfiddle
EDIT:
Yeath, I got it, it is appearing window scroll panel on changing doc height.
Any solutions?

The shift is caused by this line:
$('#bottom_nav').css({'top':$(document).height()+100});
This is setting the top of the #bottom_nav element to 100 pixels past the end of the document... effectively increasing the height of the document by 170px (100px + the height of #bottom_nav). The next time this code is run, the value returned from $(document).height() is 170 higher... leading the page to expand in height by yet another 170px.

Related

jQuery isn't working to make navigation icons appear after scrolling past 1vh

I work in a web development environment that uses WordPress. The theme we use is ThemeCo's Pro.
I'm still learning javascript (so please forgive me if I'm really far off), and I'm trying to use jQuery to write a piece of code that will allow an element to appear after scrolling 1vh of the page. Can anyone help me understand why this isn't working? I can't tell if it's my code, or my theme might not be allowing it. The theme itself uses jQuery on the front end, but has a javascript file I may edit, but for the most part, the frontend editor is pretty reliable for code.
I'm using pieces from this question to help me write it, as well as referencing the jQuery library.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var minH = $(window).height() * 1;
if (scroll >= minH) {
$("#circle-menu").fadeTo(500, 1);
}
else {
$("#circle-menu").fadeTo(500, 0);
}
});
Just to make sure I understand what you're trying to do, I'll quickly reiterate what your code does: Basically, minH is supposed to be 1vh, and if scroll is >= minH, you want #circle-menu to fade in.
That being said, I think we have to look at a couple potential issues with the code above:
1vh is really just 1/100 of the viewport height, which can be calculated as:
// this is 1vh, which is what you're going for
$(window).height() / 100
As opposed to:
// this is 100vh
$(window).height() * 1
The second would be that you're using fadeTo. The difference between fadeIn/fadeOut and fadeTo is that fadeTo doesn't affect an element's display property. It only affects an element's opacity property. This means that if the theme's default value for the menu's display property is set to "none", fadeTo is not going to make it fade into sight. To get around this, in my opinion, it would be better to use fadeIn and fadeOut instead, especially since it doesn't seem like you're trying to control different levels of opacity (which is what fadeTo is really needed for).
I made a quick code snippet to demonstrate the above fixes.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var vh = $(window).height() / 100;
var minH = vh;
if (scroll >= minH) {
$("#circle-menu").fadeIn(500);
}
else {
$("#circle-menu").fadeOut(500);
}
});
p {
margin-top: 10vh;
height: 150vh;
border: 2px solid #666;
}
#circle-menu {
font-family: 'Segoe UI', verdana, sans-serif;
font-size: 20px;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 50px;
box-shadow: 1px 2px 3px rgba(50,50,50,0.1);
z-index: 1;
display: none;
background-color: steelblue;
color: white;
padding-left: 20px;
padding-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="circle-menu">Menu</div>
<p></p>

How to open link in <a href> when click on parent <h3> element?

I have the problem when click in my title some post. Because I need set title have font-size and line-height is big. When user click between two line, they can't click. If hover in text, it's work.
I added a red arrow with 2 heads in the middle of the 2 lines (click on this to see image)
But user not hover exactly all time, so they will try click many time when start read some post in my website.
Code look like that:
.entry-title {
font-family: Arial,Helvetica,sans-serif;
padding-top: 2px;
font-weight: 700;
font-size: 26px;
line-height: 46px !important;
width: 50%;
}
<h3 class="entry-title">
This line very long, have font-size is 26 and line-height is 46px
</h3>
I purposely to width 50% to have 2 line in sample code.
Have any method to fix that? User only hover anything on h3 tag, click on h3 tag and will open link in the a href.
So sorry if my first post is bad. I also research in Stackoverflow before ask this question but can't find the question same my case.
I prefer the simple method to resolve that. Thank you very much!!!
Since you cannot change your HTML structure, you can select all elements with the entry-title class using document.querySelectorAll and add click event handlers to all of them to click the child anchor tag.
document.querySelectorAll('.entry-title').forEach(title => title.addEventListener("click", function(e){
this.querySelector('a').click();
}));
var h3 = document.querySelector(".entry-title");
h3.addEventListener("click", function () {
var a = h3.getElementsByTagName('a')[0];
a.click();
});
.entry-title {
font-family: Arial,Helvetica,sans-serif;
padding-top: 2px;
font-weight: 700;
font-size: 26px;
line-height: 46px !important;
width: 50%;
cursor:pointer;
}
<h3 class="entry-title">
This line very long, have font-size is 26 and line-height is 46px
</h3>
Update:
Use addEventListener on <h3> and simulate click(); on <a> link
Your example could be:
var h3 = document.getElementsByClassName("entry-title");
for (var i = 0; i < h3.length; i++) {
var a = h3[i].getElementsByTagName("a")[0];
h3[i].addEventListener("click", function() {
a.click();
});
}
.entry-title {
font-family: Arial, Helvetica, sans-serif;
padding-top: 2px;
font-weight: 700;
font-size: 26px;
line-height: 46px !important;
width: 50%;
}
<h3 class="entry-title">
This line very long, have font-size is 26 and line-height is 46px
</h3>
Adding padding might help or put everything in a div and add an Eventlistner to the div
div = document.getElementbyid('divid')
div.addEventlistner('click',function(e){
window.location.assign('url')
})
sorry for poor spellings
Try enclosing the heading itself within the a tags.

How to make a button go down when scrolling? (CSS)

It's header. I want to make these 2 buttons go down with Joblist text when I scroll down.
It SHOULDN'T be like that. I mean these 2 buttons need to stay below the logo always. and when I scroll down, logo and buttons should go down and disappear.
<header>
<div class="header-btn">
Button 1
Button2
</div>
</header>
css
header > .header-btn > a { /* Header buttons styling */
display: inline-block;
text-decoration: none;
font-size: 17px;
color: #f6f6f6;
background-color: rgba(77,85,106,0.8);
letter-spacing: .1em;
padding: 1em 2em;
border-radius: 30px;
border: 1px solid #d6d6d6;
position: absolute;
top: 65%;
margin: 0 15px;
font-family: 'Syncopate', sans-serif;
}
forgot to mention that Im using js for how fast or slow that Joblist text disappears.
var pContainerHeight = $('header').height();
$(window).scroll(function(){
var wScroll = $(this).scrollTop();
if (wScroll <= pContainerHeight) {
$('.logo').css({
'transform' : 'translate(0px, '+ wScroll /4 +'%)'
});
}
You should make those buttons go down with Javascript. Simply add an event listener on the page scroll (as you already do) and, as the user scrolls, add the difference on the position of those two buttons.
Something like this JSFiddle should work:
var original_top = $(".buttons").offset().top
$(window).scroll(function(){
$(".buttons").offset({top: $(this).scrollTop() + original_top})
})
Have you tried setting header position:relative and .header-btn position:absolute. The relative position will scroll and the absolute is in relation to its relative container so it will also scroll.
change position to relative from absolute

Create and Display a Div using JQuery without distorting other elements

I am trying to create a div and show a timeout message in there. But it actually distorts other parts of Page. For eg see below. Session Timed out is the div with the message.
Now I don't want this to happen. PFB the JQuery code I am using to create this Div
function ShowSessionTimeOutDiv() {
var styler = document.createElement("div");
styler.setAttribute("style","font-size:15px;width:auto;height:auto;top:50%;left:40%;color:red;");
styler.innerHTML = "<b><i>Session TimedOut, Please refresh the Page</i></b>";
document.body.appendChild(styler);
var currentDiv = $('#GoToRequestControl1_UpdatePanel1').get(0);
currentDiv.parentNode.insertBefore(styler,currentDiv) ;
}
Am I missing something here? The Part in which this div is being displayed is coming from Master Page.
Have you tried the position:fixed styling on it in css, i did that on one of my websites and it didn't distort anything.
A page has a natural flow of its elements based on the default display rules specified by the W3C. When you add a div in between other elements it naturally affects the layout of the page; the positions of the other elements.
In order to drop in a new element without it affecting other elements you have to either reserve space for it, or take it out of the normal page flow.
There are a couple of ways to take an element out of the flow — you can float it, float:left or float:right, which is great, for example, to stack blocks on the left (instead of top-down) and let them wrap to new rows as available width changes. Using a flex layout gives you a lot of control also. But in this case of one thing popping up, changing the positioning of the new element is the most straightforward and can let you put the block exactly where you want it.
I have a demonstration and full explanation in a fiddle showing several examples along the way to getting what you want.
Basically, styling is needed to reposition the timeout message element that you're inserting. Styling is better done with CSS styles, compared to adding a bunch of inline styles. If I put my timeout popup message in a "messagebox" I can make a class for it.
/* Your styles, plus a couple extra to make the example stand out better */
div.messagebox {
font-size: 16px;
width: auto;
height: auto;
top: 40%;
left: 30%;
background-color: white;
border: 2px solid black;
}
Likewise, style the message itself with a class, instead of using inline styles and the deprecated presentational tags <b> and <i>.
/* I want the message in a messagebox to be bold-italic-red text. */
div.messagebox .message {
color: red;
font-style: italic;
font-weight: bold;
}
The big difference is that we will change the positioning of the element from the default static to instead use absolute positioning:
/* I don't really recommend a class called "positioned".
A class should describe the kind of thing the element *is*
not how it *looks*
*/
div.messagebox.positioned {
position: absolute;
width: 40%;
padding: 1.5em;
}
/* The container of the positioned element also has to be positioned.
We position it "relative" but don't move it from its natural position.
*/
section#hasposition {
position: relative;
}
The term "absolute" is tricky to learn ... the element being positioned is given an absolute position within its container, in a sense it's positioned relative to its container... but what position:relative means is relative to its own natural position, so it's easy to get confused at first over whether you want absolute or relative positioning.
Putting it all together, we have some basic HTML that represents major portions of a page — a real page will have far more, but those should be contained within some top-level containers. This shows only those top-level containers.
Then we have some javascript that will add the new element at the appropriate time. Here I just call the function to add it after a delay created with setTimeout(). I'm using full-on jQuery since you're using some in your example, and it makes the javascript more portable and more concise.
function ShowSessionTimeoutStyled() {
var styler = $('<div>').addClass('messagebox').addClass('positioned');
styler.html('<span class="message">The Session Timed Out</span>');
$('#hasposition .above').after(styler);
}
// wait 6 seconds then add the new div
setTimeout(ShowSessionTimeoutStyled, 6000);
div.messagebox {
font-size: 16px;
width: auto;
height: auto;
top: 20%;
left: 20%;
background-color: white;
border: 2px solid black;
}
div.messagebox .message {
color: red;
font-style: italic;
font-weight: bold;
}
div.messagebox.positioned {
position: absolute;
width: 40%;
padding: 1.5em;
}
section#hasposition {
position: relative;
}
/* also style some of the basic parts so you can see them better in the demonstration */
section.explanation {
margin: 1em 0.5em;
padding: 0.5em;
border: 1px solid gray;
}
.demonstration {
margin-left: 1em;
padding: 1em;
background-color: #e0e0e0;
}
.demonstration .above {
background-color: #fff0f0;
}
.demonstration .middle {
background-color: #f0fff0;
}
.demonstration .below {
background-color: #f0f0ff;
}
.demonstration footer {
background-color: white;
}
p {
margin-top: 0;
padding-top: 0;
}
section {
font-family: sans-serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="explanation">
<p>Here, a div is added dynamically, after the "basic part above", but the added div is <em>positioned</em>. You can see the other content isn't affected.</p>
<section class="demonstration" id="hasposition">
<div class="above">Basic part above</div>
<div class="middle">Middle part</div>
<div class="below">Part Below</div>
<footer>This is the page footer</footer>
</section>
</section>
I highly recommend the site Position Is Everything for articles and tutorials on positioning. Some of its other content is outdated — who needs to make PNGs to do drop-shadows any more? — but the way positioning works hasn't changed.

Unselectable text in div to selectable leaflet

As the title says, I used this (Example)
More specifically I used the info box in top right corner(US Population Density). I modified it to show me some more info onclick etc. Now I have a problem, this div is unselectable. I need to be able to select text (for copy text purpose), instead of selecting the text, it just moves the map. Is there a "quite easy solution" to it, because I can't find the right place. Maybe somehow in CSS?
.info {
position: fixed;
right: 0;
bottom: 23px;
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
/*-webkit-user-select: text;
-moz-user-select: text;
user-select: text;
-webkit-user-drag: text;*/ /*Tried this, didn't work. */
}
.info h4 {
margin: 0 0 100px;
color: #777;
}
Edit: I should add, when I start selecting on other div, then I can select it. As seen on picture, if I start selecting on div where my layers are shown, I can select text, but if I try to directly select from that div (on top right corner of picture) it moves map. I know picture is cut quite small, hope it gives the info/vision wha needed.
Picture: http://www.upload.ee/image/3839164/asd.PNG
Thanks,
Kristjan
Use disableClickPropagation in your controls onAdd method.
onAdd: function (map) {
var container = L.DomUtil.create('div', 'my-custom-control');
container.innerHTML += 'This is an example using disableClickPropagation.';
L.DomEvent.disableClickPropagation(container);
return container;
}
http://jsfiddle.net/9q756/1/
You can fix this by re-enabling pointer-events on the bottom en top control-containers. These get set to none in leaflet.css:
https://github.com/Leaflet/Leaflet/blob/master/dist/leaflet.css#L93
You need to overrule this in your own custom CSS:
.leaflet-top,
.leaflet-bottom {
pointer-events: all;
}

Categories