Hammer.js with plain javascript - javascript

How to use hammer JS events without JQuery selectors just using plain Javascript methods?

Bind hammer to a container element:
var hammer = new Hammer(document.getElementById("container"));
Now, on every gesture that is performed on the container element,
you'll receive a callback object with information on the gesture.
Some example functions:
hammer.ondragstart = function(ev) { };
hammer.ondrag = function(ev) { };
hammer.ondragend = function(ev) { };
hammer.onswipe = function(ev) { };
hammer.js is available as completely standalone version, so you don't need to import jquery resources. See: http://eightmedia.github.com/hammer.js/
Full documentation: https://github.com/eightmedia/hammer.js#documentation

Just a quick look over the GitHub documentation:
var hammer = new Hammer(document.getElementById("container"));
creates a 'hammer' without jQuery. After that you can set callback functions, you don't need any jQuery for that too. But beware! HammerJS might need jQuery internally, so it is possible you can't leave out the <script src="path/to/jquery.js"></script>

The short answer is: just use the plain old DOM API. You're not obliged, or forced to use nothing but jQuery once you've included it.
var someElements = document.querySelectorAll('.someClass');//not jQuery, perfectly valid
var byId = document.getElementById('someId');
var sameScript = $('#anotherId');//nothing stops me from doing this... using jQ for some things
If you find the DOM API a bit clunky (which it is), you might as well do something like this:
var pureDOMRef = $('someID')[0];//returns "normal" Element object, removes jQ wrapper
var multiple = Array.prototype.slice.apply($('.classSelector'),[0]);//returns Array
Just play around, switch back and forth if you want to, nothing wrong with that

The new version of hammer.js provides a JQuery plugin which has to be understand first that it's not a plugin from JQuery - it is FOR JQuery. So if you use JQuery for your site for other purposes then it's convenient that you can basically 'apply' a plugin from hammer at a JQuery selector like this:
$(element).hammer(options).bind("pan", myPanHandler);
Since hammer.js has a modern OOP pattern it can use instances for multiple data handling at once, hence every JQuery element that is bound to hammer is an instance. (IMHO) JQuery slows down by some ms, if you don't mind use this plugin or stay with Vanilla.
http://hammerjs.github.io/jquery-plugin/

Related

Trigger jQuery when a vanilla js function has been fired

I got a jQuery function that catches changes on a input field and add it to a variable.
The input field is also held up on a vanilla js based API lib, that I cant convert to jQuery.
The lib is an address API, so people can select a address, and that wont trigger my jQuery function. I therefore thought of a workaround, where my jQuery is watching my vanilla js, to see when it's fired, and fire my jQuery function right after.
My jQuery function:
$('#billing_address_1').on('input',function(e){
let addressValue = $('#billing_address_1').val();
});
My vanilla js function:
"use strict"
dawaAutocomplete.dawaAutocomplete( document.getElementById("billing_address_1"), {
select: function(selected) {
document.getElementById("valgtadresse").innerHTML = selected.tekst;
}
});
All solutions I've been able to search for, has been requiring that I use .trigger() on my vanilla js in this case. They've not been made for the mix of these two js alternatives. Can I do it in a more proper way?
If you don't want to touch your fields with trigger you can try event emitter pattern which is quite popular in node. Here you keep an object as notifier on which you call event and also hook listeners for that event. It is basically a Pub-Sub pattern a simple implementation of which in vanilla javascript is available over here by mudge or you might also try any alternatives if you find
// KEEP THIS SOMEWHERE IN OUTER SCOPE
let bird = new EventEmitter()
//THEN - hook on any event you name it
bird.on('tweet', (val)=>{
console.log(val)
addressValue = val
})
//THEN - emit that named event wherever you might need
dawaAutocomplete.dawaAutocomplete( document.getElementById("billing_address_1"), {
select: function(selected) {
document.getElementById("valgtadresse").innerHTML = selected.tekst;
bird.emit('tweet', selected.tekst);
}
});

Add method to chaining in jQuery plugin

I am trying to write an auto complete jQuery plugin.
The desired usage:
$('.advancedSelect').advancedSelect({/*plugin options*/}).change(function(){})/*.otherJQueryMethods*/;
The implementation:
$.fn.advancedSelect = function({
return this.each(function(){
var $advSel = $('<input/>');
var $el = $(this).after($advSel).hide();
/* my codes on desired functionalities */
/* how is it possible to trigger the chained change method */
});
});
In a comment on my soon-to-be-deleted answer (as it answered a question other than your real question, as it turns out), you've said:
I was wondering whether we could have a syntax like this:
$('.advancedSelect').advancedSelect({/*plugin options*/}).onChange(function(){}).css({})
-and by .css I meant any other jQuery's methods.
I would suggest either this:
$('.advancedSelect').advancedSelect({/*other plugin options*/, onChange: function(){}}).css({})
or this:
$('.advancedSelect').advancedSelect({/*plugin options*/}).advancedSelect("onChange", function(){}).css({})
... with a fairly strong preference for the first one. :-)
Re that first option, an adjunct you see a lot is an optional "options" method you can use later to change options::
// Initial setup
$('.advancedSelect').advancedSelect({/*other plugin options*/, onChange: function(){}}).css({})
// Later, I need to change something
$('.advancedSelect').advancedSelect("options", { onChange: function(){}});
Side note: If this change-like method is to register a change handler, why not just use jQuery's change (or on with some plugin-specific event name) and have your plugin raise an event? That's how I would handle any kind of event-related thing in a plugin. Look at bootstrap's use of shown.bs.modal and such, for instance.

Using jquery Callbacks.fire method as a event handler

So I've got a jquery project where I'm using an external class that has callback style events.
Meaning, it has an "onSave" property that takes one function. However, I need to more than one other components to hook into it.
What I've settled on for now, goes like this:
var saveCallbacks = $.Callbacks();
saveCallbacks.fire.callbacks = saveCallbacks;
globalDoodad.onSave = saveCallbacks.fire;
which allows me to do this in my other components:
globalDoodad.onSave.callbacks.add( myMethod );
Is there a better way to handle this? It seems to be working ok, just has a bit of a smell to it.

Listening and firing events with Javascript and maybe jQuery

In my JavaScript and Flex applications, users often perform actions that I want other JavaScript code on the page to listen for. For example, if someone adds a friend. I want my JavaScript app to then call something like triggerEvent("addedFriend", name);. Then any other code that was listening for the "addedFriend" event will get called along with the name.
Is there a built-in JavaScript mechanism for handling events? I'm ok with using jQuery for this too and I know jQuery makes extensive use of events. But with jQuery, it seems that its event mechanism is all based around elements. As I understand, you have to tie a custom event to an element. I guess I can do that to a dummy element, but my need has nothing to do with DOM elements on a webpage.
Should I just implement this event mechanism myself?
You have a few options:
jQuery does allow you to do this with objects not associated with the document. An example is provided below.
If you're not already using jQuery on your page, then adding it is probably overkill. There are other libraries designed for this. The pattern you are referring to is called PubSub or Publish/Subscribe.
Implement it yourself, as you've suggested, since this is not difficult if you're looking only for basic functionality.
jQuery example:
var a = {};
jQuery(a).bind("change", function () {
alert("I changed!");
});
jQuery(a).trigger("change");
I would implement such using MVVM pattern with knockjs library.
Just create an element, and use jquery events on it.
It can be just a global variable, doesn't even have to be connected to the DOM.
That way you accomplish your task easily and without any extra libs.
Isn't it possible to bind onchange events in addition to click events? For instance, if addFriend is called and modifies a list on the page, you could bind the change event to then invoke additional functionality.
$('#addFriendButton').click( function() {
// modify the #friendList list
});
$('#friendList').change( function() {
myOtherAction();
});
This is total Host independent, no need for jQuery or dom in this case!
function CustomEvents(){
//object holding eventhandlers
this.handlers_ = {};
}
//check if the event type does not exist, create it.
//then push new callback in array.
CustomEvents.prototype.addEventListner = function (type, callBack){
if (!this.handlers_[type]) this.handlers_[type] = [];
this.handlers_[type].push(callBack);
}
CustomEvents.prototype.triggerEvent = function (type){
//trigger all handlers attached to events
if (!this.handlers_[type]) return;
for (var i=0, handler; handler = this.handlers_[type][i]; i++)
{
//call handler function and supply all the original arguments of this function
//minus the first argument which is the type of the event itself
if (typeof handler === "function") handler.apply(this,arguments.slice(1));
}
}
//delete all handlers to an event
CustomEvents.prototype.purgeEventType = function(type){
return delete this.handlers_[type];
}
test:
var customEvents = new CustomEvents();
customEvents.addEventListner("event A", function(arg){alert('Event A with arguments' + arg);));
customEvents.triggerEvent("event A", "the args");
EDIT added arguments passing

A better way to search for events?

I recently found myself in the situation that I needed to remove a function bound to the resize event of the window by WordPress' media manager (media-upload.js), because it was interfering with the proper use of Thickbox. The event is attached like this:
a(window).resize(function(){tb_position()})
It took me a while, but I finally found out I could do it in this way:
jQuery.each( jQuery(window).data('events')['resize'], function(i, event) {
var thisEvent = event.toString().replace(/\n/g, '').replace(/\t/g, '').split(' ').join('');
var expectedEvent = 'function(){tb_position()}';
if (thisEvent == expectedEvent)
delete jQuery(window).data(‘events’)[‘resize’][i];
})
Here I cycle through the events, removing spaces, tabs and new lines from them and compare them to what I'm looking for, and when I find it I throw it out of the goddamn airlock. It happens in this case that the attached function perhaps doesn't have spaces, tabs or new lines, but this way also works with more complicated functions as far as I can tell.
Is there an easier and/or more elegant way of doing this? Is this a recipe for disaster down the road?
When you register a handler for an event, you can use a qualifier:
$('#something').bind('click.removeMeSomeday', function() { ... });
Then when you need to remove it you can do so without bothering other handlers for "click".
Now, it occurs to me that you may not be able to affect the way that Wordpress binds its event handler.
Another way around might be to use WordPress' system for queueing/unqueueing or registering/deregistering scripts. Unregister media-upload.js, and then queue your own version of it.
http://codex.wordpress.org/Function_Reference/wp_enqueue_script
http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-includes/functions.wp-scripts.php.source.html#l74
http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-includes/functions.wp-scripts.php.source.html#l37
Prem

Categories

Resources