I created a custom event called slides.swap but I want to prevent the event coming from a click in the trigger(). It's not working. How do I do that from the trigger()?
I know I can prevent it in the click function but I just want to keep everything "encapsulated".
JS:
tabs.on('click', 'a', function(e){
$(this).trigger('slides.swap', e);
});
//Custome event
tabs.find('a').bind('slides.swap', function(e){
var self = $(this),
selfIndex = self.parent().index(),
targetSlide = slides.eq(selfIndex);
e.preventDefault(); //somehow this doesn't work
//fade in/out slides
slides.filter('.active').stop(true, false).fadeOut(speed, function(){
$(this).removeClass('active');
});
targetSlide.stop(true, false).fadeIn(speed).addClass('active');
tabs.removeClass('selected');
self.parent().addClass('selected');
});
You're calling preventDefault() on the Event object for the swap event, which is different to the click event. Try calling preventDefault() on the event object you pass to the slides.swap handler;
tabs.find('a').bind('slides.swap', function(e, clickEvent){
if (typeof clickEvent === "object" && typeof clickEvent.preventDefault === "function") { // Check the parameter was provided and that it was an event object.
clickEvent.preventDefault();
}
// everything else
});
It must be said though that this isn't great program design. It's wrong to manipulate another event chain/ object from another.
Related
How can I tell if a function being called originated from a click event?
For instance, an anchor or button is clicked and the event is captured and a function is called.
Inside of this function in firebug's stack trace I can see an Object like this
Object { originalEvent=Event click, type="click", timeStamp=97128874, more...}
It says the originalEvent came from a click.
Depending on whether it came from or click or not, processing occurs differently.
Is there a way to tell if the function being called originated from a click event?
Any function that is triggered with an event is sent an event object. Call .type on this object and it will return which event it is. Here is a simple example from the jQuery docs:
$( "a" ).click(function( event ) {
alert( event.type ); // "click"
});
So lets say you want to listen for both clicks and typing in a text input:
$( "input" ).on("click keyup", eventHandler);
But you want to do something special on a click:
eventHandler = function(event){
if (event.type === 'click'){
// code to execute if there is a click
} else {
// code to execute if there is a non-click event
}
// code to execute for both click and non-click events
};
That would be the event.type
var elem = document.getElementById('test');
elem.addEventListener('click', function(event) {
console.log(event.type)
}, false);
FIDDLE
or in jQuery
$('#test').on('click paste mouseenter', function(event) {
console.log(event.type)
});
FIDDLE
See it:
DEMO
$('div').click(test);
function test(e){
if(e && e.type === 'click')
alert('called from click!');
else alert('NOT called from click!');
}
test();
demo
function myFn( evt ){
console.log( evt.type );
}
$('div').on('click mouseenter mouseleave', myFn);
I have a MooTools script (please dont ask why..) where elements are added a mouseenter event. In jQuery, I open/show those elements within a fancybox. When it pops up, the mouseenter event wont get fired in the first place since the cursor is already on an element eventually, depending where the user clicks to open the fancybox. But the jQuery mousemove event does fire on those.
I could just add a mousemove event in the MooTools file which triggers the mouseenter event, but for the sake of learning: how would I fire an elements event function (and make use of the this-reference)?
This didnt work for me.
MooTools:
$$('.foo').addEvents({
mouseenter: function(){
console.log('fired!'); // never does ):
// stuff happens here
}
});
jQuery:
$('#bar').fancybox({
onComplete: function() {
$('.foo').unbind('mousemove').mousemove(function() {
var el = this;
console.log('mousemoved');
$('.foo').unbind('mousemove');
// does not work:
(function($$) {
$$(this).fireEvent('mouseenter', $(this));
})(document.id);
// neither does this:
var event;
if (document.createEvent) {
event = document.createEvent("HTMLEvents");
event.initEvent("mousemove", true, true);
} else {
event = document.createEventObject();
event.eventType = "mousemove";
}
event.eventName = "mousemove";
event.memo = {};
if (document.createEvent) {
this.dispatchEvent(event);
}
else {
this.fireEvent("on" + event.eventType, event);
}
// whats the solution?
// something like: this.fireEvent('mouseenter', this); would be cool!
});
}
});
Just get to your jQuery Element and then call the fireEvent from the Element.prototype
// does not work:
(function($$) {
$$(this).fireEvent('mouseenter', $(this));
})(document.id);
to:
$(this)[0].fireEvent('mouseenter' /* optional event obj, { target: $(this)[0] } */);
// or as #Sergio suggests -
this.fireEvent('mouseenter'); // this == element anyway
I would like a cross modern browser way to take a mouse event from one html element and pass it on to another.
eg.
el1.addEventListener('mousemove', function(e) {
el2.trigger('mousemove', e);
});
el2.addEventListener('mousemove', function(e) {
//THIS SHOULD BE CALLED WHEN EITHER el1
});
a jquery solution is ok but I would prefer a non-jquery solution. Is this simple?
Here is the correct code
var el1 = document.getElementById('el1');
var el2 = document.getElementById('el2');
el1.onmousemove = function(e) {
alert('el1 event');
el2.onmousemove(e);
};
el2.onmousemove = function(e) {
alert('el2 event');
};
demo
This is good if you want the event argument e to pass over to el2's event. This updated demo shows mouse position being passed over.
native should work like that
var evt;
el1.onmousemove = function() {
evt = document.createEvent('MouseEvent');
evt.initEvent('mousemove', true, true);
el2.dispatchEvent(evt);
}
You can read up on element.dispatchEvent here:
https://developer.mozilla.org/en-US/docs/DOM/element.dispatchEvent
If you accept a jQuery answer then here's the code:
// el1 and el2 are the jQuery objects of the DOM elements
el1.mousemove(function (event) {
el2.mousemove(event);
});
In pure javascript:
el1.onmousemove = function(e) {
el2.onmousemove('mousemove', e);
};
el2.onmousemove = function(e) {
};
el1.addEventListener('mousemove', handler, false);
el2.addEventListener('mousemove', handler2, false);
function handler(e) {
// do some stuff
handler2.call(el2, e); // pass el2 as this reference, event as the argument.
};
not too sure if this is what you are looking for, just name the event handlers and trigger the one off the other.
if you do not need the this reference in the second handler, use handler2(e); instead.
further readings:
Function.prototype.call
Here is a half-baked demo passing the mouse event args. I'm unsure how well supported layerX/Y is, I just used it to show the demo.
I want to show a menu after a click, drag, and release action.
How do I trigger that with jQuery?
Listen for a mousedown event on whatever should be clicked on.
Add a mousemove and mouseup event handler to the window
In the mouseup event handler call trigger('yourcustomeventhere') on whatever element you please. Also, remove the mouseup and mousemove event handlers from window
...?
profit.
jQuery is the library that will do this for you. I thought I explained the code well enough, but apparantly not:
$(anElement).mousedown(foodown);
function foodown(){
$(window).mousemove(foomove).mouseup(fooup);
//stuff
}
function foomove(){
//stuff
}
function fooup(){
$(someElement).trigger('yourcustomevent');
$(window).unbind('mousemove', foomove).unbind('mouseup', fooup);
}
/**
* Dragondrop jQuery plugin by zzzzBov
*/
(function ($) {
"use strict";
var $window;
function begin(e) {
var event;
$window.mousemove(drag).mouseup(end);
event = $.Event('beginDragon');
$(e.target).trigger(event);
if (event.isDefaultPrevented()) {
e.preventDefault();
}
}
function drag(e) {
var event;
event = $.Event('dragDragon');
$(e.target).trigger(event);
if (event.isDefaultPrevented()) {
e.preventDefault();
}
}
function end(e) {
var event;
event = $.Event('endDragon');
$(e.target).trigger(event);
$window.unbind('mousemove', drag).unbind('mouseup', end);
if (event.isDefaultPrevented()) {
e.preventDefault();
}
}
$.each('beginDragon dragDragon endDragon'.split(' '), function (i, name) {
$.fn[name] = function(data,fn) {
if (fn == null) {
fn = data;
data = null;
}
return arguments.length > 0 ?
this.bind(name, data, fn) :
this.trigger(name);
};
});
$window = $(window);
$window.mousedown(begin);
}(jQuery));
You could use the jQueryUI and let it do a lot for you. It also comes with a create UI (of course, because it's jQuery UI)
Take a look at this: http://jqueryui.com/demos/droppable/
edit:
Or take a look here: http://jqueryui.com/demos/draggable/
Take a close look to the events used here.
jQuery UI has a drag and drop implementation. If that doesn't do what you do, you'll have to roll your own implementation by tracking the mouseup and mousedown events on the element yourself. (And possibly mouseleave to detect if the mouse left the area you want to track the gesture in.)
I have an anchor tag on my page, I want an event attached to it, which will fire when the display of this element change.
How can I write this event, and catch whenever the display of this element changes?
This is my way of doing on onShow, as a jQuery plugin. It may or may not perform exactly what you are doing, however.
(function($){
$.fn.extend({
onShow: function(callback, unbind){
return this.each(function(){
var _this = this;
var bindopt = (unbind==undefined)?true:unbind;
if($.isFunction(callback)){
if($(_this).is(':hidden')){
var checkVis = function(){
if($(_this).is(':visible')){
callback.call(_this);
if(bindopt){
$('body').unbind('click keyup keydown', checkVis);
}
}
}
$('body').bind('click keyup keydown', checkVis);
}
else{
callback.call(_this);
}
}
});
}
});
})(jQuery);
You can call this inside the $(document).ready() function and use a callback to fire when the element is shown, as so.
$(document).ready(function(){
$('#myelement').onShow(function(){
alert('this element is now shown');
});
});
It works by binding a click, keyup, and keydown event to the body to check if the element is shown, because these events are most likely to cause an element to be shown and are very frequently performed by the user. This may not be extremely elegant but gets the job done. Also, once the element is shown, these events are unbinded from the body as to not keep firing and slowing down performance.
You can't get an onshow event directly in JavaScript. Do remember that the following methods are non-standard.
IN IE you can use
onpropertychange event
Fires after the property of an element
changes
and for Mozilla
you can use
watch
Watches for a property to be assigned
a value and runs a function when that
occurs.
You could also override jQuery's default show method:
var orgShow = $.fn.show;
$.fn.show = function()
{
$(this).trigger( 'myOnShowEvent' );
orgShow.apply( this, arguments );
return this;
}
Now just bind your code to the event:
$('#foo').bind( "myOnShowEvent", function()
{
console.log( "SHOWN!" )
});
The code from this link worked for me: http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/
(function ($) {
$.each(['show', 'hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
return el.apply(this, arguments);
};
});
})(jQuery);
$('#foo').on('show', function() {
console.log('#foo is now visible');
});
$('#foo').on('hide', function() {
console.log('#foo is hidden');
});
However the callback function gets called first and then the element is shown/hidden. So if you have some operation related to the same selector and it needs to be done after being shown or hidden, the temporary fix is to add a timeout for few milliseconds.