If any of the following listeners are activated, they are activated 2^x times, x being the number of times any one of them has been triggered. The first time it will run 2 times, ten 4, 8, 16 ect. What am I missing that is triggering them more than once?
$(document).on('click',"#post-ride",(function() {
addRide(currentDriver, $(destinationInput).val(), $(originInput).val(),$(dateInput).val(), $(timeInput).val());
console.log("add ride called");
$.getScript("scripts/myRides.js", function() {
});
}));
$(document).on('click',"#request-ride",(function() {
requestRide(currentDriver, $(destinationInput).val(), $(originInput).val(), $(dateInput).val(), $(timeInput).val());
$.getScript("scripts/myRides.js", function() {
});
}));
$(document).on('click',"#leave-ride",(function() {
leaveRide(currentDriver, $(this).closest('div').attr('id') );
$.getScript("scripts/myRides.js", function() {
});
console.log("leave ride called");
}));
$(document).on('click',"#cancel-ride",(function() {
cancelRide(currentDriver, $(this).closest('div').attr('id') );
$.getScript("scripts/myRides.js", function() {
});
}));
$(document).on('click',"#remove-friend",(function() {
removeFriend(currentDriver, $(this).closest('div').attr('id') );
$.getScript("scripts/friends.js", function() {
});
}));
$(document).on('click',"#add-friend",(function() {
addFriend(currentDriver, $(this).closest('div').attr('id') );
$.getScript("scripts/friends.js", function() {
});
}));
Presumably, either myRides.js or friends.js or both are adding duplicate event listeners every time you load it.
The logical question to ask would be why are you loading the same script over and over again? You probably should not be doing that.
If there is one function in that script that you want to execute, you can test whether that function is already loaded and if so, just call it. If not, then load the script and let it execute when it's loaded.
If there's some other reason why you are loading the same script over and over again, then you could protect each event listener from installing a subsequent copy by keeping track of whether you've loaded each one yet in it's own state variable, though this is probably the more tedious way to solve the problem.
You are adding new handlers each time you "getScript"
Related
I've downloaded this Drupal 8 template and the site is at www.plotujeme.sk. It has an responsive navigation with this .js script:
function sidebar_menu() {
var windowsize = jQuerywindow.width(),
jQuerynav = jQuery("nav"),
slide = {
clear: function () {
jQuerybody.removeClass('toggled');
jQuery('.overlay').hide();
jQuery('.easy-sidebar-toggle').prependTo("header");
//jQuery('#search').prependTo("body");
jQuery('.navbar.easy-sidebar').removeClass('toggled');
jQuery('#navbar').removeAttr("style");
},
start: function () {
jQuery('.overlay').show();
jQuerybody.addClass('toggled');
jQueryhtml.addClass('easy-sidebar-active');
jQuerynav.addClass('easy-sidebar');
jQuery('.easy-sidebar-toggle').prependTo(".easy-sidebar");
//jQuery('#search').prependTo("#navbar");
jQuery('#navbar').height(jQuerywindow.height()).css({
"padding-top": "60px"
});
},
remove: function () {
jQuerynav.removeClass('easy-sidebar');
}
};
if (windowsize < 1003) {
jQuerynav.addClass('easy-sidebar');
jQuery('.easy-sidebar-toggle').on("click", function (e) {
e.preventDefault();
if (jQuerybody.hasClass('toggled')) {
slide.clear();
} else {
slide.start();
}
});
/*
jQueryhtml.on('swiperight', function () {
slide.start();
});
jQueryhtml.on('swipeleft', function () {
slide.clear();
}); */
} else {
slide.clear();
slide.remove();
}
}
and:
jQuery(document).ready(function () {
"use strict";
sidebar_menu();
jQuery(window).resize(function () {
sidebar_menu();
});
});
Problem is, that if I open responsive navigation by clicking on hamburger button, it works several times and then it stops working, the page and a browser freezes or is unresponsive for a long time. I also noticed that (even in template preview) sometimes it does not work at all and nothing happens after clicking hamburger icon. When I resize window multiple times sometimes it works sometimes not.
Do you see any error in the script that could possibly cause this problem?
Update: I also tried to use jQuery('.easy-sidebar-toggle').off("click"); just before jQuery('.easy-sidebar-toggle').on("click", function() {...}); but got the same results.
jQuery(window).resize(function () {
sidebar_menu();
});
As a result, whenever sidebar_menu function changes the window size, this function is called again and again, like a recursion, hence the freezing
I think the reason might be the following lines in the resize handler:
jQuerynav.addClass('easy-sidebar');
jQuery('.easy-sidebar-toggle').on("click", ...
They are run every time the window is resized by even one pixel, so a few dozen times a second if you drag the window border. Not sure about the first line, whether it adds the class over and over, but the second line certainly adds an event handler multiple times and fills up the stack. That's the reason your browser freezes. It just can't process the hundreds of registered events.
Just a guess, though.
I am using ajaxComplete to run some functions after dynamic content is loaded to the DOM. I have two separate functions inside ajaxComplete which uses getJSON.
Running any of the functions once works fine
Running any of them a second time causes a loop cause they are using getJSON.
How do I get around this?
I'm attaching a small part of the code. If the user has voted, clicking the comments button will cause the comments box to open and close immediately.
$(document).ajaxComplete(function() {
// Lets user votes on a match
$('.btn-vote').click(function() {
......
$.getJSON(path + 'includes/ajax/update_votes.php', { id: gameID, vote: btnID }, function(data) {
......
});
});
// Connects a match with a disqus thread
$('.btn-comment').click(function() {
var parent = $(this).parents('.main-table-drop'), comments = parent.next(".main-table-comment");
if (comments.is(':hidden')) {
comments.fadeIn();
} else {
comments.fadeOut();
}
});
});
Solved the problem by checking the DOM loading ajax request URL
$(document).ajaxComplete(event,xhr,settings) {
var url = settings.url, checkAjax = 'list_matches';
if (url.indexOf(checkAjax) >= 0) { ... }
}
I have a weird problem. I have a freight calculation field to be executed if the User deletes a digit input , I hide one content. While running the script in chrome console, it is loaded, but when using the call in html, js it does not run. This is what I have.
https://jsfiddle.net/diasbass/u3xr0921/
jQuery(document).ready(function($) {
$("#btnFreteSimulacao").click(function() {
$("#txtCep").keyup(function() {
if ($("#txtCep").val()) {
$('p.montagem').hide();
} else {
$('p.montagem').show();
}
});
});
});
The keyup event handler is inside the click function, probably it is of no use.
Also need to check $("#txtCep").val().length for showing and hiding the p.montagem
jQuery(document).ready(function($) {
$("#txtCep").keyup(function() {
if($("#txtCep").val().length ==0) {
$('p.montagem').hide();
} else {
$('p.montagem').show();
}
});
});
jsfiddle
Here you are mixing two asynchronous events 1) Button click 2) Input keyup. Your code expects to work when both are happening same time. I would suggest remove dependency on one event. Like below.
$( "#btnFreteSimulacao" ).click(function() {
// $("#txtCep").keyup(function() {
if($("#txtCep").val()) {
$('p.montagem').hide();
} else {
$('p.montagem').show();
}
});
// });
});
If thats not possible, try to look towards promises.
I've been trying to figure out this issue with my website for a while now--I have a bunch of "stars" a user can click on.
clicking on a star loads a file into a div with information regarding that star. It also loads a button for the players to click and "Take over" the planet. That all is working well and fine, however--I've recently discovered an issue that I'm not quite sure how to handle.
IF a player clicks on multiple stars before reloading the page for whatever reason--when the click to attack/whatever the star--it'll send multiple requests across the server. I at first thought this was something in my coding that was sending all information regarding all the stars, however I've come to realize that it's only the stars that the player has clicked on.
Now--Here is the code:
$.ajaxSetup ({
// Disable caching of AJAX responses
cache: false
});
function loadStatus()
{
$.ajax(
{
url:'world1.php', error: function () { }, dataType:'json',
success: function(data)
{
denial = false;
$('#credits').html(data.credits);
$('#fuelleft').html(data.fuel);
$('#energyleft').html(data.energy);
}
});
}
function currentStarMapURL(URL)
{
$('#starmap').load(URL, {},
function()
{
$('#loader').hide();
fullStarInformation(URL);
starInformation();
setInterval(function() { $('.unknown').effect("highlight",{color:"#800000"}, 1500)});
return false;
}
);
}
/*
purhcase upgrades
*/
/*
Retriever Better Star Info
*/
function fullStarInformation()
{
$(".star").click(
function()
{
$('#planet-bar').empty();
val = this.id;
url = "planet.php?sid="+val;
$('#planet-bar').load(url, {'sid':val},
function()
{
colony(url);
}
);
}
);
}
function colony(url)
{
$('#planet-bar').on("click", "button",
function() {
event.preventDefault();
name = 0;
$(this).hide();
name = $(this).attr('sid');
$.post('purchase.php?mode=planet', {sid: name},
function ()
{
$('#planet-bar').load(url, {}, function () { currentStarMapURL(URL2); })
}
);
$(this).prop('disabled', true);
});
}
I figured at first that the issue was a caching issue, so I added the $.ajaxSetup to the first line, but that didn't seem to change anything.
Then I figured, maybe it's the way the code was being called--I originally had two seperate functions; one for attack, one for colonizing. both of which were being called in the fullStarInformation function, So I moved it all down to one function, i'm still getting the issue.
AFAIK, right now, i may have to rewrite this entire block of code so that the colony function and the starInformation function are separate and not acting upon one another. But I wanted to get a second, third maybe even fourth set of eyes on the code before I go about doing that.
If you are getting multiple ajax calls, chances are you are setting up multiple event handlers.
Just quickly glancing through the code, I would think you should change
function colony(url)
{
$('#planet-bar').on("click", "button", function() { ... } );
To
function colony(url)
{
$('#planet-bar').off("click", "button"); //unbind old event handlers
$('#planet-bar').on("click", "button", function() { ... } );
I have an AJAX call as such :
$('a.delete_task').live('click', function() {
$this = $(this);
function deleteFunction(){
var obj = $this.parents('.task');
$(obj).addClass('highlighted');
$.post($this.attr('href'), { _method: 'delete' }, function(data) {
if ( $single_item_collection == true ) {
} else {
};
});
};
SSK.confirm_delete($this, deleteFunction, "task");
return false;
});
And then I take my deleteFunction() and throw it into the delete_confirmation :
$(function(){
window.SSK = new(Class.extend({
confirm_delete: function(obj, action, label){
$(".confirm-deletion").live("click", function(){
action.call(obj);
$(this).parents("#delete-message").fadeOut();
return false;
});
},
The problem is that when I click it the first time it works. When I click it the second time, it passes through the first $(this), and the second $(this). Likewise, when I click another item for a third time, it tries and pass all three and so on.
Somehow it is caching $(this). As crazy as that is. And passing it everytime the method is passed again.
Confirm delete as a function creates a popup and passes the method of the link you originally clicked to it as the variable obj.
Then if you click confirm it does this :
$(".confirm-deletion").live("click", function(){
action.call(obj);
$(this).parents("#delete-message").fadeOut();
return false;
});
You are adding a click event to the element 'confirm-deletion' every single time the user clicks 'delete_task'. That's why the click event is firing multiple times, it's literally been added multiple times.
No, it's surely not crazy caching. Read https://developer.mozilla.org/en/JavaScript/Reference/Operators/this and rewrite confirm_delete and/or deleteFunction.
I'm quite sure that you need to put $(this) in a caching value in the click-handler closure, and then use that in deleteFunction.