document won't fire mousemove event if mousedown occurred in iframe - javascript

I have a same origin iframe. Mouse events in the iframe are triggered in the document like so:
// this won't work
$('iframe').contents().find('body').on('mousedown mouseup mousemove', function(e) {
$(document).trigger(e);
});
// this does work
$('iframe').contents().on('mousedown mouseup mousemove', function(e) {
$(document).trigger(e);
});
My problem is if the mousedown occurs in the iframe and the mouse leaves the iframe, the document won't trigger it's own mousemove events until a mouseup occurs.
I've tried triggering mouseup in both the iframe and the document once the mouse leaves the iframe, but the document mousemove events won't resume until a physical mouseup occurs.

This is what worked for me on a page that had multiple iFrames:
$(function() {
$('iframe').each(function(index) {
$(this).load(function () {
$(this).contents().on("mousedown", function (e) {
$(document).trigger(e);
})
.on("mouseup", function (e) {
$(document).trigger(e);
});
});
});
});
It would work with only one iframe too. The important part is to wait for the frame load to complete before binding events, otherwise it may not work properly. In my case, the mouse events were detected properly in one iframe, but not in the other.

using object literal notation you can add multiple events to the .on(). then i added the .contents() to get all of your events to work within an Iframe. here's a working fiddle
$('.myiframe').contents().on({
mousedown: function () {
console.log('mouse down triggered');
},
mouseup: function () {
console.log('mouse up triggered');
},
mousemove: function() {
console.log('mouse move triggered');
}
});

When u call the above code from a page, it takes some time to load the frame body. Hence it cannot attach the frame mousemove event listener. If you call it with settimeout function it will be able to get the content of frame and movemove will get attched to body of frame.
:)

Related

How is possible to get cursor position and cursor events outside and cross origin iframe?

I am working on a video player. This player is used inside an iframe on the client's page, so it is cross-origin. When the user clicks on seekbar and drags the cursor out of iframe, I can't identify the mouseup event, so it keeps selected. I notice that youtube player can do it, and can identify cursor events outside iframe. How can i do it using javascript?
One thing to consider is that the mouseup event only fires if the pointer is directly over the element with the eventListener. It doesn't keep track of what element the mousedown event fired on, it only knows about the state of the mouse at the time of the mouseup.
The mouseup event is fired at an Element when a button on a pointing
device (such as a mouse or trackpad) is released while the pointer is
located inside it.
https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseup_event
Therefore you need some other method of tracking if your user has initiated the drag on your seekbar playhead.
A possible solution is to use a boolean variable. Then to listen to mouseup on document and check the value of that variable.
let scrubbingTimeline = false;
document.querySelector('button').addEventListener('mousedown', ()=> {
console.log('Mouse down')
scrubbingTimeline = true
})
document.addEventListener('mouseup', ()=> {
if(scrubbingTimeline === true) {
console.log('Mouse has been released')
scrubbingTimeline = false
}
})
Another possible solution would be to initiate the mouseup listener only once the mousedown callback has fired. Then to stop listening after one event. Like this:
function mouseUpHandler() {
console.log("Mouse Lifted")
document.removeEventListener('mouseup', mouseUpHandler)
}
document.querySelector('button').addEventListener('mousedown', ()=> {
console.log('Down')
document.addEventListener('mouseup', mouseUpHandler)
})
Important: This code is for the inner document. I.E. the one that will be the iframe.

js/jQuery: Stop event listener

I have multiple DOM elememts. When each one becomes visible within the window then I fire an animation on that element.
Each element registers the window scroll event to the same event handler, passing this handler the element's ID and an event-specific callback function for the animation.
This single event handler tests if the element is on screen and if so fires the callback.
But ... it still listens for the window scroll event even after firing the callback. How can I turn off the scroll listener? jQuery "off" didn't work.
$(window).on('scroll', function () {
sharedFunctionsModuleName.initialAnimationWhenChartBottomVisible({
chartID: chartID,
callbackFunction: thisWebpageModuleName.animationFunctionName
});
});
EventTarget.removeEventListener()?
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
just use the one event instead of on
$(window).one('scroll', function () {
sharedFunctionsModuleName.initialAnimationWhenChartBottomVisible({
chartID: chartID,
callbackFunction: thisWebpageModuleName.animationFunctionName
});
});
this automatically unbinds after the first time its fired
The documentation is here

Upon a click, how do I set an event handler to fire on a subsequent click?

I have a piece of JavaScript using jQuery that looks a bit like this:
$('.myclass').on('click', function() {
// Do Stuff
$(document).on('click.mynamespace', function() {
// Do More Stuff
$(document).off('click.mynamespace');
});
});
Upon a click on .myclass, I am expecting it to Do Stuff, then attach a handler to the click event on the document and Do More Stuff on a subsequent click - but it appears that both Stuff and More Stuff happen on the first click.
Is the click event still firing when the second event handler is attached? How do I achieve my desired effect?
Try calling stopPropagation to prevent the event from bubbling out to the document on the first click:
$('.myclass').on('click', function(e) {
e.stopPropagation();
// Do Stuff
$(document).on('click.mynamespace', function() {
// Do More Stuff
$(document).off('click.mynamespace');
});
});

How to temporarily disable all event handlers attached to a control

Is there a way to do.
$("#controlId").suspendEvents();
$("#controlId").resumeEvents();
I'm aware of preventDefault and stopPropagation. I want to do from outside the event.
Please consider the following in your answer.
I cannot modify these bound events.
I do not know the bound events (Although it will be possible it will take me long time to do it). so it is not possible to .off() and then add them back one by one.
I was able to put together answers from 2 other questions.
1.Bind an event handler to front of the queue
2.Attach handler to all events in a control
The idea is to bind an event handler with e.stopImmediatePropagation to front of the queue for all events. It seems crude i would be glad if this can be improved.
The solution...
$.fn.preBind = function (type, data, fn) {
this.each(function () {
var $this = $(this);
$this.bind(type, data, fn);
$.each(type.split(/ +/), function () {
var currentBindings = $this.data('events')[this];
if ($.isArray(currentBindings)) {
currentBindings.unshift(currentBindings.pop());
}
});
});
return this;
};
$.fn.suspendEvents = function () {
this.preBind("click keydown keyup keypress mouseover mouseenter mouseout mouseleave mousedown mouseup mousemove change blur focus focusin focusout scroll resize load unload beforeunload", null, blockEvents);
}
$.fn.resumeEvents = function () {
var _this = this;
$.each("click keydown keyup keypress mouseover mouseenter mouseout mouseleave mousedown mouseup mousemove change blur focus focusin focusout scroll resize load unload beforeunload".split(/ +/), function () {
_this.unbind(this, blockEvents);
});
}
function blockEvents(e) {
e.stopImmediatePropagation();
}
Now i could use
$("#controlId").suspendEvents();
$("#controlId").resumeEvents();
EDIT: Modified resumeEvents() to overcome IE issue.
everything bubbles up, so catch any event in body and prevent them.
alternative
var myCtlrs = $("all i want").attr("disabled", disabled");
then
myCtlrs.removeAttr("disabled");

Losing MouseUp event if releasing not over the same element

I have got a problem with a slider. When i grab the handler, i change the .src of the image, just to change its color. However, i want it to change back to the original color when i release the mouse button. I have tried two things.
1) Changing it back on the handler mouseup event: this works only if i release the button over the handler, so this is not a solution.
2)Changin it back on the window mouseup event: the event is not firing properly. If i click and release on any place of the window, the event fires normaly, but if i click in the handler, move the cursor to any other point of the window, and then release the button, the event will not fire.
Btw, im using the prototype js framework.
Solutions? Thanks
Here is the code. I load the handler function when the document is ready.
function handler()
{
var handler = $('handler');
Event.observe(window, "mouseup", function(){
alert('salta'); //to see when mouseup fires
if(handler.src=='http://localhost/moodle/blocks/videoavatar/eggface/trunk/gripper_o.png'){ //orange
handler.src='http://localhost/moodle/blocks/videoavatar/eggface/trunk/gripper.png';} //grey
});
Event.observe(handler,'mousedown',function(){handler.src='http://localhost/moodle/blocks/videoavatar/eggface/trunk/gripper_o.png';}); //orange
}
You should be attaching the mouseup handler to the document object.
How about onmouseout event?
Here is the code. I load the handler function when the document is ready.
function handler()
{
var handler = $('handler');
Event.observe(window, "mouseup", function(){
alert('salta'); //to see when mouseup fires
if(handler.src=='http://localhost/moodle/blocks/videoavatar/eggface/trunk/gripper_o.png'){ //orange
handler.src='http://localhost/moodle/blocks/videoavatar/eggface/trunk/gripper.png';} //grey
});
Event.observe(handler,'mousedown',function(){handler.src='http://localhost/moodle/blocks/videoavatar/eggface/trunk/gripper_o.png';}); //orange
}

Categories

Resources