Skip to content

Commit

Permalink
added .bind and .unbind, improved .delegate, added swipe plug…
Browse files Browse the repository at this point in the history
…in, added test page for events, fixed `classList` for the iOS (String.prototype.trim isn't supported);
  • Loading branch information
millermedeiros committed Sep 24, 2010
1 parent fdc136a commit 9b22c8d
Show file tree
Hide file tree
Showing 14 changed files with 535 additions and 59 deletions.
32 changes: 26 additions & 6 deletions README.markdown
Expand Up @@ -40,7 +40,7 @@ The ultimate goal is to have a ~2k library that handles most basic dredge work f
- `.delegate(selector, eventType, handler)` : Attach an Event listener to matched elements using the event delegation pattern.
- `.hasClass(className)` : Check if any matched element has given class.
- `.addClass(className)` : Add one or more classes (separated by spaces) into each matched element.
- `.removeClass(className)` : Removes one or more class names (separated by spaces) from mathched elements, removes all classes if `null`.
- `.removeClass(className)` : Removes one or more class names (separated by spaces) from matched elements, removes all classes if `null`.
- `.toggleClass(className, switch)` : Add or remove one or more classes from each element in the set of matched elements.
- `.add(elementsArray)` : Add a set of elements to the matched elements set.
- `.map(callbackFn(i, element))` : Pass each element in the current matched set through a function, producing a new zepto object containing the return values.
Expand All @@ -53,12 +53,30 @@ The ultimate goal is to have a ~2k library that handles most basic dredge work f
- `$.extend(firstObj, secondObj)` : Mixin, copy properties from one object into another, will extend `zepto` by default if second parameter is omitted.
- `$.map(array, callbackFn)` : Translate all items in an array or array-like object to another array of items. (similar to similar to `jQuery.map` and not to `Array.prototype.map`)

### Event Handlers ("live" events) ###
### Event Handlers ###

#### delegate ####
#### bind/unbind ####

$('body').delegate('div.touchable', 'touchstart', function(evt){
alert("I'm touched!");
- `.bind(eventType, eventHandler)` : Attach event listener onto each matched element.
- `.unbind(eventType, eventHandler)` : Remove event listener from each matched element, *(both parameters are required)*.

##### example #####

var handler = function(evt){
$(this).unbind('touchstart', handler); //remove listener after first call, so it will be called only once per matched element
alert("yay!");
};

$('#my_div').bind('touchstart', handler); //add listener


#### delegate ("live" event) ####

`.delegate(selector, eventType, eventHandler)` : Listen for events triggered by descendant nodes of matched elements - A.K.A "event delegation".

//will trigger when any descendant element of "#my_div" that has the class ".touchable" is touched
$('#my_div').delegate('.touchable', 'touchstart', function(evt){
alert("I'm touched!");
});


Expand All @@ -80,7 +98,9 @@ The ultimate goal is to have a ~2k library that handles most basic dredge work f

### Recommendations ###

Best used if you stick in the contents of zepto.min.js into a `<script>` tag in your HTML (no need to load it form an external file).
- Make sure the site still works without JavaScript since many devices doesn't support it! Use it as an enhancement and not as a prerequisite.
- Best used if you stick in the contents of zepto.min.js into a `<script>` tag in your HTML (no need to load it form an external file).
- Compress your JavaScript files before deploying.

I'd love some help on this, so please feel free to mess around!

Expand Down
4 changes: 2 additions & 2 deletions dev/build/build.number
@@ -1,3 +1,3 @@
#Build Number for ANT. Do not edit!
#Thu Sep 23 17:03:44 EDT 2010
build.number=10
#Fri Sep 24 17:36:45 EDT 2010
build.number=15
2 changes: 1 addition & 1 deletion dev/build/build.properties
Expand Up @@ -2,7 +2,7 @@

## PROPERTIES ##

version_number = 0.1.3
version_number = 0.1.4
dist.name = zepto.js
dist.min.name = zepto.min.js

Expand Down
8 changes: 7 additions & 1 deletion dev/build/build.xml
Expand Up @@ -54,7 +54,13 @@
<echo message="${dist.min.name} built." />
</target>

<target name="all" depends="build, minify">
<target name="copyExtras">
<copy todir="${js_deploy.dir}/extras">
<fileset dir="${src.dir}/extras" />
</copy>
</target>

<target name="all" depends="build, minify, copyExtras">
<echo message="Build Complete." />
</target>

Expand Down
16 changes: 13 additions & 3 deletions dev/src/classlist.js
Expand Up @@ -9,15 +9,25 @@

//--- As of 2010/09/23 native HTML5 Element.classList is only supported by Firefox 3.6+ ---//

var regexSpaces = /\s+/g;
var regexSpaces = /\s+/g,
regexTrim = /^\s+|\s+$/g;

/**
* remove multiple spaces and trailing spaces
* @param {string} className
* @return {string}
*/
function sanitize(className){
return className.replace(regexSpaces, ' ').trim();
return trim( className.replace(regexSpaces, ' ') );
}

/**
* Remove white spaces from begining and end of string
* - as of 2010/09/24 Safari Mobile doesn't support `String.prototype.trim`
* @param {string} str
*/
function trim(str){
return str.replace(regexTrim, '');
}

/**
Expand Down Expand Up @@ -100,7 +110,7 @@
if(zepto.isDef(isAdd)){
(isAdd)? this.addClass(className) : this.removeClass(className);
}else{
var classes = className.trim().split(' '),
var classes = trim(className).split(' '),
regex,
elements = this.get(); //for scope and performance
classes.forEach(function(c){
Expand Down
4 changes: 2 additions & 2 deletions dev/src/core.js
Expand Up @@ -27,12 +27,12 @@
context = selector;
matched = [selector];
selector = null;
}else if(selector instanceof zepto){ //zepto object
}else if(selector instanceof zepto){ //"clone" zepto object
selector = selector.selector;
context = selector.context;
}

if(context instanceof zepto){
if(context instanceof zepto){ //if finding descendant node(s) of all matched elements
matched = [];
context.each(function(el){
matched = matched.concat( zepto.makeArray(el.querySelectorAll(selector)) );
Expand Down
36 changes: 26 additions & 10 deletions dev/src/event.js
Expand Up @@ -5,28 +5,44 @@
zepto.fn.extend({

/**
* @param {string} selector
* @param {string} eventType
* @param {string} eventType Event type.
* @param {function(Event)} handler Event handler.
*/
bind : function(eventType, handler){
return this.each(function(el){
el.addEventListener(eventType, handler, false);
});
},

/**
* @param {string} eventType Event type.
* @param {function(Event)} handler Event handler.
*/
unbind : function(eventType, handler){
return this.each(function(el){
el.removeEventListener(eventType, handler, false);
});
},

/**
* @param {string} selector Selector
* @param {string} eventType Event type that it should listen to. (supports a single kind of event)
* @param {function(this:HTMLElement, Event)} callback
* @return {zepto}
*/
delegate : function(selector, eventType, callback){
return this.each(function(elm){
var
root = elm,
targets = this.find(selector).get();

var targets = this.find(selector).get();
return this.each(function(el){
function delegateHandler(evt){
var node = evt.target;
while(node && targets.indexOf(node)<0){
node = node.parentNode;
}
if(node && node !== root){
if(node && node !== el){
callback.call(node, evt);
}
}

elm.addEventListener(eventType, delegateHandler, false);
el.addEventListener(eventType, delegateHandler, false);
});
}

Expand Down
71 changes: 71 additions & 0 deletions dev/src/extras/swipe.js
@@ -0,0 +1,71 @@

/* -- zepto.js : swipe plugin ------------------- */

(function(zepto){

/**
* @param {string} direction Swipe direction ('left', 'right', 'up', 'down')
* @param {function({direction: string, changeX: number, changeY: number})} callback
* @param {{x: number, y: number}} threshold
*/
zepto.fn.swipe = function(direction, callback, threshold){

var thold = {x:30, y:30}, //default threshold
origin = {x:0, y:0},
dest = {x:0, y:0},
isVertical = (direction === 'up' || direction === 'down');

if(threshold) zepto.extend(thold, threshold); //overwrite default threshold

function updateCords(cordsObj, evt){
cordsObj.x = evt.targetTouches[0].pageX;
cordsObj.y = evt.targetTouches[0].pageY;
}

function onTouchStart(evt){
updateCords(origin, evt);
}

function onTouchMove(evt){
evt.preventDefault();
updateCords(dest, evt);
}

function onTouchEnd(evt){
var changeX = origin.x - dest.x,
changeY = origin.y - dest.y,
distX = Math.abs(changeX),
distY = Math.abs(changeY),
evtInfo = {
changeX : changeX,
changeY : changeY,
direction : direction
};

if(!isVertical && distX >= thold.x && distY <= thold.y){
if( (direction === 'left' && changeX > 0) || (direction === 'right' && changeX < 0) ){
callback.call(evt.currentTarget, evtInfo); //assign `this` to element (used "currentTarget" instead of "target" because of event bubbling)
}
}else if(isVertical && distX <= thold.x && distY >= thold.y){
if( (direction === 'up' && changeY > 0) || (direction === 'down' && changeY < 0) ){
callback.call(evt.currentTarget, evtInfo); //assign `this` to element (used "currentTarget" instead of "target" because of event bubbling)
}
}
}

this.bind('touchstart', onTouchStart);
this.bind('touchmove', onTouchMove);
this.bind('touchend', onTouchEnd);
//swipe doesn't require 'touchcancel' since 'touchend' won't be called then.

return this; //chain
};

//create aliases "touchLeft", "touchRight", etc..
'left right up down'.split(' ').forEach(function(direction){
zepto.fn['swipe'+ direction.substr(0,1).toUpperCase() + direction.substr(1)] = function(callback, threshold){
return this.swipe(direction, callback, threshold);
};
});

}(zepto));
7 changes: 4 additions & 3 deletions dev/src/style.js
Expand Up @@ -6,12 +6,12 @@ zepto.fn.extend({

/**
* Set style of matched elements.
* @param {string} style CSS string.
* @param {string} css CSS string.
* @return {zepto}
*/
css : function(style){
css : function(css){
return this.each(function(el){
el.style.cssText += ';'+ style;
el.style.cssText += ';'+ css;
});
},

Expand All @@ -23,6 +23,7 @@ zepto.fn.extend({
* @return {zepto}
*/
anim : function(transform, opacity, duration){
//TODO: change the way anim works, since it's overwriting the "-webkit-transition:all" it's hard to change other CSS values later without animation.
return this.css('-webkit-transition:all '+ (duration||0.5) +'s;'+'-webkit-transform:'+ transform +';opacity:'+ (opacity===0?0:opacity||1) );
}

Expand Down

0 comments on commit 9b22c8d

Please sign in to comment.