Jquery slideToggle “bounces” multiple times on resize
I have a little problem with a simple jQuery script (I'm not an expert):
My requirements:
1) I have multiple elements that are made of
- a title
- a body
2) For a screen size > 768px, all the elements are visibile
3) For a screen size =< 768px I want to emulate the Bootstrap Collapse behavior, so when you click on the title, the "body" of the element, i.e. <div class="panel--collapsible" id="panel1">
becomes visible. The body of the element is not visible at the beginning by default.
I post here the code I wrote so far
$(document).ready(function() {
toggleDivOnMobile();
window.addEventListener('resize', function() {
toggleDivOnMobile();
});
});
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (window.outerWidth <= 768) {
content.slideToggle("slow");
}
});
return false;
}
.panel--collapsible {
display: none;
}
@media screen and (min-width:769px) {
.panel--collapsible {
display: block!important;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="par1" class="collapsible">
<h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
<div class="panel--collapsible" id="panel1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div id="par2" class="collapsible">
<h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
<div class="panel--collapsible" id="panel2">
<p>Cuius et cetera</p>
</div>
</div>
My problem is: after resizing the window, the collapse works, but it "bounces" multiple times.
You can simulate the behavior by resizing the window.
Thank you for your help;of course if you need more information, write me a comment :)
javascript jquery slidetoggle
add a comment |
I have a little problem with a simple jQuery script (I'm not an expert):
My requirements:
1) I have multiple elements that are made of
- a title
- a body
2) For a screen size > 768px, all the elements are visibile
3) For a screen size =< 768px I want to emulate the Bootstrap Collapse behavior, so when you click on the title, the "body" of the element, i.e. <div class="panel--collapsible" id="panel1">
becomes visible. The body of the element is not visible at the beginning by default.
I post here the code I wrote so far
$(document).ready(function() {
toggleDivOnMobile();
window.addEventListener('resize', function() {
toggleDivOnMobile();
});
});
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (window.outerWidth <= 768) {
content.slideToggle("slow");
}
});
return false;
}
.panel--collapsible {
display: none;
}
@media screen and (min-width:769px) {
.panel--collapsible {
display: block!important;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="par1" class="collapsible">
<h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
<div class="panel--collapsible" id="panel1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div id="par2" class="collapsible">
<h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
<div class="panel--collapsible" id="panel2">
<p>Cuius et cetera</p>
</div>
</div>
My problem is: after resizing the window, the collapse works, but it "bounces" multiple times.
You can simulate the behavior by resizing the window.
Thank you for your help;of course if you need more information, write me a comment :)
javascript jquery slidetoggle
add a comment |
I have a little problem with a simple jQuery script (I'm not an expert):
My requirements:
1) I have multiple elements that are made of
- a title
- a body
2) For a screen size > 768px, all the elements are visibile
3) For a screen size =< 768px I want to emulate the Bootstrap Collapse behavior, so when you click on the title, the "body" of the element, i.e. <div class="panel--collapsible" id="panel1">
becomes visible. The body of the element is not visible at the beginning by default.
I post here the code I wrote so far
$(document).ready(function() {
toggleDivOnMobile();
window.addEventListener('resize', function() {
toggleDivOnMobile();
});
});
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (window.outerWidth <= 768) {
content.slideToggle("slow");
}
});
return false;
}
.panel--collapsible {
display: none;
}
@media screen and (min-width:769px) {
.panel--collapsible {
display: block!important;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="par1" class="collapsible">
<h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
<div class="panel--collapsible" id="panel1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div id="par2" class="collapsible">
<h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
<div class="panel--collapsible" id="panel2">
<p>Cuius et cetera</p>
</div>
</div>
My problem is: after resizing the window, the collapse works, but it "bounces" multiple times.
You can simulate the behavior by resizing the window.
Thank you for your help;of course if you need more information, write me a comment :)
javascript jquery slidetoggle
I have a little problem with a simple jQuery script (I'm not an expert):
My requirements:
1) I have multiple elements that are made of
- a title
- a body
2) For a screen size > 768px, all the elements are visibile
3) For a screen size =< 768px I want to emulate the Bootstrap Collapse behavior, so when you click on the title, the "body" of the element, i.e. <div class="panel--collapsible" id="panel1">
becomes visible. The body of the element is not visible at the beginning by default.
I post here the code I wrote so far
$(document).ready(function() {
toggleDivOnMobile();
window.addEventListener('resize', function() {
toggleDivOnMobile();
});
});
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (window.outerWidth <= 768) {
content.slideToggle("slow");
}
});
return false;
}
.panel--collapsible {
display: none;
}
@media screen and (min-width:769px) {
.panel--collapsible {
display: block!important;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="par1" class="collapsible">
<h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
<div class="panel--collapsible" id="panel1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div id="par2" class="collapsible">
<h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
<div class="panel--collapsible" id="panel2">
<p>Cuius et cetera</p>
</div>
</div>
My problem is: after resizing the window, the collapse works, but it "bounces" multiple times.
You can simulate the behavior by resizing the window.
Thank you for your help;of course if you need more information, write me a comment :)
$(document).ready(function() {
toggleDivOnMobile();
window.addEventListener('resize', function() {
toggleDivOnMobile();
});
});
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (window.outerWidth <= 768) {
content.slideToggle("slow");
}
});
return false;
}
.panel--collapsible {
display: none;
}
@media screen and (min-width:769px) {
.panel--collapsible {
display: block!important;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="par1" class="collapsible">
<h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
<div class="panel--collapsible" id="panel1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div id="par2" class="collapsible">
<h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
<div class="panel--collapsible" id="panel2">
<p>Cuius et cetera</p>
</div>
</div>
$(document).ready(function() {
toggleDivOnMobile();
window.addEventListener('resize', function() {
toggleDivOnMobile();
});
});
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (window.outerWidth <= 768) {
content.slideToggle("slow");
}
});
return false;
}
.panel--collapsible {
display: none;
}
@media screen and (min-width:769px) {
.panel--collapsible {
display: block!important;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="par1" class="collapsible">
<h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
<div class="panel--collapsible" id="panel1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div id="par2" class="collapsible">
<h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
<div class="panel--collapsible" id="panel2">
<p>Cuius et cetera</p>
</div>
</div>
javascript jquery slidetoggle
javascript jquery slidetoggle
asked Nov 14 '18 at 13:32
Riccardo De ContardiRiccardo De Contardi
1,176313
1,176313
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
The problem is you're calling toggleDivOnMobile
, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.
The solution would be to set some external variable and only attach your event listeners once, like so:
var isMobile = false;
$(document).ready(function() {
toggleDivOnMobile();
handleWindowResize();
window.addEventListener('resize', function() {
handleWindowResize();
});
});
function handleWindowResize() {
isMobile = window.outerWidth <= 768;
}
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (isMobile) {
content.slideToggle("slow");
}
});
return false;
}
There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off
function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.
EDIT
You may also want to place the isMobile
check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.
EDIT 2
Updated code per OP request to include onload resize call.
Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, asisMobile=false
and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again
– Riccardo De Contardi
Nov 16 '18 at 9:27
@RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.
– Sheng Slogar
Nov 16 '18 at 9:38
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53301447%2fjquery-slidetoggle-bounces-multiple-times-on-resize%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The problem is you're calling toggleDivOnMobile
, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.
The solution would be to set some external variable and only attach your event listeners once, like so:
var isMobile = false;
$(document).ready(function() {
toggleDivOnMobile();
handleWindowResize();
window.addEventListener('resize', function() {
handleWindowResize();
});
});
function handleWindowResize() {
isMobile = window.outerWidth <= 768;
}
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (isMobile) {
content.slideToggle("slow");
}
});
return false;
}
There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off
function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.
EDIT
You may also want to place the isMobile
check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.
EDIT 2
Updated code per OP request to include onload resize call.
Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, asisMobile=false
and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again
– Riccardo De Contardi
Nov 16 '18 at 9:27
@RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.
– Sheng Slogar
Nov 16 '18 at 9:38
add a comment |
The problem is you're calling toggleDivOnMobile
, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.
The solution would be to set some external variable and only attach your event listeners once, like so:
var isMobile = false;
$(document).ready(function() {
toggleDivOnMobile();
handleWindowResize();
window.addEventListener('resize', function() {
handleWindowResize();
});
});
function handleWindowResize() {
isMobile = window.outerWidth <= 768;
}
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (isMobile) {
content.slideToggle("slow");
}
});
return false;
}
There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off
function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.
EDIT
You may also want to place the isMobile
check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.
EDIT 2
Updated code per OP request to include onload resize call.
Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, asisMobile=false
and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again
– Riccardo De Contardi
Nov 16 '18 at 9:27
@RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.
– Sheng Slogar
Nov 16 '18 at 9:38
add a comment |
The problem is you're calling toggleDivOnMobile
, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.
The solution would be to set some external variable and only attach your event listeners once, like so:
var isMobile = false;
$(document).ready(function() {
toggleDivOnMobile();
handleWindowResize();
window.addEventListener('resize', function() {
handleWindowResize();
});
});
function handleWindowResize() {
isMobile = window.outerWidth <= 768;
}
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (isMobile) {
content.slideToggle("slow");
}
});
return false;
}
There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off
function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.
EDIT
You may also want to place the isMobile
check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.
EDIT 2
Updated code per OP request to include onload resize call.
The problem is you're calling toggleDivOnMobile
, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.
The solution would be to set some external variable and only attach your event listeners once, like so:
var isMobile = false;
$(document).ready(function() {
toggleDivOnMobile();
handleWindowResize();
window.addEventListener('resize', function() {
handleWindowResize();
});
});
function handleWindowResize() {
isMobile = window.outerWidth <= 768;
}
function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (isMobile) {
content.slideToggle("slow");
}
});
return false;
}
There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off
function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.
EDIT
You may also want to place the isMobile
check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.
EDIT 2
Updated code per OP request to include onload resize call.
edited Nov 16 '18 at 9:37
answered Nov 14 '18 at 14:52
Sheng SlogarSheng Slogar
912614
912614
Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, asisMobile=false
and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again
– Riccardo De Contardi
Nov 16 '18 at 9:27
@RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.
– Sheng Slogar
Nov 16 '18 at 9:38
add a comment |
Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, asisMobile=false
and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again
– Riccardo De Contardi
Nov 16 '18 at 9:27
@RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.
– Sheng Slogar
Nov 16 '18 at 9:38
Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as
isMobile=false
and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again– Riccardo De Contardi
Nov 16 '18 at 9:27
Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as
isMobile=false
and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again– Riccardo De Contardi
Nov 16 '18 at 9:27
@RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.
– Sheng Slogar
Nov 16 '18 at 9:38
@RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.
– Sheng Slogar
Nov 16 '18 at 9:38
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53301447%2fjquery-slidetoggle-bounces-multiple-times-on-resize%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown