I want the call function to run every 1.5 seconds.
However, if you are clicking continuously on a mobile machine
From the moment the call function is called in succession.
This is the code I am using:
$('#sendVideo').unbind('click');
$('#sendVideo').bind('click', function (event) {
$("#sendVideo").prop("disabled", true);
call();
setTimeout("$('#sendVideo').prop('disabled', false);", 1500);
});
Is there a solution for this?
You can use a clever hack:
var clickInProgress = false;
$('#sendVideo').bind('click', function (event) {
if(clickInProgress) return;
clickInProgress = true;
$("#sendVideo").prop("disabled", true);
call();
setTimeout("$('#sendVideo').prop('disabled', false); clickInProgress=false;", 1500);
});
You can set a flag on the element during the capture phase and delete it during bubble phase. I am not sure about jQuery but in simple java-script you can achieve it like this:
// set the flag on at capture
document.querySelector("#sendVideo").addEventListener('click', function(e) {
if (this.flagOn) {
e.preventDefault();
return false;
}
this.flagOn = true;
return true;
}, true);
// delete on bubble
document.querySelector("#sendVideo").addEventListener('click', function(e) {
delete this.flagOn;
}, false);
This should handle that for you without any modification in your own code.
Related
Working on a Drupal 9 site and trying to add some custom JS code to a page.
Drupal.behaviors.syfyGlobalHideMenu = {
attach: function (context, settings) {
$('.nav-flyout', context).once('remove-modals', function () {
$(document).keyup(function (e) {
if (e.keyCode == 27) {
$('.nav-flyout', context).removeClass('js-flyout-active');
}
});
});
}
};
Wondering if there's a vanilla JS equivalent to the jQuery .once functionality above?
Currently Drupal attaches the event listener multiple times and I am trying to avoid that as I only want to attach the event listener once but have it remain attached and run every time the event is invoked.
let intervalID = null;
const search = document.querySelector(".call-us-table input#edit-search");
search.addEventListener("keydown", event => {
form.setAttribute("onsubmit", "return false");
clearInterval(intervalID);
});
search.addEventListener("keyup", event => {
intervalID = setInterval(submitForm, 2000);
});
Jquery once adds an html attribute to check if is the first time to run.
function vanillaOnce() {
if (!document.body.getAttribute('data-once')) {
document.body.setAttribute('data-once', 'true');
return true;
} else {
return false;
}
}
if (vanillaOnce) {
console.log('runs only once');
}
I created a site that will change images from being displayed on mouse scroll. It was working until this morning on my local machine, but suddenly stopped. When I check the dev console I get an error message that says "[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312"
I have read the information at the provided url and I still do not understand how I can turn off this feature. In my code I have the following:
var changeImage = function changeImage(event) {
event.preventDefault();
if (brochure.waitForDelay === false) {
window.onwheel = function () {
return false;
};
brochure.waitForDelay = true;
if (event.deltaY < 0) {
scrollUp();
} else {
scrollDown();
}
setTimeout(function () {
brochure.waitForDelay = false;
window.onwheel = function () {
return true;
};
}, 1250);
} else {
return;
}
};
var determineScrollDirection = function determineScrollDirection() {
document.addEventListener('wheel', changeImage, { passive: false });
};
In determineScrollDirection I set the passive as false and tried to call preventDefault in the changeImage function but I still get the same error message.
I was able to fix this issue by removing the following line:
window.onwheel = function () {
return false;
};
$('.slideArrow').toggle(function (event) {
//some code
}, function (event) {
//some code
});
This works fine for content which are loaded on page-load.But the same function does not work for content loaded with ajax.It just does not intercept the click.
What should I do?
In an other scenario,i faced a same problem(not for toggle,for click) and sorted it this way.I dont know what to do for toggle?
$('.common-parent').on('click','.target-of-click',function(){
//some code
})
The flag method :
var flag = false;
$(document).on('click', '.slideArrow', function(event) {
if (flag) {
// do one thing
}else{
// do another thing
}
flag = !flag;
});
the data method
$(document).on('click', '.slideArrow', function(event) {
if ( $(this).data('flag') ) {
// do one thing
}else{
// do another thing
}
$(this).data('flag', !$(this).data('flag'));
});
My bind function:
$searchInput.bind('blur', function() {
$searchResults.remove();
}
But this shouldn't happen if I click on a link inside of $searchResults. Now $searchResults is removed before I can click on a link.
How should I do that?
You may simply set a flag on mouse over $searchResults:
var isOver = false;
$searchInput.bind("blur", function(e) {
if (!isOver) {
$searchResults.remove();
}
});
$searchResults.hover(function() {
isOver = true;
}, function() {
isOver = false;
});
DEMO: http://jsfiddle.net/sUA4D/
You can do the same via element data, e.g. setting $searchResults.data("isOver", true).
One option that comes to mind is to delay the execution of the $.remove() call, like this:
$searchInput.bind('blur', function() {
setTimeout(function() {
$searchResults.remove();
}, 100);
}
$searchInput.find('a').on('click', function() {
$searchResults.remove();
});
I'm writing a jQuery plugin where the events which start/stop the plugin are customisable, so potentially the same event could both start and stop the plugin (e.g. click to start and click to stop).
What's an elegant way, ideally not involving timeouts or unbinding and rebinding of listeners (and not too many "isPlaying" "isBeingStarted" flags etc..) to make sure the correct callback is called
(Note: When I posted this answer, the question had a typo in it which made it seem like binding/unbinding would be okay as long as timeouts weren't involved.)
I don't see any need for timeouts, just bind/unbind as appropriate:
this.bind(startEvent, start);
function start() {
$(this).unbind(startEvent).bind(stopEvent, stop);
}
function stop() {
$(this).unbind(stopEvent).bind(startEvent, start);
}
In the above, I assume that startEvent is the configured start event name (and I'd probably add a namespace to it, e.g. the user passes in "click" but you add ".niftyplugin" to it resulting in startEvent containing "click.niftyplugin" so you can bind/unbind at will), and stopEvent is the configured stop event name (with namespace).
Here's a full example, with namespaces and using data to remember the options (you could use a closure if you prefer) - live copy:
// Plugin stuff
(function($) {
$.fn.niftyPlugin = niftyPlugin;
function niftyPlugin(options) {
var data;
data = {
startEvent: (options && options.startEvent || "click") + ".niftyplugin",
stopEvent: (options && options.stopEvent || "click") + ".niftyplugin"
};
this.data("niftyPlugin", data).bind(data.startEvent, start);
return this;
}
function start() {
var $this = $(this),
data = $this.data("niftyPlugin");
$this.unbind(data.startEvent).bind(data.stopEvent, stop);
display("Start");
}
function stop() {
var $this = $(this),
data = $this.data("niftyPlugin");
$this.unbind(data.stopEvent).bind(data.startEvent, start);
display("Stop");
}
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
})(jQuery);
// Use
jQuery(function($) {
$("#theButton").click(function() {
$("<p>Non-plugin hook fired</p>").appendTo(document.body);
}).niftyPlugin({
startEvent: "click"
});
});
The only other alternative I see is stopImmediatePropagation - live example:
// Plugin stuff
(function($) {
$.fn.niftyPlugin = niftyPlugin;
function niftyPlugin(options) {
var startEvent, stopEvent, running = false;
startEvent = (options && options.startEvent || "click") + ".niftyplugin";
stopEvent = (options && options.stopEvent || "click") + ".niftyplugin";
this.bind(startEvent, start).bind(stopEvent, stop);
return this;
function start(event) {
if (running) {
return;
}
running = true;
display("Start");
event.stopImmediatePropagation();
}
function stop(event) {
if (!running) {
return;
}
running = false;
display("Stop");
event.stopImmediatePropagation();
}
}
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
})(jQuery);
// Use
jQuery(function($) {
$("#theButton").click(function() {
$("<p>Non-plugin hook fired</p>").appendTo(document.body);
}).niftyPlugin({
startEvent: "click"
});
});
I don't like it, though, because it interferes with other handlers for the event. For instance, in the above, if I change the use to this:
// Use
jQuery(function($) {
$("#theButton").niftyPlugin({
startEvent: "click"
}).click(function() {
$("<p>Non-plugin hook fired</p>").appendTo(document.body);
});
});
...so the plug-in grabs the events before the non-plug-in code, boom, the non-plug-in code never sees the event (example).
So despite the overhead, I suspect bind/unbind are your friends here.
It may be overkill, but an elegant way to not have to maintain a bunch of flags (e.g. "isPlaying") is to use a Finite State Machine.
Here's a jQuery implementation: https://github.com/DukeLeNoir/jquery-machine
The eventual solution I've gone for is to do a quick uniqueness test for events used for stopping and starting and if there are any events used for both stopping and starting then a different listener (which does an isPlaying check) is attached to these. There's a small performance hit on loading the plugin, but after that the event handling code is about as efficient as can be.
function processEvents() {
var tempStart = opts.startEvent.split(" ").sort(),
tempStop = opts.stopEvent.split(" ").sort();
startEventLoop: for(var i=0, il = tempStart.length;i<il;i++) {
for(var j=0, jl = tempStop.length;j<jl;j++) {
if(tempStart[i] == tempStop[j]) {
stopStartEvents.push(tempStart[i])
tempStop.splice(j,1);
continue startEventLoop;
}
}
startEvents.push(tempStart[i])
}
startEvents = startEvents.join(" ");
stopEvents = tempStop.join(" ");
stopStartEvents = stopStartEvents.join(" ");
}
$this.on(stopEvents, function() {
$this.trigger("stop.flickBook");
}).on(startEvents, function() {
$this.trigger("start.flickBook");
}).on(stopStartEvents, function() {
playing ? $this.trigger("stop.flickBook") : $this.trigger("start.flickBook");
});