JQuery .width() returns inconsistent values - javascript

I try to get the width of a specific element with JQuery.
Sometimes, .width() returns the right value, sometimes one that is too little (this happens random on a few page loads)
So most of the time I get the right value when I load my page, but sometimes something gets messed up.
I thought, that my code firing too early (when css is not loaded or something similar) might cause this, but even after I started to use $(window).bind("load", function(){ ... code goes here ...}), the situation hasn't really changed.
My code:
$(document).ready(function () {
$(".section-content .feature-details").each(function (index, object) {
var featureDetails = $(object);
featureDetails.find(".details-content").width(featureDetails.find(".details-navigation").width());
console.log(featureDetails.find(".details-navigation").width());
});
EDIT:
(If I do a setTimeout, everything works fine, so this problem has to be related to some form of async loading, which isn't "fast enough" - right?)
The exact code I use:
JavaScript:
$(document).ready(function () {
// setTimeout(function () {
$(".section-content .feature-details").each(function (index, object) {
var featureDetails = $(object);
featureDetails.find(".details-content").width(featureDetails.find(".details-navigation").width());
console.log(featureDetails.find(".details-navigation").width());
});
// }, 100);
});
HTML:
<div class="feature columns columns-justify-fullwidth columns-vertical-align-center">
<div class="feature-details">
<div class="details-navigation">
<ul>
<li><div>Web</div></li>
<li class="active"><div>Desktop</div></li>
<li><div>Mobile</div></li>
<li><div>Datenbanken</div></li>
</ul>
</div>
<div class="details-content">
<p>
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
<br/>
<br/> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
</p>
</div>
</div>
<div class="showcase"></div>
</div>
CSS:
.columns {
display: flex;
}
.columns-justify-fullwidth {
justify-content: space-between;
}
.columns-vertical-align-center {
align-items: center;
}
.feature-details .details-navigation {
display: inline-block;
}
.feature-details .details-navigation ul {
display: inline-block;
height: 50px;
border-bottom: 2px solid #aaa;
}
.feature-details .details-navigation li {
height: 100%;
display: inline-block;
vertical-align: top;
}
.feature-details .details-navigation li:not(:last-child) {
margin-right: 18px;
}
.feature-details .details-navigation ul a {
display: table;
height: 100%;
font-size: 16px;
}
.feature-details .details-navigation ul a > div {
display: table-cell;
padding-bottom: 12px;
vertical-align: bottom;
}
/*
.feature-details .details-navigation ul li:hover {
border-bottom: 2px solid #222;
}
*/
.feature-details .details-navigation ul li:hover a {
color: #222;
}
.feature-details .details-navigation li.active {
border-bottom: 2px solid #222;
}
.feature-details .details-content {
margin-top: 16px;
}
.feature .showcase {
width: 450px;
height: 450px;
background-color: #f7f7f7;
}

Try using jQuery $( document ).ready and see if the results are more consistent. I am not able to get any inconsistent widths.
$(document).ready(function() {
$(".feature-details").each(function(index, object) {
var featureDetails = $(object);
featureDetails.find(".details-content").width(featureDetails.find(".details-navigation").width());
console.log(featureDetails.find(".details-navigation").width());
})
})

Related

Unable to insert element before and after (both) in jQuery

I am using jQuery 3.x. I am trying to append a dynamically created element before and after an element using insertBefore() and insertAfter(). However, only insertBefore() is working, and another one is ignored. When I am commenting one then other is working. why?
p = $("<p></p>").text("This is a dynamicly created element");
p.insertAfter($('nav'));
p.insertBefore($('nav'));
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 20px;
}
header,
nav,
main,
aside,
footer {
padding: 10px 15px;
border: 1px solid mediumseagreen;
text-align: center;
}
header {
background: dodgerBlue;
}
nav {
background: mediumSeaGreen;
}
main {
background: #d3d3d3;
}
main,
aside {
height: 1200px;
}
main {
width: 80%;
float: left;
}
aside {
width: 20%;
float: right;
}
div::after {
content: " ";
float: none;
clear: both;
display: table;
}
main {
text-align: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
This is header
</header>
<nav>
This is navbar
</nav>
<main>
<article>
<h2>This is heading</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Cum atque fuga, eos neque ipsum enim id inventore necessitatibus laboriosam quo nobis, repellendus maxime veritatis error ut expedita, velit aspernatur asperiores!
</p>
</article>
</main>
<aside>
This is side bar
</aside>
<div></div>
<footer>
This is footer
</footer>
The issue is because the p references only a single element. You insert it in to the DOM in the insertAfter() call, then move the same element to a new location using insertBefore().
To do what you require you can clone() the element before the second insertion. Also note that you don't need to create an entire jQuery object to select nav, you can just pass the selector as a string. Try this:
let p = $("<p />", {
text: "This is a dynamicly created element"
});
p.insertAfter('nav');
p.clone().insertBefore('nav');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 20px;
}
header,
nav,
main,
aside,
footer {
padding: 10px 15px;
border: 1px solid mediumseagreen;
text-align: center;
}
header {
background: dodgerBlue;
}
nav {
background: mediumSeaGreen;
}
main {
background: #d3d3d3;
}
main,
aside {
height: 1200px;
}
main {
width: 80%;
float: left;
}
aside {
width: 20%;
float: right;
}
div::after {
content: " ";
float: none;
clear: both;
display: table;
}
main {
text-align: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>This is header</header>
<nav>This is navbar</nav>
<main>
<article>
<h2>This is heading</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Cum atque fuga, eos neque ipsum enim id inventore necessitatibus laboriosam quo nobis, repellendus maxime veritatis error ut expedita, velit aspernatur asperiores!
</p>
</article>
</main>
<aside>This is side bar</aside>
<div></div>
<footer>This is footer</footer>
One other thing to mention, I would suggest researching flexbox layouts. They're a much more modern and extensible technique than forcing display: table on a div to create a multi-column layout.

Can't apply margin-right to relatively positioned element

I am working in Vue to build a series of cards that scroll across a mobile screen in the x-direction. It's sort of like a testimonial section where the user can scroll right or left to see new testimonials.
I am able to apply a left margin to the cards however I can't add a right margin to the final card so that it can be scrolled into the center of the screen.
Here is the code sandbox: https://6ky1r.csb.app/
Note, this is designed for the mobile but you can see the issue on the desktop view also.
When you scroll all the way to the right the white background of the card goes all the way to the edge which is not desired.
<template>
<div class="homePageTwo">
<div class="cardHolder">
<div class="cardSpace" v-for="card in cards" :key="card.index">
<SlidingCard :title="card.title" :content="card.content" :icon="card.icon"/>
</div>
</div>
</div>
</template>
<script>
import SlidingCard from "./SlidingCard.vue";
export default {
name: "App",
components: {
SlidingCard
},
data() {
return {
cards: [
{
title: "Food Services",
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
},
{
title: "Assisted Living",
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
},
{
title: "Retail",
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
},
{
title: "Education",
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
}
]
};
}
};
</script>
<style>
.homePageTwo {
height: 100vh;
background-color: #f7f8fc;
padding-top: 3rem;
}
.cardHolder {
display: flex;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: mandatory;
scroll-snap-type: x mandatory;
}
.cardSpace {
padding: 2.5rem;
background-color: #ffffff;
margin-left: 1rem;
margin-right: 1rem;
}
</style>
<template>
<div class="slidingCard">
<div class="photoHolder">
<img class="homePageOneImg" :alt="alt" :src="icon">
</div>
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
</template>
<script>
export default {
name: "SlidingCard",
data() {
return {};
},
props: ["title", "content", "icon", "alt"]
};
</script>
<style scoped>
.slidingCard {
background-color: #ffffff !important;
width: 60vw;
display: inline-flex;
flex-direction: column;
position: relative;
scroll-snap-align: center;
}
.photoHolder {
height: 10rem;
line-height: 10rem;
border-radius: 90px;
background-color: #f7f8fc;
width: 8rem;
margin: auto;
}
img {
vertical-align: middle;
height: 75px;
width: 75px;
}
h1 {
font-size: 18px;
font-weight: bold;
}
p {
font-size: 1rem;
white-space: normal !important;
}
</style>
See margin collapsing.
I see a couple of simple fixes:
Option 1:
Adding margin: 0 1rem; to the cardHolder.
Option 2:
Add a hidden border after the last child. See this.

How to add a class to the div when article visible on screen?

I am displaying articles horizontally on the mouse wheel. I have to display the menu div on top when articles 5 comes on the screen. I mean I want to add class to the element when it gets visible on screen when scrolling. I tried some script but it not working.
I set display:none on the class .about_menu and using the script I am adding the class .active display: block but how can I identify the articles 05 come on screen?
Would you help me out in this?
$(window).on('scroll', function(){
if ($(".active_05").is(':visible')){
$(".about_menu").addClass("active");
}
});
(function() {
function scrollHorizontally(e) {
e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
document.getElementById('gentags').scrollLeft -= (delta*40); // Multiplied by 40
e.preventDefault();
}
if (document.getElementById('gentags').addEventListener) {
// IE9, Chrome, Safari, Opera
document.getElementById('gentags').addEventListener("mousewheel", scrollHorizontally, false);
// Firefox
document.getElementById('gentags').addEventListener("DOMMouseScroll", scrollHorizontally, false);
} else {
// IE 6/7/8
document.getElementById('gentags').attachEvent("onmousewheel", scrollHorizontally);
}
})();
#gentags {
position:relative;
margin-top: -.25em;
display: inline-block;
width: 100%;
overflow-x: scroll;
overflow-y: hidden;
}
#gentags > div{
overflow: hidden;
width:200%;
}
::-webkit-scrollbar {
width: 0px; /* remove scrollbar space */
background: transparent; /* optional: just make scrollbar invisible */
}
/* optional: show position indicator in red */
::-webkit-scrollbar-thumb {
background: transparent;
}
.horizontal_scroll .full_screen_100 article{
width: 16.58%;
height: 100%;
float:left;
border-left: solid 1px #E2E2E2;
}
.active{
display: block !important;
}
.about_menu{
position: fixed;
width: 100%;
text-align: center;
display: none;
}
.about_menu .about_menu_wrapper ul.about_menu_list{
list-style: none;
text-decoration: none;
}
.about_menu .about_menu_wrapper ul.about_menu_list li{
display: inline-block;
text-decoration: none;
margin: 10px;
}
.about_menu .about_menu_wrapper ul.about_menu_list li a{
font-size: 18px;
color: red
}
.about_menu .about_menu_wrapper ul.about_menu_list li a:hover{
color: #000;
}
<div class="about_menu">
<div class="about_menu_wrapper">
<ul class="about_menu_list">
<li>About us</li>
<li>Team</li>
<li>Clients</li>
</ul>
</div>
</div>
<div id="gentags">
<div class="horizontal_scroll">
<div class="full_screen_100" id="left_scroll">
<article><div><p class="scroll_number">01</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article><div><p class="scroll_number">02</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article><div><p class="scroll_number">03</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article><div><p class="scroll_number">04</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article class=" active_05"><div><p class="scroll_number">05</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article><div><p class="scroll_number">06</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Try this https://jsfiddle.net/wy9o3oh8/1/
Find right side offset of the active_05 if it is >0 then show menu
var rt = ($(window).width() - ($(".active_05").offset().left ));
if(rt>0)
{
$(".about_menu").addClass("active");
}
(function() {
function scrollHorizontally(e) {
e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
document.getElementById('gentags').scrollLeft -= (delta*40); // Multiplied by 40
var rt = ($(window).width() - ($(".active_05").offset().left ));
if(rt>200)
{
$(".about_menu").addClass("active");
}
else
{
$(".about_menu").removeClass("active");
}
e.preventDefault();
}
if (document.getElementById('gentags').addEventListener) {
// IE9, Chrome, Safari, Opera
document.getElementById('gentags').addEventListener("mousewheel", scrollHorizontally, false);
// Firefox
document.getElementById('gentags').addEventListener("DOMMouseScroll", scrollHorizontally, false);
} else {
// IE 6/7/8
document.getElementById('gentags').attachEvent("onmousewheel", scrollHorizontally);
}
})();
#gentags {
position:relative;
margin-top: -.25em;
display: inline-block;
width: 100%;
overflow-x: scroll;
overflow-y: hidden;
}
#gentags > div{
overflow: hidden;
width:200%;
}
::-webkit-scrollbar {
width: 0px; /* remove scrollbar space */
background: transparent; /* optional: just make scrollbar invisible */
}
/* optional: show position indicator in red */
::-webkit-scrollbar-thumb {
background: transparent;
}
.horizontal_scroll .full_screen_100 article{
width: 16.58%;
height: 100%;
float:left;
border-left: solid 1px #E2E2E2;
}
.active{
display: block !important;
}
.about_menu{
position: fixed;
width: 100%;
text-align: center;
display: none;
}
.about_menu .about_menu_wrapper ul.about_menu_list{
list-style: none;
text-decoration: none;
}
.about_menu .about_menu_wrapper ul.about_menu_list li{
display: inline-block;
text-decoration: none;
margin: 10px;
}
.about_menu .about_menu_wrapper ul.about_menu_list li a{
font-size: 18px;
color: red
}
.about_menu .about_menu_wrapper ul.about_menu_list li a:hover{
color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="about_menu">
<div class="about_menu_wrapper">
<ul class="about_menu_list">
<li>About us</li>
<li>Team</li>
<li>Clients</li>
</ul>
</div>
</div>
<div id="gentags">
<div class="horizontal_scroll">
<div class="full_screen_100" id="left_scroll">
<article><div><p class="scroll_number">01</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article><div><p class="scroll_number">02</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article><div><p class="scroll_number">03</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article><div><p class="scroll_number">04</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article class=" active_05"><div><p class="scroll_number">05</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
<article><div><p class="scroll_number">06</p><span class="page_slogan">Lorem ipsum dolor sit amet, </span></div></article>
</div>
</div>
</div>
From your comment check this updated version
https://jsfiddle.net/wy9o3oh8/3/
change the value of 50 how you want

Animating content from a div that is displayed inside another div

Really new to jquery, so any help appreciated it.
Trying to solve a design challenge. I needed to display the content from a div inside another div, on hover of a third element.
Found some code that helped me put it together, but I wonder if there is a way to animate (slidedown, fadein, etc.) the content when is displayed.
Any idea how can I apply animation to the .html function when it displays the content?
var divContent = $("#explore-agility-content").html('');
$( ".industry" ).hover(
function() {
$("#explore-agility-content").html( $( this).find("#shortdesc").html() );
},
function() {
$("#explore-agility-content").html( divContent );
}
);
https://jsfiddle.net/rnwebdesigner/3wyrwd92/71/
Here are fadeIn fadeOut effects on hover and mouseout
check this fiddle
https://jsfiddle.net/parthjasani/3wyrwd92/72/
var divContent = $("#explore-agility-content").html('');
$(".industry").hover(
function () {
$("#explore-agility-content").html($(this).find("#shortdesc").html());
$("#explore-agility-content .wb").hide().fadeIn()
},
function () {
$("#explore-agility-content .wb").fadeOut(function () {
$("#explore-agility-content").html(divContent);
})
}
);
You can add and remove css classes which can contain several properties to be transitioned on mouse enter and leave..
See snippet below (solution 1)
$('.image').mouseenter(function(){
$(".text").addClass("animate")
});
$('.image').mouseleave(function(){
$(".text").removeClass("animate")
});
.image {
width: 50px;
height: 50px;
display: block;
background-color: red;
}
.text {
background-color: white;
padding:40px;
transition:all 0.5s;
}
.left {
display:block;
height:400px;
width: 400px;
background: url('http://i.stack.imgur.com/jGlzr.png') no-repeat 0 0 scroll;
background-color:#0C0C0C;
background-size: 100% 100%;
}
.animate{
opacity:1 !important;
padding-top:50px;
}
.noanimate{
opacity:0;
padding-top:-50px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image"></div>
<div class="left">
<div class="text noanimate">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt consequat tristique. Curabitur vestibulum semper nulla id ornare.
</div>
</div>
Solution 2 - using hover function instead of mounseenter and leave
$('.image').hover(function(){
$(".text").toggleClass("animate")
});
.image {
width: 50px;
height: 50px;
display: block;
background-color: red;
}
.text {
background-color: white;
padding:40px;
transition:all 0.5s;
}
.left {
display:block;
height:400px;
width: 400px;
background: url('http://i.stack.imgur.com/jGlzr.png') no-repeat 0 0 scroll;
background-color:#0C0C0C;
background-size: 100% 100%;
}
.animate{
opacity:1 !important;
padding-top:50px;
}
.noanimate{
opacity:0;
padding-top:-50px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image"></div>
<div class="left">
<div class="text noanimate">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt consequat tristique. Curabitur vestibulum semper nulla id ornare.
</div>
</div>

Dropdown javascript block

I have a problem with javascript dropdown clicking menu.
I need show some content after clicking header of box.
HTML
<div id='cookiemenu'>
<div class='cookiemenu_header' onclick='ShowCookieBox()'>
Test
</div>
<div id="cookiemenu_dropwdown" class='cookiemenu_content'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus mollis magna sed scelerisque hendrerit.
</div>
</div>
CSS
#cookiemenu {
width:100%;
overflow: hidden;
display:block;
}
#cookiemenu div.cookiemenu_header {
width:100%;
display:block;
margin-top: 0px;
background-color: #0B3954;
color:#FFFFFF;
text-align: center;
height: 25px;
font-size: 20px;
line-height: 25px;
}
#cookiemenu div.cookiemenu_header:hover, div.cookiemenu_header:target {
cursor: hand;
text-decoration: underline;
}
div.cookiemenu_content {
}
.ShowCookieBox {
display:block;
border:2px solid #red;
}
JS
<script>
function ShowCookieBox() {
document.getElementById("cookiemenu_dropdown").classList.toggle("ShowCookieBox");
}
</script>
It's not working at all. Can someone tell me why?
And the second question. Is there any chance to change the JS so It could save "status" of box (showed or hidden) in cookies? So user can leave it, close page and on the next visit it stays as he leaved it?
You have two typos.
The id of the div should be cookiemenu_dropdown on the div, but it is currently cookiemenu_dropwdown.
Also the color is just red not #red.
function ShowCookieBox() {
document.getElementById("cookiemenu_dropdown").classList.toggle("ShowCookieBox");
}
#cookiemenu {
width:100%;
overflow: hidden;
display:block;
}
#cookiemenu div.cookiemenu_header {
width:100%;
display:block;
margin-top: 0px;
background-color: #0B3954;
color:#FFFFFF;
text-align: center;
height: 25px;
font-size: 20px;
line-height: 25px;
}
#cookiemenu div.cookiemenu_header:hover, div.cookiemenu_header:target {
cursor: hand;
text-decoration: underline;
}
div.cookiemenu_content {
}
.ShowCookieBox {
display:block;
border:2px solid red;
}
<div id='cookiemenu'>
<div class='cookiemenu_header' onclick='ShowCookieBox()'>
Test
</div>
<div id="cookiemenu_dropdown" class='cookiemenu_content'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus mollis magna sed scelerisque hendrerit.
</div>
</div>
Change your CSS rules to
div.cookiemenu_content.ShowCookieBox {
display: block;
border:2px solid red;
}
div.cookiemenu_content {
display: none;
}
The display: block from .ShowCookieBox was being overwritten by display: none from the div.cookiemenu_content rules when the ShowCookieBox class was applied.
Check the jsfiddle

Categories