JQuery .animate() only works in Chrome - javascript

I am using the JQuery .animate() function to slide divs in a container div. This works without issue in Google Chrome, but when I try in either Firefox or IE, the divs become a garbled mess and don't actually slide. I'm new to Javascript and ignorant in the ways of browser compatibility, can anyone point me in the right direction? Here is the relevant code:
The HTML
<div id="slider">
<div id="main" class="content">
</div>
<div id="projects" class="content">
</div>
<div id="about" class="content">
</div>
<div id="contact" class="content">
</div>
</div>
The CSS
#slider {
width: 100px;
height: 100px;
overflow: hidden;
position: relative;
}
#main {
background-color: red;
width: inherit;
height: inherit;
position: absolute;
}
#projects {
background-color: blue;
width: inherit;
height: inherit;
position: absolute;
}
#about {
background-color: yellow;
width: inherit;
height: inherit;
position: absolute;
}
#contact {
background-color: green;
width: inherit;
height: inherit;
position: absolute;
}
.content {
left: 0;
top: 0;
}
The JavaScript
$(document).ready(function() {
var contentWidth = '100px';
for( var i=0; i < 2; i++) {
$('.gallery' + (i + 1)).colorbox({ opacity:0.5 , rel:'gallery' + (i+1)});
}
$('.content').css({
position: 'absolute',
left: contentWidth
});
$('#main').addClass('visible');
document.getElementById('main').style.left = "0";
$("li a").click(function () {
event.preventDefault();
var $blockID = $( $(this).attr('href') );
if ($blockID.hasClass('visible')) { return; }
$('.content.visible')
.removeClass('visible')
.animate({ left: '-=100px' }, {
duration: 'slow',
complete: function () {
$(this).css('left', '100px');
}
}
);
$blockID
.addClass('visible')
.animate({ left: 0 }, {duration: 'slow'});
});
});
JSFiddle: http://jsfiddle.net/bwvVZ/
I can also provide a link to the site in question, although I will hold off because I am not sure if its against the rules. Any help is much appreciated!

You are missing the event argument from your click handler
$("li a").click(function(){
event.preventDefault();
//...
});
It should be
$("li a").click(function (event){
event.preventDefault();
//...
});
DEMO.

Can't test in IE myself but this fixes Firefox and the returnValue should fix IE. CSSDeck Test - I can't access jsfiddle from my current location.
$("li a").click(function (event){
event.returnValue = false; //ie
if(event.preventDefault) //prevents error if not found
event.preventDefault();
var $blockID = $($(this).attr('href'));
...

Related

Adding and removing class at div top?

I am trying to make a class fade in when 'register' class div top enters the window and otherwise have the class fade out
How can I make this work?
$(window).scroll(function() {
var tint = $('.register').offset().top;
if ($(this).scrollTop() > tint) {
$('.tint').fadeIn(1000);
} else {
$('.tint').fadeOut(1000);
}
});
section {
height: 100vh;
width: 100%;
}
.tint {
background-color: #000;
width: 100%;
height: 100vh;
opacity: 0.6;
position: absolute;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section></section>
<section class="register">
<div class="tint"></div>
<div>Content</div>
</section>
Class example code you posted seems to work correctly, I think you should check css also if there is any problem. But if want any other methods then here are some methods: you can use fadIn() - fadeOut(), or hide() - show() or css visibility or display block and none , or simply can jquery UI animate functionality. Here is animation example to hide div jquery animate
$(window).scroll(function() {
var top_of_element = $("#element").offset().top;
var bottom_of_element = $("#element").offset().top + $("#element").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
var top_of_screen = $(window).scrollTop();
if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
// the element is visible, do something
} else {
// the element is not visible, do something else
}
});
$(window).scroll(function() {
var tint = $('.register').offset().top;
if ($(this).scrollTop() > tint) {
$('.register').fadeIn();
// OR
//$(".register").show();
// OR
//$(".register").css('visibility', 'visible');
} else {
$('.register').fadeOut();
// OR
//$(".register").hide();
// OR
//$(".register").css('visibility', 'hidden');
}
});
.tint {
background-color: #000;
width: 100%;
height: 100vh;
opacity: 0.6;
position: absolute;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="register">
<div class="tint"></div>
<div>Content</div>
</section>
The only problem, that you've passed a string to fadeOut, which expects a number.
So, remove the quotes around '1000', and you'll be right:
$(window).scroll(function() {
var tint = $('.register').offset().top;
if ($(this).scrollTop() > tint) {
$('.tint').fadeIn(1000);
} else {
$('.tint').fadeOut(1000);
}
});
section {
height: 100vh;
width: 100%;
}
.tint {
background-color: #000;
width: 100%;
height: 100vh;
opacity: 0.6;
position: absolute;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section></section>
<section class="register">
<div class="tint"></div>
<div>Content</div>
</section>

jQuery: Finish dragging without triggering click event

I am trying to set up the following page where:
If you click the button, you can see a div.
If you click the div, you can see the next div.
If you move the button, there is no »click« (desired behaviour)
The problem I am having is that if you move the div, the next div appears - this is not what I want. The "next div" should not be displayed after a drag event finishes on it.
Here is my code:
$(function() {
$("#button").draggable({
stack: 'div',
containment: "body"
});
});
$('#button').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
// click function
$("#content").toggle();
}
});
$(function() {
$("#content").draggable({
stack: 'div',
containment: "body"
});
});
let containers = $('.trip').hide();
let firstContainer = containers.first().show();
containers.on('click', function() {
//Get current element and next sibling
let elem = $(this);
let next = elem.next('.trip');
//Does sibling exist?
if (next.length) {
next.show();
} else {
firstContainer.show();
}
elem.hide();
});
body {
width: 100vw;
height: 100vh;
padding: 0;
margin: 0;
left: 0;
top: 0;
background-color: grey;
}
#button {
width: 100px;
height: 100px;
background-color: cyan;
}
#content {
display: none;
cursor: all-scroll;
top: 10%;
left: 10%;
position: absolute;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
<div id="button">Button</div>
<div id="content">
<div class="trip">div 1</div>
<div class="trip">div 2</div>
<div class="trip">div 3</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
Is there a way to solve this? :)
(a possible problem is also that pure JavaScript is mixed with jQuery)
Thanks
The main problem to solve here is in distinguishing a regular click event on #content, from other "click like events" that are also triggered during completion of the element being dragged.
You're code currently has a method of doing that which you could re purpose for the desired behaviour:
if (! $(this).hasClass('ui-draggable-dragging')) {
/* This was a "regular click event"
}
So in the case of your code, you could revise it as follows:
$(function() {
/* Combine on ready logic into one place */
$("#button").draggable({
stack: 'div',
containment: "body"
});
$("#content").draggable({
stack: 'div',
containment: "body"
});
/* Hide all trip elements except for first */
$('.trip', '#content').not(':first').hide();
});
$('#button').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
$("#content").toggle();
}
});
$('#content').on('mouseup', function() {
/* Reuse same logic in #button mouseup handler */
if (!$(this).hasClass('ui-draggable-dragging')) {
/*
If content element if not dragging, treat mouse up as conclusion
of click event and rotate visibility of trip elements like this
*/
let trip = $('.trip:visible', '#content');
let next = trip.next().length === 0 ?
$('.trip:first', '#content') : trip.next();
trip.hide();
next.show();
}
});
body {
width: 100vw;
height: 100vh;
padding: 0;
margin: 0;
left: 0;
top: 0;
background-color: grey;
}
#button {
width: 100px;
height: 100px;
background-color: cyan;
}
#content {
display: none;
cursor: all-scroll;
top: 10%;
left: 10%;
position: absolute;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
<div id="button">Button</div>
<div id="content">
<div class="trip">div 1</div>
<div class="trip">div 2</div>
<div class="trip">div 3</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
Actually, all you need is this bit of readable code,
Assign a class .draggable to all your draggable elements
Use the new class as stack: '.draggable'
Register click to your '#container', not on your .trip elements
Use only one Event, the "click" one:
Hide all .trip but first using CSS .trip~.trip {display:none;}
jQuery( $ => {
const $cont = $('#content');
const $bttn = $('#button');
const $trip = $('.trip');
const tripL = $trip.length;
let i = 0;
$('.draggable').draggable({stack:'div', containment:'body'});
$bttn.on('click', function() {
if (!$(this).hasClass('ui-draggable-dragging')) $cont.toggle();
});
$cont.on('click', function() {
$trip.eq(++i % tripL).show().siblings($trip).hide();
});
});
html, body { height:100%; margin:0;}
body {
background-color: grey;
}
#button {
width: 100px;
height: 100px;
background-color: cyan;
}
#content {
display: none;
cursor: all-scroll;
top: 10%;
left: 10%;
position: absolute;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
.trip ~ .trip {display: none;}
<!-- PS: Add class="draggable" to draggable elements -->
<div id="button" class="draggable">Button</div>
<div id="content" class="draggable">
<div class="trip" id="a">div 1</div>
<div class="trip" id="b">div 2</div>
<div class="trip" id="c">div 3</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
EDIT
For more contents see this answer: https://stackoverflow.com/a/57351517/383904

How to make a popup disappear only when clicked anywhere outside of it

I'm trying to toggle a popup when click on a specific link and then remove class ".open" from it when clicked anywhere other than the popup box.
Using below methods I was able to get the popup disappear when clicked outside of it but it's now also getting disappear when clicked inside the popup area.
$(".onclick-dropdown-link, .user-message-center-link").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
var id = $this.attr('href');
$('.onclick-dropdown').not(id).removeClass('open');
$(id).toggleClass('open');
});
$('body:not(.onclick-dropdown.open)').click(function(e) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
});
.onclick-dropdown {
opacity: 0;
visibility: hidden;
background: #f3f3f3;
width: 390px;
height: 390px;
position: absolute;
top: 128px;
right: 28px;
height: auto;
padding: 0;
z-index: 999;
}
.onclick-dropdown.open {
opacity: 1;
visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="alert-center-link">
<a class="onclick-dropdown-link" href="#alert-center">The Link</a>
</li>
</ul>
<div id="alert-center" class="onclick-dropdown">
<p>Lorem Ipusm</p>
</div>
Change your .click() function to the following:
$(document).click(function(e) {
if( !$('.onclick-dropdown').is(e.target) && !$('.onclick-dropdown').children().is(e.target)) {
if( $('.onclick-dropdown').hasClass('open') ) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
}
}
});
Change your Popup HTML to :
<div id="alert-center-outer" class="onclick-dropdown">
<div id="alert-center">
//CONTENT HERE...
<p>Lorem Ipusm</p>
</div>
</div>
#alert-center-outer{
position: fixed;
left; 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0.5;
background-color: black;
}
#alert-center{
width: 200px;
height: 300px;
margin: 0 auto;/*This will center align it.*/
}
Clicking the #alert-center-outer should hide the popup.
Clicking the #alert-center should stopPropagation so that it doesn't bubble to its parent.
try below code
$(document).ready(function(){
$(".onclick-dropdown-link, .user-message-center-link").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
var id = $this.attr('href');
$('.onclick-dropdown').not(id).removeClass('open');
$(id).toggleClass('open');
});
$(document).click(function(e) {
if (!$(e.target).closest('.onclick-dropdown').length)
$("#alert-center, #message-center, #user-message-center").removeClass('open');
});
})
.onclick-dropdown {
opacity: 0;
visibility: hidden;
background: #f3f3f3;
width: 390px;
height: 390px;
position: absolute;
top: 128px;
right: 28px;
height: auto;
padding: 0;
z-index: 999;
}
.onclick-dropdown.open {
opacity: 1;
visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="alert-center" class="onclick-dropdown">
<p>Lorem Ipusm</p>
</div>
<li class="alert-center-link"><a class="onclick-dropdown-link" href="#alert-center">asdfsdfsdfds</a></li>
// only trigger once
$('body').one('click', function(e) {
var $target = $(e.target);
// the $target which trigger click event is not the popup dom itself
// and also is not the children dom of the popup
if (!$target.is('#alert-center') && $target.parents('#alert-center').length === 0) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
}
})
Is that what you want?
Now you can add any tags in the popup, and click inside the popup area where not hide it.

Rest of divs are shown when resizing browser in single page website

I am developing a single page website, the page is composed by a header and a footer, both fixed at top and bottom respectively and the content in the middle.
The content is a div with 100% of width and height.
At the header there is a menu to access the sections with smooth scrolling, everything works fine at this point, but when I choose the third section and resize the browser I can see the divs above and below, which should be hidden.
I tried to position the current div absolute with addClass/removeClass and modify the height when resize but did not work either.
This is the code:
CSS:
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
background-color: red;
overflow: hidden;
}
#cabecera, #footer {
width: 100%;
height: 50px;
background-color: #D1D1D1;
position: fixed;
left: 0;
z-index: 1000;
}
#cabecera {
top: 0;
}
#footer {
bottom: 0;
}
#menu li {
list-style: none;
float: left;
margin-right: 10px;
}
#menu li span {
cursor: pointer;
}
.centrar {
width: 960px;
margin: 0 auto;
}
#section1 {
background-color: #fbfbfb;
}
#section2 {
background-color: #017EFF;
}
#section3 {
background-color: #9F25F6;
}
#section4 {
background-color: #FB8114;
}
#section5 {
background-color: #373737;
}
.layout {
width: 100%;
height: 100%;
}
.active {
position: absolute;
top: 0;
left: 0;
}
</style>
JAVASCRIPT:
<script type="text/javascript">
$(document).ready(function(){
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash;
var $target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing');
/*$("#section1").removeClass("active");
$("#section2").removeClass("active");
$("#section3").removeClass("active");
$("#section4").removeClass("active");
$("#section5").removeClass("active");*/
/*$target.addClass("active");*/
});
/*$(window).resize(function () {
var doc = $(document).height() || $(window).height();
var cabecera = $("#cabecera").height();
var footer = $("#footer").height();
var margin = doc - cabecera - footer;
$('#section3').css({ 'min-height': + margin + 'px' });
});
$(window).resize();*/
});
</script>
HTML:
<body>
<div id="cabecera">
<div class="centrar">
<ul id="menu">
<li>section1</li>
<li>section2</li>
<li>section3</li>
<li>section4</li>
<li>section5</li>
</ul>
</div>
</div>
<div id="section1" class="layout"></div>
<div id="section2" class="layout"></div>
<div id="section3" class="layout"></div>
<div id="section4" class="layout"></div>
<div id="section5" class="layout"></div>
<div id="footer">
<div class="centrar"></div>
</div>
</body>
EDIT:
Screenshot normal browser //
Screenshot resized browser
Steps to reproduce:
1) Open the browser resized to a small window
2) Open the page
3) Go to "section3"
4) Change the height of the browser, increasing or decrementing
5) Take a look at the divs above and below :S
You have to scroll to the top of the selected element(initialized on first) on the resize event of the window without any animation so that it gets executed transparently for the visitor.
The $target variable needs to be declared "globally" so that the resize function will know which was the last accessed section.
<script type="text/javascript">
$(document).ready(function(){
var $target = $(".layout:first");
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash;
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing');
});
$(window).resize(function(){
$(window).scrollTop($target.offset().top);
});
});
</script>

How can i check if multiple divs have been clicked in JS?

I'm trying to "track" if all divs have been clicked. If all divs have been clicked something should happen. This can only happen when all divs have been clicked.
http://jsbin.com/cawukapumi/1/
This is what i've gathered so far.
Any help is more then appreciated.
$(document).ready(function(){
$(".masterobject").click(function() {
$(this).data('clicked, true');
});
if ($('#obj1').data('clicked') && $('#obj2').data('clicked') && $('#obj3').data('clicked') && $('#obj4').data('clicked') && $('#obj5').data('clicked') ) {
console.log( "all has been clicked" );
}
});
.masterobject {
position: absolute;
background-color: red;
z-index: 2;
}
#obj1 {
width: 50px;
height: 60px;
top: 25%;
left: 19%;
}
#obj2 {
width: 150px;
height: 100px;
top: 12%;
left: 84%;
}
#obj3 {
width: 80px;
height: 80px;
top : 66%;
left : 73%;
}
#obj4 {
top: 54%;
left: 28%;
width: 60px;
height: 70px;
}
#obj5 {
width: 100px;
height: 100px;
top: 45%;
right: 13%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="masterobject" id="obj1"></div>
<div class="masterobject" id="obj2"></div>
<div class="masterobject" id="obj3"></div>
<div class="masterobject" id="obj4"></div>
<div class="masterobject" id="obj5"></div>
Add a class, see if its count matches the count of items:
$(document).ready(function(){
$(".masterobject").click(function() {
$(this).addClass("clicked");
if ($(".masterobject").length == $(".clicked").length)
alert("all clicked");
});
});
In general, you could do something like this:
var clickers = $(".clicker");
clickers.on("click", function() {
$(this).data("clicked", true);
$(this).addClass("clicked");
var all = true;
clickers.each(function() {
all &= $(this).data("clicked");
return all;
});
if (all) {
alert("all clicked!");
}
});
.clicker {
background-color: red;
width: 100px;
height: 100px;
position: absolute;
}
.clicked {
background-color: blue;
}
#div1 {
left: 10px;
top: 10px;
}
#div2 {
left: 10px;
top: 130px;
}
#div3 {
left: 130px;
top: 10px;
}
#div4 {
left: 130px;
top: 130px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clicker" id="div1"></div>
<div class="clicker" id="div2"></div>
<div class="clicker" id="div3"></div>
<div class="clicker" id="div4"></div>
What we are doing is for every div with the class clicker we bind a click handler that will get the clicked property of this div. Then we check to see if all divs with this class have been clicked and pop an alert if they have.
Note: I added a class so you can tell when you've clicked a div (in my example, they now turn blue). You could actually use that instead of a data property by using .hasClass.
1 approach: You'll need to check if all the divs are clicked each time one is clicked. So, I'd loop through each of your div's, see if the attribute is set... and if not, set a standard boolean var to false.
Something like the following...
var allClicked = true;
$('.masterobject').each(function(){
if(!$(this).data('clicked')){
allClicked=false;
return false;
}
});
if(allClicked){
alert('yay!');
}
http://jsbin.com/kokumohohe/2/edit?output
It is a bit ugly, but you can do something like:
div1 = "1";
div2 = "1";
div3 = "1";
divSum = div1 + div2 + div3;
console.log(divSum);
$("#div1").click(function() {
div1 = "2";
check();
});
$("#div2").click(function() {
div2 = "2";
check();
});
$("#div3").click(function() {
div3 = "2";
check();
});
function check () {
divSum = div1 + div2 + div3;
if (divSum = 222) {
alert("TAdaaahh!");
};
}
Here is a fiddle: http://jsfiddle.net/xdpyx3rx/1/
What about this approach using combination of jQuery and getElementsByClassName method, which allows you not to requery DOM on each click taking advantage of live NodeList:
$(document).ready(function() {
var clicked = document.getElementsByClassName('clicked');
var $masterObjects = $(".masterobject").click(function() {
$(this).addClass("clicked");
if ($masterObjects.length === clicked.length) {
alert("all clicked");
}
});
});
Demo: http://jsbin.com/wepoqumita/1/

Categories