Must click twice to active onclick event JavaScript - javascript

I need to click twice on the div (class="funfact") in order to active onclick event ff0().
Yes, I included the JS script in the HTML file.
var ffans = document.querySelector(".funfactans");
//ffans = fun fact answer
function ff0() {
if (ffans[0].style.height == '0px') {
ffans[0].style.height = '45px'
ffans[0].style.marginBottom = '10px'
ffans[0].style.paddingRight = '10px'
ffans[0].style.visibility = 'visible'
ffans[0].style.opacity = '1'
ffans[0].style.pointerEvents = 'auto'
}
<div class="facts">
<div class="funfact" onclick="ff0()">Fact1</div>
<div class="funfactans">Fact1 answer</div>
</div>
<script src="mainNew.js"></script>

height="0px" vs visibility and another height is the difference between display:none and display:block
.style.height == '0px' cannot be tested like that
I believe you want this
window.addEventListener("load", function() {
document.querySelector(".facts").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("funfact")) {
tgt.nextElementSibling.classList.toggle("hide");
}
})
})
.funfactans {
height: 45px;
marginBottom: 10px;
paddingRight: 10px;
pointerEvents: auto;
}
.hide {
display: none
}
<title>FunFacts</title>
<div class="facts">
<div class="funfact">Fact1</div>
<div class="funfactans hide">Fact1 answer</div>
<div class="funfact">Fact2</div>
<div class="funfactans hide">Fact2 answer</div>
</div>

Related

jQuery animtion stops when user scrolls

I'm using multiple number elements on my site which are counting up after hitting the visible area of the viewport.
That part works until the user manually scrolls the page. If the user scrolls up or down, the animation stops for a second and repeats when the user don't scroll anymore. It looks very buggy.
If I try to replicate the problem in a fiddle, the same code always works without the "stuttering"?
jQuery(function($) {
$(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i, el) {
function visPx() {
var H = $(this).height(),
r = el.getBoundingClientRect(),
t = r.top,
b = r.bottom;
return cb.call(el, Math.max(0, t > 0 ? H - t : (b < H ? b : H)));
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
$(".fig-number").inViewport(function(px) {
// if px>0 (entered V.port) and
// if prop initNumAnim flag is not yet set = Animate numbers
if (px > 0 && !this.initNumAnim) {
this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 10000,
step: function(now) {
$(this).text(Math.ceil(now));
}
});
}
});
});
html,
body {
height: 100%;
}
.spacer {
height: 100%;
width: 100%;
display: block;
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">1000</h1>
<h1 class="fig-number">1500</h1>
</div>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">2000</h1>
<h1 class="fig-number">2500</h1>
</div>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">3000</h1>
<h1 class="fig-number">3500</h1>
</div>
The working fiddle (same code): https://jsfiddle.net/JSCray/r7g0vn93/3/

Add a div below inline-block wrapped row - Part 2

A solution suggested by #musicnothing in an older thread displays a content div below the row of inline divs, this works good when the div.wrapblock is clicked itself.
http://jsfiddle.net/SYJaj/7/
function placeAfter($block) {
$block.after($('#content'));
}
$('.wrapblock').click(function() {
$('#content').css('display','inline-block');
var top = $(this).offset().top;
var $blocks = $(this).nextAll('.wrapblock');
if ($blocks.length == 0) {
placeAfter($(this));
return false;
}
$blocks.each(function(i, j) {
if($(this).offset().top != top) {
placeAfter($(this).prev('.wrapblock'));
return false;
} else if ((i + 1) == $blocks.length) {
placeAfter($(this));
return false;
}
});
});
The issue I'm having.
I need to trigger the same effect, but by adding the click event to a link within the wrapblock itself.
My code is nearly identical.
What I have changed is the click event handle, from $('.wrapblock').click(function() to $('.more').on('click', function() I also needed to add .closest(".wrapblock") for the content div to position itself outside of the wrapblock.
$('.more').on('click', function() {
...
if ($blocks.length == 0) {
placeAfter($(this).closest(".wrapblock"));
return false;
}
Everything can be seen and tested http://jsfiddle.net/7Lt1hnaL/
Would be great if somebody could shed some light on how I can calculate which block it needs to follow with the offset method, thanks in advance.
As you can see in the latest fiddle example, the content div is not displaying below the row of divs.
I also apologise, I wanted to post on the thread in discussion but I only have a minor posting reputation which doesn't let me, thanks.
var $chosen = null;
var $allBlocks = [];
$(function(){
$allBlocks = $('.wrapblock');
})
$(window).on('resize', function() {
if ($chosen != null) {
$('#content').css('display','none');
$('body').append($('#content'));
$chosen.trigger('click');
}
});
$('.more').on('click', function() {
$chosen = $(this);
var position = $chosen.parent('.wrapblock').position();
$('#content').css('display','inline-block');
$allBlocks.filter(function(idx, ele){
return $(ele).position().top == position.top;
})
.last()
.after($('#content'));
});
.wrapblock
{
background: #963a3a;
display: inline-block;
width: 90px;
height: 90px;
color: white;
font-size: 14px;
text-align: left;
padding: 10px;
margin: 10px;
vertical-align:top;
position:relative;
}
#content
{
display:none;
vertical-align:top;
width:100%;
background: #5582c1;
font-size: 12px;
color: white;
padding: 10px;
}
.more {
position:absolute;
bottom:15px;
right:15px;
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div class="wrapblock">1
<span class="more" data-ref="1">more</span>
</div>
<div class="wrapblock">2
<span class="more" data-ref="2">more</span>
</div>
<div class="wrapblock">3
<span class="more" data-ref="3">more</span>
</div>
<div class="wrapblock">4
<span class="more" data-ref="4">more</span>
</div>
<div class="wrapblock">5
<span class="more" data-ref="5">more</span>
</div>
<div class="wrapblock">6
<span class="more" data-ref="6">more</span>
</div>
<div class="wrapblock">7
<span class="more" data-ref="7">more</span>
</div>
<div class="wrapblock">8
<span class="more" data-ref="8">more</span>
</div>
<div class="wrapblock">9
<span class="more" data-ref="9">more</span>
</div>
<div id="content">Some Content</div>
Seems to do what you want. Basically, it just filters down the set of all blocks to the row of the block you clicked on using the assumption that they'll all have the same vertical offset (top), then takes the last one, because jQuery will keep them in document order, so that'll be the last one in the layout row.
Oh, and I updated the fiddle http://jsfiddle.net/7Lt1hnaL/1/

Disable element scrolling with keyboard arrows

Fiddle
So I'm trying to disable scrolling of a div when another div is visible.
The code bellow I'm using does just that, but only when using mousewheel to scroll.
If I click the scrollbar and drag it, or if I focus the div and use keyboard down button, the scrolling still happens.
Why is that and how can I solve my problem (possibly without overlaying a transparent element over my scrollbar or similar "hacks")?
$('#element').on('scroll mousewheel keydown keypress keyup', function (event) {
const element = $(event.currentTarget);
const shouldScroll = false;
if (!shouldScroll) {
event.preventDefault();
event.stopPropagation();
return false;
}
});
Why don't you do it like this?
var scrollEnabled = true;
var scrollX = 0;
var scrollY = 0;
$(document).ready(function() {
$('div.outer').on('scroll', function(event) {
if (!scrollEnabled) this.scrollTo(scrollX, scrollY);
});
$('#tglBtn').on('click', function(event) {
if (scrollEnabled == true) {
scrollEnabled = false;
scrollX = $('div.outer').scrollLeft();
scrollY = $('div.outer').scrollTop();
} else {
scrollEnabled = true;
}
});
});
div.outer {
height: 500px;
width: 500px;
background-color: red;
overflow-y: scroll;
}
div.inner {
height: 200px;
width: 500px;
}
div.inner:nth-child(odd) {
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="tglBtn" value="Enable/Disable scrolling" />
<div class="outer">
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
</div>

animation is not working as expected

I am trying an animation on the two divs on button click . Here is the demo i have created js fiddle. what i want is
when the user will click on the button the right div will slide to right (it will hide). and the width of left div will become 100%.
on second time when user will click the right div will visible from right to left slide and the width of left div will 50 %
I am trying this code .
my html is
<div class="col-md-12">
<div id="tags-left" class="col-md-6">
div left
</div>
</div>
<div id="tag-div" class="col-md-6">
div right
</div>
</div>
<div class="col-md-12">
<div class="btn-main">
<input id="show-tag" type="button" class="save-btn" value="Show Tag">
<input id="preview" type="button" class="save-btn" value="Preview">
</div>
my js is
$("#show-tag").click(function (e)
{
$( "#tag-div" ).toggle( "slow", function(element) {
//e.preventDefault();
if ($('#tag-div').is(":visible") ) {
$('#tags-left').css('width','50%');
} else {
$('#tags-left').css('width','100%');
}
});
});
$("#show-tag").click(function (e)
{
$( "#tag-div" ).toggle( "slow", function(element) {
//e.preventDefault();
if ($('#tag-div').is(":visible") ) {
$('#tags-left').css('width','50%');
} else {
$('#tags-left').css('width','100%');
}
});
});
.col-md-6 {
width:45%;
float:left;
background:red;
height:200px;
margin:3px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="col-md-12">
<div id="tags-left" class="col-md-6">
div left
</div>
</div>
<div id="tag-div" class="col-md-6">
div right
</div>
</div>
<div class="col-md-12">
<div class="btn-main">
<input id="show-tag" type="button" class="save-btn" value="Show Tag">
<input id="preview" type="button" class="save-btn" value="Preview">
</div>
This one is simple solution without doing much coding see the fiddle: https://jsfiddle.net/uzar3j4q/7/
JS
var action = 1;
$("#show-tag").click(function () {
if ( action == 1 ) {
$("#tag-div" ).animate({'width':'0%',});
$('#tags-left').animate({'width':'90%'});
action = 2;
} else {
$("#tag-div" ).animate({'width':'45%',});
$('#tags-left').animate({'width':'45%'});
action = 1;
}
});
CSS
.col-md-6 {
width:45%;
float:left;
background:red;
height:200px;
margin:3px;
overflow:hidden; /* This property is added just to hide overflowing content */
}
first of all .. put left and right div in same div and in css
CSS
.col-md-12 {
white-space: nowrap;
overflow: hidden;
height:200px;
}
and you can use animate() method in js
JS
$("#show-tag").click(function (e)
{
$( "#tag-div" ).toggle( "slow", function(element) {
//$('#tags-left').css('width','0%');
//e.preventDefault();
if ($('#tag-div').is(":visible") ) {
$('#tags-left').animate({'width':'45%'},500);
} else {
$('#tags-left').animate({'width':'100%'},500);
}
});
});
DEMO HERE
you can just play around that to get the exact action you need
Optimized #Nilesh Mahajan's answer.
Found a problem with it when clicking on the button continuously.
// Caching
var $tagsLeft = $('#tags-left'),
$tagDiv = $('#tag-div');
var tagLeftWidth,
tagDivWidth;
$("#show-tag").on('click', function () {
var $this = $(this);
$this.prop('disabled', true).addClass('disabled'); // Disable the button
tagLeftWidth = $tagDiv.width() ? '90%' : '45%';
tagDivWidth = $tagDiv.width() ? '0%' : '45%';
$tagDiv.animate({
'width': tagDivWidth
}, function() {
$this.prop('disabled', false).removeClass('disabled'); // Enabling button
});
$tagsLeft.animate({
'width': tagLeftWidth
});
});
Demo: https://jsfiddle.net/tusharj/uzar3j4q/11/
Try this html:
<div id="tag-left" class="col-md-6">div left</div>
<div id="tag-right" class="col-md-6">div right</div>
and this javascript:
$("#show-tag").click(function (e) {
if($("#tag-right").width() == 0) {
$("#tag-left").animate({
width: '0'
});
$("#tag-right").animate({
width: '90%'
});
} else {
$("#tag-left").animate({
width: '90%'
});
$("#tag-right").animate({
width: '0'
});
}
});
jsfiddle

Function acting funny on resize

I have this banner ticker which works as you first load the page, but it gets messed up as you resize the second time and my assumption is that I am not calling the function in the right way on the resize event, any advice so I can understand what is going on?
jsfiddle
html
<div class="">
<div class="topBanners" style="float: left; width: 200px; ">
<p>First one</p>
</div>
<div class="topBanners" style="float: left; width: 200px; ">
<p>Second</p>
</div>
<div class="topBanners" style="float: left; width: 200px; ">
<p>Third</p>
</div>
</div>
js
$(document).ready(function() {
currentTopBanner = 0;
var topBanners = $('.topBanners');
console.log(topBanners.length);
function rotateTopBanners() {
if ($(window).width() < 768) {
topBanners.hide();
$(topBanners[currentTopBanner]).fadeIn('slow').delay(100).fadeOut('slow');
$(topBanners[currentTopBanner]).queue(function () {
currentTopBanner = currentTopBanner < topBanners.length - 1 ? currentTopBanner + 1 : 0;
rotateTopBanners();
$(this).dequeue();
});
} else {
topBanners.show();
}
}
rotateTopBanners();
$(window).resize(function () {
rotateTopBanners();
});
});

Categories