special attributes in tag that are processed by javascript file - html

Impress.js supports a number of attributes:
data-x, data-y, data-z will move the slide on the screen in 3D space;
data-rotate, data-rotate-x, data-rotate-y rotate the element around the specified axis (in degrees);
data-scale – enlarges or shrinks the slide.
div id="intro" class="step" data-x="0" data-y="0">
<h2>Introducing Galaxy Nexus</h2>
<p>Android 4.0<br /> Super Amoled 720p Screen<br />
<img src="assets/img/nexus_1.jpg" width="232" height="458" alt="Galaxy Nexus" />
<!-- We are offsetting the second slide, rotating it and making it 1.8 times larger -->
<div id="simplicity" class="step" data-x="1100" data-y="1200" data-scale="1.8" data-rotate="190">
<h2>Simplicity in Android 4.0</h2>
<p>Android 4.0, Ice Cream Sandwich brings an entirely new look and feel..</p>
<img src="assets/img/nexus_2.jpg" width="289" height="535" alt="Galaxy Nexus" />
Impress.js
(function ( document, window ) {
'use strict';
// HELPER FUNCTIONS
var pfx = (function () {
var style = document.createElement('dummy').style,
prefixes = 'Webkit Moz O ms Khtml'.split(' '),
memory = {};
return function ( prop ) {
if ( typeof memory[ prop ] === "undefined" ) {
var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
props = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');
memory[ prop ] = null;
for ( var i in props ) {
if ( style[ props[i] ] !== undefined ) {
memory[ prop ] = props[i];
break;
}
}
}
return memory[ prop ];
}
})();
var arrayify = function ( a ) {
return [].slice.call( a );
};
var css = function ( el, props ) {
var key, pkey;
for ( key in props ) {
if ( props.hasOwnProperty(key) ) {
pkey = pfx(key);
if ( pkey != null ) {
el.style[pkey] = props[key];
}
}
}
return el;
}
var byId = function ( id ) {
return document.getElementById(id);
}
var $ = function ( selector, context ) {
context = context || document;
return context.querySelector(selector);
};
var $$ = function ( selector, context ) {
context = context || document;
return arrayify( context.querySelectorAll(selector) );
};
var translate = function ( t ) {
return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) ";
};
var rotate = function ( r, revert ) {
var rX = " rotateX(" + r.x + "deg) ",
rY = " rotateY(" + r.y + "deg) ",
rZ = " rotateZ(" + r.z + "deg) ";
return revert ? rZ+rY+rX : rX+rY+rZ;
};
var scale = function ( s ) {
return " scale(" + s + ") ";
};
var getElementFromUrl = function () {
// get id from url # by removing `#` or `#/` from the beginning,
// so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work
return byId( window.location.hash.replace(/^#\/?/,"") );
};
// CHECK SUPPORT
var ua = navigator.userAgent.toLowerCase();
var impressSupported = ( pfx("perspective") != null ) &&
( document.body.classList ) &&
( document.body.dataset ) &&
( ua.search(/(iphone)|(ipod)|(android)/) == -1 );
var roots = {};
var impress = window.impress = function ( rootId ) {
rootId = rootId || "impress";
// if already initialized just return the API
if (roots["impress-root-" + rootId]) {
return roots["impress-root-" + rootId];
}
// DOM ELEMENTS
var root = byId( rootId );
if (!impressSupported) {
root.className = "impress-not-supported";
return;
} else {
root.className = "";
}
// viewport updates for iPad
var meta = $("meta[name='viewport']") || document.createElement("meta");
// hardcoding these values looks pretty bad, as they kind of depend on the content
// so they should be at least configurable
meta.content = "width=1024, minimum-scale=0.75, maximum-scale=0.75, user-scalable=no";
if (meta.parentNode != document.head) {
meta.name = 'viewport';
document.head.appendChild(meta);
}
var canvas = document.createElement("div");
canvas.className = "canvas";
arrayify( root.childNodes ).forEach(function ( el ) {
canvas.appendChild( el );
});
root.appendChild(canvas);
var steps = $$(".step", root);
// SETUP
// set initial values and defaults
document.documentElement.style.height = "100%";
css(document.body, {
height: "100%",
overflow: "hidden"
});
var props = {
position: "absolute",
transformOrigin: "top left",
transition: "all 0s ease-in-out",
transformStyle: "preserve-3d"
}
css(root, props);
css(root, {
top: "50%",
left: "50%",
perspective: "1000px"
});
css(canvas, props);
var current = {
translate: { x: 0, y: 0, z: 0 },
rotate: { x: 0, y: 0, z: 0 },
scale: 1
};
var stepData = {};
var isStep = function ( el ) {
return !!(el && el.id && stepData["impress-" + el.id]);
}
steps.forEach(function ( el, idx ) {
var data = el.dataset,
step = {
translate: {
x: data.x || 0,
y: data.y || 0,
z: data.z || 0
},
rotate: {
x: data.rotateX || 0,
y: data.rotateY || 0,
z: data.rotateZ || data.rotate || 0
},
scale: data.scale || 1,
el: el
};
if ( !el.id ) {
el.id = "step-" + (idx + 1);
}
stepData["impress-" + el.id] = step;
css(el, {
position: "absolute",
transform: "translate(-50%,-50%)" +
translate(step.translate) +
rotate(step.rotate) +
scale(step.scale),
transformStyle: "preserve-3d"
});
});
// making given step active
var active = null;
var hashTimeout = null;
var goto = function ( el ) {
if ( !isStep(el) || el == active) {
// selected element is not defined as step or is already active
return false;
}
// Sometimes it's possible to trigger focus on first link with some keyboard action.
// Browser in such a case tries to scroll the page to make this element visible
// (even that body overflow is set to hidden) and it breaks our careful positioning.
//
// So, as a lousy (and lazy) workaround we will make the page scroll back to the top
// whenever slide is selected
//
// If you are reading this and know any better way to handle it, I'll be glad to hear about it!
window.scrollTo(0, 0);
var step = stepData["impress-" + el.id];
if ( active ) {
active.classList.remove("active");
}
el.classList.add("active");
root.className = "step-" + el.id;
// `#/step-id` is used instead of `#step-id` to prevent default browser
// scrolling to element in hash
//
// and it has to be set after animation finishes, because in chrome it
// causes transtion being laggy
window.clearTimeout( hashTimeout );
hashTimeout = window.setTimeout(function () {
window.location.hash = "#/" + el.id;
}, 1000);
var target = {
rotate: {
x: -parseInt(step.rotate.x, 10),
y: -parseInt(step.rotate.y, 10),
z: -parseInt(step.rotate.z, 10)
},
translate: {
x: -step.translate.x,
y: -step.translate.y,
z: -step.translate.z
},
scale: 1 / parseFloat(step.scale)
};
// check if the transition is zooming in or not
var zoomin = target.scale >= current.scale;
// if presentation starts (nothing is active yet)
// don't animate (set duration to 0)
var duration = (active) ? "1s" : "0";
css(root, {
// to keep the perspective look similar for different scales
// we need to 'scale' the perspective, too
perspective: step.scale * 1000 + "px",
transform: scale(target.scale),
transitionDuration: duration,
transitionDelay: (zoomin ? "500ms" : "0ms")
});
css(canvas, {
transform: rotate(target.rotate, true) + translate(target.translate),
transitionDuration: duration,
transitionDelay: (zoomin ? "0ms" : "500ms")
});
current = target;
active = el;
return el;
};
var prev = function () {
var prev = steps.indexOf( active ) - 1;
prev = prev >= 0 ? steps[ prev ] : steps[ steps.length-1 ];
return goto(prev);
};
var next = function () {
var next = steps.indexOf( active ) + 1;
next = next < steps.length ? steps[ next ] : steps[ 0 ];
return goto(next);
};
window.addEventListener("hashchange", function () {
goto( getElementFromUrl() );
}, false);
window.addEventListener("orientationchange", function () {
window.scrollTo(0, 0);
}, false);
// START
// by selecting step defined in url or first step of the presentation
goto(getElementFromUrl() || steps[0]);
return (roots[ "impress-root-" + rootId ] = {
goto: goto,
next: next,
prev: prev
});
}
})(document, window);
// EVENTS
(function ( document, window ) {
'use strict';
// keyboard navigation handler
document.addEventListener("keydown", function ( event ) {
if ( event.keyCode == 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
switch( event.keyCode ) {
case 33: ; // pg up
case 37: ; // left
case 38: // up
impress().prev();
break;
case 9: ; // tab
case 32: ; // space
case 34: ; // pg down
case 39: ; // right
case 40: // down
impress().next();
break;
}
event.preventDefault();
}
}, false);
// delegated handler for clicking on the links to presentation steps
document.addEventListener("click", function ( event ) {
// event delegation with "bubbling"
// check if event target (or any of its parents is a link)
var target = event.target;
while ( (target.tagName != "A") &&
(target != document.body) ) {
target = target.parentNode;
}
if ( target.tagName == "A" ) {
var href = target.getAttribute("href");
// if it's a link to presentation step, target this step
if ( href && href[0] == '#' ) {
target = document.getElementById( href.slice(1) );
}
}
if ( impress().goto(target) ) {
event.stopImmediatePropagation();
event.preventDefault();
}
}, false);
// delegated handler for clicking on step elements
document.addEventListener("click", function ( event ) {
var target = event.target;
// find closest step element
while ( !target.classList.contains("step") &&
(target != document.body) ) {
target = target.parentNode;
}
if ( impress().goto(target) ) {
event.preventDefault();
}
}, false);
// touch handler to detect taps on the left and right side of the screen
document.addEventListener("touchstart", function ( event ) {
if (event.touches.length === 1) {
var x = event.touches[0].clientX,
width = window.innerWidth * 0.3,
result = null;
if ( x < width ) {
result = impress().prev();
} else if ( x > window.innerWidth - width ) {
result = impress().next();
}
if (result) {
event.preventDefault();
}
}
}, false);
})(document, window);
My question is the Impress.js supposedly to process the data-x, data-y, data-scale attribute of the div tag. But I don't see where the code in Impress.js is doing that. Can someone point it out?

This intro to datasets may help.
First this part checking support for .dataset:
// CHECK SUPPORT
var ua = navigator.userAgent.toLowerCase();
var impressSupported = ( pfx("perspective") != null ) &&
( document.body.classList ) &&
( document.body.dataset ) &&
( ua.search(/(iphone)|(ipod)|(android)/) == -1 );
Then this part of the code, about halfway down:
steps.forEach(function ( el, idx ) {
var data = el.dataset,
step = {
translate: {
x: data.x || 0,
y: data.y || 0,
z: data.z || 0
},
rotate: {
x: data.rotateX || 0,
y: data.rotateY || 0,
z: data.rotateZ || data.rotate || 0
},
scale: data.scale || 1,
el: el
};

Related

Fixed main content and slide menu as overlap on Multi Level Push Menu

I am using this menu for my responsive website.
https://tympanus.net/codrops/2013/08/13/multi-level-push-menu/
This works great, except that I am unable to change the behavior where it pushes the main content to the right. I want to make the main content fixed and instead the menu should overlap the main content.
I had tried many things, but not sure how to achieve this. Any help is appreciated.
You must change the component.css and mlpushmenu.js files:
In component.css:
Search this:
.mp-menu {
position: absolute; /* we can't use fixed here :( */
top: 0;
left: 0;
z-index: 1;
width: 300px;
height: 100%;
-webkit-transform: translate3d(-100%, 0, 0);
-moz-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
and change by this:
.mp-menu {
position: absolute; /* we can't use fixed here :( */
top: 0;
left: 0;
z-index: 1;
width: 300px;
height: 100%;
-webkit-transform: translate3d(-100%, 0, 0);
-moz-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
transition: all .5s;
}
Now change mlpushmenu.js by this:
/**
* mlpushmenu.js v1.0.0
* http://www.codrops.com
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2013, Codrops
* http://www.codrops.com
*/
;( function( window ) {
'use strict';
function extend( a, b ) {
for( var key in b ) {
if( b.hasOwnProperty( key ) ) {
a[key] = b[key];
}
}
return a;
}
// taken from https://github.com/inuyaksa/jquery.nicescroll/blob/master/jquery.nicescroll.js
function hasParent( e, id ) {
if (!e) return false;
var el = e.target||e.srcElement||e||false;
while (el && el.id != id) {
el = el.parentNode||false;
}
return (el!==false);
}
// returns the depth of the element "e" relative to element with id=id
// for this calculation only parents with classname = waypoint are considered
function getLevelDepth( e, id, waypoint, cnt ) {
cnt = cnt || 0;
if ( e.id.indexOf( id ) >= 0 ) return cnt;
if( classie.has( e, waypoint ) ) {
++cnt;
}
return e.parentNode && getLevelDepth( e.parentNode, id, waypoint, cnt );
}
// http://coveroverflow.com/a/11381730/989439
function mobilecheck() {
var check = false;
(function(a){if(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
return check;
}
// returns the closest element to 'e' that has class "classname"
function closest( e, classname ) {
if( classie.has( e, classname ) ) {
return e;
}
return e.parentNode && closest( e.parentNode, classname );
}
function mlPushMenu( el, trigger, options ) {
this.el = el;
this.trigger = trigger;
this.options = extend( this.defaults, options );
// support 3d transforms
this.support = Modernizr.csstransforms3d;
if( this.support ) {
this._init();
}
}
mlPushMenu.prototype = {
defaults : {
// overlap: there will be a gap between open levels
// cover: the open levels will be on top of any previous open level
type : 'overlap', // overlap || cover
// space between each overlaped level
levelSpacing : 12, // Percent of sublevels
// classname for the element (if any) that when clicked closes the current level
backClass : 'mp-back'
},
_init : function() {
// if menu is open or not
this.open = false;
// level depth
this.level = 0;
// the moving wrapper
this.wrapper = this.el;
this.theconts = document.getElementById( 'mp-pusher' );
// the mp-level elements
this.levels = Array.prototype.slice.call( this.el.querySelectorAll( 'div.mp-level' ) );
// save the depth of each of these mp-level elements
var self = this;
this.levels.forEach( function( el, i ) { el.setAttribute( 'data-level', getLevelDepth( el, self.el.id, 'mp-level' ) ); } );
// the menu items
this.menuItems = Array.prototype.slice.call( this.el.querySelectorAll( 'li' ) );
// if type == "cover" these will serve as hooks to move back to the previous level
this.levelBack = Array.prototype.slice.call( this.el.querySelectorAll( '.' + this.options.backClass ) );
// event type (if mobile use touch events)
this.eventtype = mobilecheck() ? 'touchstart' : 'click';
// add the class mp-overlap or mp-cover to the main element depending on options.type
classie.add( this.el, 'mp-' + this.options.type );
// initialize / bind the necessary events
this._initEvents();
},
_initEvents : function() {
var self = this;
// the menu should close if clicking somewhere on the body
var bodyClickFn = function( el ) {
self._resetMenu();
el.removeEventListener( self.eventtype, bodyClickFn );
};
// open (or close) the menu
this.trigger.addEventListener( this.eventtype, function( ev ) {
ev.stopPropagation();
ev.preventDefault();
if( self.open ) {
self._resetMenu();
}
else {
self._openMenu();
// the menu should close if clicking somewhere on the body (excluding clicks on the menu)
document.addEventListener( self.eventtype, function( ev ) {
if( self.open && !hasParent( ev.target, self.el.id ) ) {
bodyClickFn( this );
}
} );
}
} );
// opening a sub level menu
this.menuItems.forEach( function( el, i ) {
// check if it has a sub level
var subLevel = el.querySelector( 'div.mp-level' );
if( subLevel ) {
el.querySelector( 'a' ).addEventListener( self.eventtype, function( ev ) {
ev.preventDefault();
var level = closest( el, 'mp-level' ).getAttribute( 'data-level' );
if( self.level <= level ) {
ev.stopPropagation();
classie.add( closest( el, 'mp-level' ), 'mp-level-overlay' );
self._openMenu( subLevel );
}
} );
}
} );
// closing the sub levels :
// by clicking on the visible part of the level element
this.levels.forEach( function( el, i ) {
el.addEventListener( self.eventtype, function( ev ) {
ev.stopPropagation();
var level = el.getAttribute( 'data-level' );
if( self.level > level ) {
self.level = level;
self._closeMenu();
}
} );
} );
// by clicking on a specific element
this.levelBack.forEach( function( el, i ) {
el.addEventListener( self.eventtype, function( ev ) {
ev.preventDefault();
var level = closest( el, 'mp-level' ).getAttribute( 'data-level' );
if( self.level <= level ) {
ev.stopPropagation();
self.level = closest( el, 'mp-level' ).getAttribute( 'data-level' ) - 1;
self.level === 0 ? self._resetMenu() : self._closeMenu();
}
} );
} );
},
_openMenu : function( subLevel ) {
// increment level depth
++this.level;
// move the main wrapper
var levelFactor = ( this.level - 1 ) * this.options.levelSpacing,
translateVal = this.options.type === 'overlap' ? levelFactor : this.el.offsetWidth;
this._setTransform( 'translate3d(' + translateVal + '%,0,0)' );
if( subLevel ) {
// reset transform for sublevel
this._setTransform( '', subLevel );
// need to reset the translate value for the level menus that have the same level depth and are not open
for( var i = 0, len = this.levels.length; i < len; ++i ) {
var levelEl = this.levels[i];
if( levelEl != subLevel && !classie.has( levelEl, 'mp-level-open' ) ) {
this._setTransform( 'translate3d(-100%,0,0) translate3d(' + -1*levelFactor + '%,0,0)', levelEl );
}
}
}
// add class mp-pushed to main wrapper if opening the first time
if( this.level === 1 ) {
classie.add( this.theconts, 'mp-pushed' );
this.open = true;
}
// add class mp-level-open to the opening level element
classie.add( subLevel || this.levels[0], 'mp-level-open' );
},
// close the menu
_resetMenu : function() {
this._setTransform('translate3d(-100%,0,0)');
this.level = 0;
// remove class mp-pushed from main wrapper
classie.remove( this.theconts, 'mp-pushed' );
this._toggleLevels();
this.open = false;
},
// close sub menus
_closeMenu : function() {
var translateVal = this.options.type === 'overlap' ? ( this.level - 1 ) * this.options.levelSpacing : this.el.offsetWidth;
this._setTransform( 'translate3d(' + translateVal + '%,0,0)' );
this._toggleLevels();
},
// translate the el
_setTransform : function( val, el ) {
el = el || this.wrapper;
el.style.WebkitTransform = val;
el.style.MozTransform = val;
el.style.transform = val;
},
// removes classes mp-level-open from closing levels
_toggleLevels : function() {
for( var i = 0, len = this.levels.length; i < len; ++i ) {
var levelEl = this.levels[i];
if( levelEl.getAttribute( 'data-level' ) >= this.level + 1 ) {
classie.remove( levelEl, 'mp-level-open' );
classie.remove( levelEl, 'mp-level-overlay' );
}
else if( Number( levelEl.getAttribute( 'data-level' ) ) == this.level ) {
classie.remove( levelEl, 'mp-level-overlay' );
}
}
}
}
// add to global namespace
window.mlPushMenu = mlPushMenu;
} )( window );
Example: https://jsfiddle.net/ihojose/6kyhdLbx/

Making invisible sprite with phaser

I need some help with my code. I want to make the str sprite invisible after 10 seconds.
I'm using this link for help: http://phaser.io/examples/v2/time/basic-timed-event
var game = new Phaser.Game(500, 550, Phaser.AUTO);
//var picture;
var Pacman = function (game) {
this.map = null;
this.layer = null;
this.pacman = null;
this.safetile = 14;
this.gridsize = 16;
this.speed = 100;
this.threshold = 3;
this.turnSpeed = 200;
this.marker = new Phaser.Point();
this.turnPoint = new Phaser.Point();
this.directions = [ null, null, null, null, null ];
this.opposites = [ Phaser.NONE, Phaser.RIGHT, Phaser.LEFT, Phaser.DOWN, Phaser.UP ];
this.current = Phaser.NONE;
this.turning = Phaser.NONE;
this.score=0;
this.scoreText='';
this.bonus=0;
this.bonusText='';
};
Pacman.prototype = {
init: function () {
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.pageAlignHorizontally = true;
this.scale.pageAlignVertically = true;
Phaser.Canvas.setImageRenderingCrisp(this.game.canvas);
this.physics.startSystem(Phaser.Physics.ARCADE);
},
preload: function () {
// We need this because the assets are on github pages
// Remove the next 2 lines if running locally
this.load.baseURL = 'https://nikosdaskalos.github.io/pacman/';
this.load.crossOrigin = 'anonymous';
this.load.image('str', 'assets/str.png');
this.load.image('dot', 'assets/dot.jpg');
this.load.image('coin', 'assets/coin.jpg');
this.load.image('tiles', 'assets/pacman-tiles.png');
this.load.spritesheet('pacman', 'assets/pacman.png');
this.load.tilemap('map', 'assets/pacman-map.json', null, Phaser.Tilemap.TILED_JSON);
// Needless to say, graphics (C)opyright Namco
},
create: function () {
this.map = this.add.tilemap('map');
this.map.addTilesetImage('pacman-tiles', 'tiles');
this.layer = this.map.createLayer('Pacman');
//picture = game.add.sprite(game.world.centerX, game.world.centerY, 'str');
//picture.anchor.setTo(0.5, 0.5);
//game.time.events.add(Phaser.Timer.SECOND * 4, fadePicture, this);
this.dots = this.add.physicsGroup();
this.map.createFromTiles(36, this.safetile, 'str', this.layer, this.dots);
this.map.createFromTiles(7, this.safetile, 'dot', this.layer, this.dots);
this.map.createFromTiles(35, this.safetile, 'coin', this.layer, this.dots);
// The dots will need to be offset by 6px to put them back in the middle of the grid
this.dots.setAll('x', 6, false, false, 1);
this.dots.setAll('y', 6, false, false, 1);
// Pacman should collide with everything except the safe tile
this.map.setCollisionByExclusion([this.safetile], true, this.layer);
// Position Pacman at grid location 14x17 (the +8 accounts for his anchor)
this.pacman = this.add.sprite((14 * 16) + 8, (17 * 16) + 8, 'pacman', 0);
this.pacman.anchor.set(0.5);
//this.pacman.animations.add('munch', [0, 1, 2, 1], 20, true);
this.physics.arcade.enable(this.pacman);
this.pacman.body.setSize(16, 16, 0, 0);
this.cursors = this.input.keyboard.createCursorKeys();
//this.pacman.play('munch');
this.move(Phaser.LEFT);
this.scoreText = game.add.text(0, 500, 'Score: 0', { fontSize: '34px Arial', fill: 'white' });
lives = game.add.group();
game.add.text(game.world.width - 340, 500, 'Lives : ', { fontSize: '34px Arial', fill: 'white' });
this.bonusText = game.add.text(360, 500, 'Bonus: 0', { fontSize: '20px Arial', fill: 'white' });
for (var i = 0; i < 3; i++)
{
var pacman = lives.create(game.world.width - 235 + (30 * i), 517, 'pacman');
pacman.anchor.setTo(0.5, 0.5);
pacman.angle = 90;
pacman.alpha = 0.4;
}
},
//function fadePicture() {
//game.add.tween(picture).to( { alpha: 0 }, 2000, Phaser.Easing.Linear.None, true);
//},
checkKeys: function () {
if (this.cursors.left.isDown && this.current !== Phaser.LEFT)
{
this.checkDirection(Phaser.LEFT);
}
else if (this.cursors.right.isDown && this.current !== Phaser.RIGHT)
{
this.checkDirection(Phaser.RIGHT);
}
else if (this.cursors.up.isDown && this.current !== Phaser.UP)
{
this.checkDirection(Phaser.UP);
}
else if (this.cursors.down.isDown && this.current !== Phaser.DOWN)
{
this.checkDirection(Phaser.DOWN);
}
else
{
// This forces them to hold the key down to turn the corner
this.turning = Phaser.NONE;
}
},
checkDirection: function (turnTo) {
if (this.turning === turnTo || this.directions[turnTo] === null || this.directions[turnTo].index !== this.safetile)
{
// Invalid direction if they're already set to turn that way
// Or there is no tile there, or the tile isn't index 1 (a floor tile)
return;
}
// Check if they want to turn around and can
if (this.current === this.opposites[turnTo])
{
this.move(turnTo);
}
else
{
this.turning = turnTo;
this.turnPoint.x = (this.marker.x * this.gridsize) + (this.gridsize / 2);
this.turnPoint.y = (this.marker.y * this.gridsize) + (this.gridsize / 2);
}
},
turn: function () {
var cx = Math.floor(this.pacman.x);
var cy = Math.floor(this.pacman.y);
// This needs a threshold, because at high speeds you can't turn because the coordinates skip past
if (!this.math.fuzzyEqual(cx, this.turnPoint.x, this.threshold) || !this.math.fuzzyEqual(cy, this.turnPoint.y, this.threshold))
{
return false;
}
// Grid align before turning
this.pacman.x = this.turnPoint.x;
this.pacman.y = this.turnPoint.y;
this.pacman.body.reset(this.turnPoint.x, this.turnPoint.y);
this.move(this.turning);
this.turning = Phaser.NONE;
return true;
},
move: function (direction) {
var speed = this.speed;
if (direction === Phaser.LEFT || direction === Phaser.UP)
{
speed = -speed;
}
if (direction === Phaser.LEFT || direction === Phaser.RIGHT)
{
this.pacman.body.velocity.x = speed;
}
else
{
this.pacman.body.velocity.y = speed;
}
// Reset the scale and angle (Pacman is facing to the right in the sprite sheet)
/* this.pacman.scale.x = 1;
this.pacman.angle = 0;
if (direction === Phaser.LEFT)
{
this.pacman.scale.x = -1;
}
else if (direction === Phaser.UP)
{
this.pacman.angle = 270;
}
else if (direction === Phaser.DOWN)
{
this.pacman.angle = 90;
}
this.current = direction;
},*/
this.add.tween(this.pacman).to( { angle: this.getAngle(direction) }, this.turnSpeed, "Linear", true);
this.current = direction;
},
getAngle: function (to) {
// About-face?
if (this.current === this.opposites[to])
{
return "180";
}
if ((this.current === Phaser.UP && to === Phaser.LEFT) ||
(this.current === Phaser.DOWN && to === Phaser.RIGHT) ||
(this.current === Phaser.LEFT && to === Phaser.DOWN) ||
(this.current === Phaser.RIGHT && to === Phaser.UP))
{
return "-90";
}
return "90";
},
eatDot: function (pacman, dot) {
dot.kill();
var audio = new Audio('assets/pacman_chomp.wav');
audio.play()
this.score+=10;
this.scoreText.text= 'Score: ' + this.score;
//setTimeout(audio.play(),2000);
if (this.dots.total === 0)
{
this.dots.callAll('revive');
}
},
/*function muteAudio() {
var audio = document.getElementById('audioPlayer');
if (audio.mute = false) {
document.getElementById('audioPlayer').muted = true;
}
else {
audio.mute = true
document.getElementById('audioPlayer').muted = false;
}
}*/
eatCoin: function(pacman,coin){//pente
coin.kill();
this.score+=20;
this.scoreText.text= 'Score: ' + this.score;
var audio = new Audio('assets/pacman_eatfruit.wav');
audio.play()
if(this.coins.total===0)
{
this.coins.callAll('revive');
}
},
eatStr: function(pacman,str){//pente
str.kill();
this.bonus+=100;
this.bonusText.text= 'Bonus: ' + this.bonus;
var audio = new Audio('assets/pacman_eatfruit.wav');
audio.play()
if(this.strs.total===0)
{
this.strs.callAll('revive');
}
},
update: function () {
this.physics.arcade.collide(this.pacman, this.layer);
this.physics.arcade.overlap(this.pacman, this.dots, this.eatDot, null, this);
this.physics.arcade.overlap(this.pacman, this.dots, this.eatCoin, null, this);
this.physics.arcade.overlap(this.pacman, this.dots, this.eatStr, null, this);
this.marker.x = this.math.snapToFloor(Math.floor(this.pacman.x), this.gridsize) / this.gridsize;
this.marker.y = this.math.snapToFloor(Math.floor(this.pacman.y), this.gridsize) / this.gridsize;
// Update our grid sensors
this.directions[1] = this.map.getTileLeft(this.layer.index, this.marker.x, this.marker.y);
this.directions[2] = this.map.getTileRight(this.layer.index, this.marker.x, this.marker.y);
this.directions[3] = this.map.getTileAbove(this.layer.index, this.marker.x, this.marker.y);
this.directions[4] = this.map.getTileBelow(this.layer.index, this.marker.x, this.marker.y);
this.checkKeys();
if (this.turning !== Phaser.NONE)
{
this.turn();
}
}
};
game.state.add('Game', Pacman, true);
</script>
</body>
</html>
So, can anyone help me with making the str invisible after 10 seconds?
You were pretty close.
I'm going to use pacman as an example, since I'm not 100% sure how you were going to fade out the coins. When Pacman eats them?
First, you want the following fadePicture function:
fadePicture: function() {
game.add.tween(this.pacman).to( { alpha: 0 }, 2000, Phaser.Easing.Linear.None, true);
},
Note how that was changed from function fadePicture().
Next, in your create function you can refer to it:
this.game.time.events.add(Phaser.Timer.SECOND * 4, this.fadePicture, this);
That replaces the following:
//game.time.events.add(Phaser.Timer.SECOND * 4, fadePicture, this);
I've created a JSFiddle with the relevant changes.
If you do want your coins to fade then I would try updating fadePicture to accept a dot/str parameter and then game.add.tween on that.

How do I call a function which is within a plugin in Javascript, from ActionScript 3

I have a plugin in Javascript, and within this plugin there are many functions. What I want is to call the $.Repro.barraSonido function from ActionScript 3 code. The plugin is this:
(function ($) {
$.fn.Repro = function () {
var parametros = {
ejecucion: false,
lista: null,
audio: 0
};
var tposic = true;
$.Repro = function (opciones) {
$.ropc = $.extend({}, parametros, opciones);
var Metodos = {
Iniciar: function () {
$('#opc_player').attr('unselectable', 'on').css('user-select', 'none').on('selectstart', false);
$.Repro.barra();
$.Repro.volumen();
$.Repro.movPlaylist();
$('#btn_play').on('click', $.Repro.musc_play);
}
};
return Metodos;
};
$.Repro.musc_play = function () {
if (!swf('jrepro').ispausa()) $(this).removeClass('play').addClass('parar');
else $(this).removeClass('parar').addClass('play');
swf('jrepro').pausa();
return false;
};
$.Repro.autoplay = function () {
var e = $('.lista_musica').find('.selecc');
if (e.length == 0) return '';
$.ropc.lista = e.parent();
$('#T-tema').text(e.find('.artista').html());
$('#T-artista').text(e.find('.tema').html());
return new Array(s['s' + e.attr('name')], e.attr('aud'));
}
};
$.Repro.play = function (c) {
if ($.ropc.lista) {
var el = $.ropc.lista.find("li");
if (c != undefined) {
$.ropc.audio = c;
} else if ($('#btn_aleatorio').hasClass('aleatorioS') && el.length > 1) {
var sg = true;
while (sg) {
var rnd = Math.floor(Math.random() * el.length);
if (rnd != $.ropc.audio) sg = false;
}
$.ropc.audio = rnd;
} else if ($('#btn_repetir').hasClass('repetirS')) {
$.ropc.audio = $.ropc.audio;
} else $.ropc.audio = $.ropc.audio >= (el.length - 1) ? 0 : ($.ropc.audio + 1);
var eil = el.eq($.ropc.audio);
el.removeClass('selecc');
eil.addClass('selecc');
$('#T-tema').text(eil.find('.tema').html());
$('#T-artista').text(eil.find('.artista').html());
swf('jrepro').r(s['s' + eil.attr('name')], eil.attr('aud'));
if (swf('jrepro').ispausa()) $('#btn_play').removeClass('play').addClass('parar');
else $('#btn_play').removeClass('parar').addClass('play');
}
};
$.Repro.barraSonido = function (n, total, n2, total2) {
$.Repro.cargaSonido(n2, total2);
if (n <= total) {
var i_tiempo = (n / 1000);
var m = Math.floor(i_tiempo / 60),
s = Math.ceil(i_tiempo % 60);
$("#tinicial").html((m > 9 ? m : 0 + '' + m) + ':' + (s > 9 ? s : 0 + '' + s));
var t_total = (total / 1000),
fm = Math.floor(t_total / 60),
fs = Math.ceil(t_total % 60);
$("#tfinal").html((fm > 9 ? fm : 0 + '' + fm) + ':' + (fs > 9 ? fs : 0 + '' + fs));
if (total > 0 && tposic) {
var pos = Math.round((Math.round(n) * $('#precarga').width()) / (total));
$('.bar_pr').css('width', pos + 'px');
$('#player_puntero').css('left', pos + 'px');
}
}
};
$.Repro.cargaSonido = function (n, total) {
if (total > 0 && $('#precarga').width() < 290) {
var posCarg = Math.round((n * 290) / total);
$('#precarga').css({width: posCarg}, 500);
}
};
$.Repro.barra = function () {
$('.bar_fon').slider({
max: 100,
range: "min",
slide: function (a, c) {
tposic = false;
$('.bar_pr').css('width', c.value + '%');
},
stop: function (a, c) {
swf('jrepro').tie(parseInt($('#player_puntero').css('left')), $('#precarga').width());
tposic = true;
}
});
};
$.Repro.movPlaylist = function () {};
return $.Repro;
}();
})(jQuery);
It doesn't work, and I put the following in the SWF file:
import flash.external.ExternalInterface;
function call_javascript(evt:MouseEvent):void {
ExternalInterface.call("$.Reproductor.barraSonido");//Even with "()"
}
js_btn.addEventListener(MouseEvent.MOUSE_UP, call_javascript);
For testing purposes, in the function $.Reproductor.barraSonido, I added alert("hola");.
The HTML file is:
<script type="text/javascript">
//Here is the plugin
</script>
<object width="300" height="150">
<param name="movie" value="player.swf">
<embed src="player.swf" width="300" height="150">
</embed>
</object>
You can use AS3's External Interface class to communicate with Javascript (both to and from). You can read more about External Interface here:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html
For your needs, something such as:
if(ExternalInterface.available) ExternalInterface.call('$.Repro. barraSonido', ...arguments);
will call the function. You'll need to replace the ...arguments in the above example with the parameters you'd like to pass to the barraSonido function.

JQuery SVG making objects droppable

I am trying to build a seating reservation web app using SVG. Imagine, I've created rectangles in the svg, which represents an empty seat. I want to allow user to drop an html "image" element on the "rect" to reserve the seat.
However, I couldn't get the droppable to work on the SVG elemnets. Any one has any idea why this is so? Here is the code:
$('#target').svg();
var svg = $("#target").svg('get');
svg.rect(20, 10, 100, 50, 10, 10, { fill: '#666', class: "droppable" });
$('rect')
.droppable({
accept: '.product',
tolerance: 'touch',
drop: function (event, ui) {
alert('df');
}
}
I looked in to the jQuery-ui source and figured out why it wasn't working with SVGs. jQuery thinks they have a width and height of 0px, so the intersection test fails.
I wrapped $.ui.intersect and set the correct size information before passing the arguments through to the original function. There may be more proportion objects that need fixing but the two I did here are enough to fix my :
$.ui.intersect_o = $.ui.intersect;
$.ui.intersect = function(draggable, droppable, toleranceMode) {
//Fix helper
if (draggable.helperProportions && draggable.helperProportions.width === 0 && draggable.helperProportions.height === 0) {
draggable.helperProportionsBBox = draggable.helperProportionsBBox || $(draggable.element).get(0).getBBox();
draggable.helperProportions = draggable.helperProportionsBBox;
}
//Fix droppable
if (droppable.proportions && droppable.proportions.width === 0 && droppable.proportions.height === 0) {
droppable.proportionsBBox = droppable.proportionsBBox || $(droppable.element).get(0).getBBox();
droppable.proportions = droppable.proportionsBBox;
}
return $.ui.intersect_o(draggable, droppable, toleranceMode);
};
With jQuery UI 1.11.4 I had to change Eddie's solution to the following, as draggable.proportions is now a function:
$.ui.intersect_o = $.ui.intersect;
$.ui.intersect = function (draggable, droppable, toleranceMode, event) {
//Fix helper
if (draggable.helperProportions && draggable.helperProportions.width === 0 && draggable.helperProportions.height === 0) {
draggable.helperProportionsBBox = draggable.helperProportionsBBox || $(draggable.element).get(0).getBBox();
draggable.helperProportions = draggable.helperProportionsBBox;
}
if (droppable.proportions && !droppable.proportions().width && !droppable.proportions().height)
if (typeof $(droppable.element).get(0).getBBox === "function") {
droppable.proportionsBBox = droppable.proportionsBBox || $(droppable.element).get(0).getBBox();
droppable.proportions = function () {
return droppable.proportionsBBox;
};
}
return $.ui.intersect_o(draggable, droppable, toleranceMode, event);
};
If you want to restrict the drop on svg elements to hit on visible content only (for example in polygons) you might want to use this addition to Peter Baumann's suggestion:
$.ui.intersect_o = $.ui.intersect;
$.ui.intersect = function (draggable, droppable, toleranceMode, event) {
//Fix helper
if (draggable.helperProportions && draggable.helperProportions.width === 0 && draggable.helperProportions.height === 0) {
draggable.helperProportionsBBox = draggable.helperProportionsBBox || $(draggable.element).get(0).getBBox();
draggable.helperProportions = draggable.helperProportionsBBox;
}
if (droppable.proportions && !droppable.proportions().width && !droppable.proportions().height)
if (typeof $(droppable.element).get(0).getBBox === "function") {
droppable.proportionsBBox = droppable.proportionsBBox || $(droppable.element).get(0).getBBox();
droppable.proportions = function () {
return droppable.proportionsBBox;
};
}
var intersect = $.ui.intersect_o(draggable, droppable, toleranceMode, event);
if (intersect) {
var dropTarget = $(droppable.element).get(0);
if (dropTarget.ownerSVGElement && (typeof (dropTarget.isPointInFill) === 'function') && (typeof (dropTarget.isPointInStroke) === 'function')) {
var x = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left + draggable.helperProportions.width / 2,
y = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top + draggable.helperProportions.height / 2,
p = dropTarget.ownerSVGElement.createSVGPoint();
p.x = x;
p.y = y;
p = p.matrixTransform(dropTarget.getScreenCTM().inverse());
if(!(dropTarget.isPointInFill(p) || dropTarget.isPointInStroke(p)))
intersect = false;
}
}
return intersect;
};
In case if anyone has the same question in mind, droppable doesn't work in jquery SVG. So in the end, I did the following to create my own droppable event:
In draggable, set the target currently dragged been dragged to draggedObj ,
In the mouse up event, check if the draggedObj is null, if it's not null, then drop the item according to the current position. ( let me know if you need help on detecting the current position)

jquery html chrome developer tools timeline, jquery firing for every mousemove event?

jQuery is firing on every mousemove event for me.
How do I get it to stop doing that?
It seems like jQuery 1.2.6 do not have this behavior, but 1.4 and 1.5 does.
Stackoverflow.com does the same thing. Wonder what changed.
The jQuery event code:
/*
* A number of helper functions used for managing events.
* Many of the ideas behind this code originated from
* Dean Edwards' addEvent library.
*/
jQuery.event = {
// Bind an event to an element
// Original by Dean Edwards
add: function( elem, types, handler, data ) {
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
return;
}
// TODO :: Use a try/catch until it's safe to pull this out (likely 1.6)
// Minor release fix for bug #8018
try {
// For whatever reason, IE has trouble passing the window object
// around, causing it to be cloned in the process
if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
elem = window;
}
}
catch ( e ) {}
if ( handler === false ) {
handler = returnFalse;
} else if ( !handler ) {
// Fixes bug #7229. Fix recommended by jdalton
return;
}
var handleObjIn, handleObj;
if ( handler.handler ) {
handleObjIn = handler;
handler = handleObjIn.handler;
}
// Make sure that the function being executed has a unique ID
if ( !handler.guid ) {
handler.guid = jQuery.guid++;
}
// Init the element's event structure
var elemData = jQuery._data( elem );
// If no elemData is found then we must be trying to bind to one of the
// banned noData elements
if ( !elemData ) {
return;
}
var events = elemData.events,
eventHandle = elemData.handle;
if ( !events ) {
elemData.events = events = {};
}
if ( !eventHandle ) {
elemData.handle = eventHandle = function( e ) {
// Handle the second event of a trigger and when
// an event is called after a page has unloaded
return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
jQuery.event.handle.apply( eventHandle.elem, arguments ) :
undefined;
};
}
// Add elem as a property of the handle function
// This is to prevent a memory leak with non-native events in IE.
eventHandle.elem = elem;
// Handle multiple events separated by a space
// jQuery(...).bind("mouseover mouseout", fn);
types = types.split(" ");
var type, i = 0, namespaces;
while ( (type = types[ i++ ]) ) {
handleObj = handleObjIn ?
jQuery.extend({}, handleObjIn) :
{ handler: handler, data: data };
// Namespaced event handlers
if ( type.indexOf(".") > -1 ) {
namespaces = type.split(".");
type = namespaces.shift();
handleObj.namespace = namespaces.slice(0).sort().join(".");
} else {
namespaces = [];
handleObj.namespace = "";
}
handleObj.type = type;
if ( !handleObj.guid ) {
handleObj.guid = handler.guid;
}
// Get the current list of functions bound to this event
var handlers = events[ type ],
special = jQuery.event.special[ type ] || {};
// Init the event handler queue
if ( !handlers ) {
handlers = events[ type ] = [];
// Check for a special event handler
// Only use addEventListener/attachEvent if the special
// events handler returns false
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
// Bind the global event handler to the element
if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle, false );
} else if ( elem.attachEvent ) {
elem.attachEvent( "on" + type, eventHandle );
}
}
}
if ( special.add ) {
special.add.call( elem, handleObj );
if ( !handleObj.handler.guid ) {
handleObj.handler.guid = handler.guid;
}
}
// Add the function to the element's handler list
handlers.push( handleObj );
// Keep track of which events have been used, for global triggering
jQuery.event.global[ type ] = true;
}
// Nullify elem to prevent memory leaks in IE
elem = null;
},
global: {},
// Detach an event or set of events from an element
remove: function( elem, types, handler, pos ) {
// don't do events on text and comment nodes
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
return;
}
if ( handler === false ) {
handler = returnFalse;
}
var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
events = elemData && elemData.events;
if ( !elemData || !events ) {
return;
}
// types is actually an event object here
if ( types && types.type ) {
handler = types.handler;
types = types.type;
}
// Unbind all events for the element
if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
types = types || "";
for ( type in events ) {
jQuery.event.remove( elem, type + types );
}
return;
}
// Handle multiple events separated by a space
// jQuery(...).unbind("mouseover mouseout", fn);
types = types.split(" ");
while ( (type = types[ i++ ]) ) {
origType = type;
handleObj = null;
all = type.indexOf(".") < 0;
namespaces = [];
if ( !all ) {
// Namespaced event handlers
namespaces = type.split(".");
type = namespaces.shift();
namespace = new RegExp("(^|\\.)" +
jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
}
eventType = events[ type ];
if ( !eventType ) {
continue;
}
if ( !handler ) {
for ( j = 0; j < eventType.length; j++ ) {
handleObj = eventType[ j ];
if ( all || namespace.test( handleObj.namespace ) ) {
jQuery.event.remove( elem, origType, handleObj.handler, j );
eventType.splice( j--, 1 );
}
}
continue;
}
special = jQuery.event.special[ type ] || {};
for ( j = pos || 0; j < eventType.length; j++ ) {
handleObj = eventType[ j ];
if ( handler.guid === handleObj.guid ) {
// remove the given handler for the given type
if ( all || namespace.test( handleObj.namespace ) ) {
if ( pos == null ) {
eventType.splice( j--, 1 );
}
if ( special.remove ) {
special.remove.call( elem, handleObj );
}
}
if ( pos != null ) {
break;
}
}
}
// remove generic event handler if no more handlers exist
if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
jQuery.removeEvent( elem, type, elemData.handle );
}
ret = null;
delete events[ type ];
}
}
// Remove the expando if it's no longer used
if ( jQuery.isEmptyObject( events ) ) {
var handle = elemData.handle;
if ( handle ) {
handle.elem = null;
}
delete elemData.events;
delete elemData.handle;
if ( jQuery.isEmptyObject( elemData ) ) {
jQuery.removeData( elem, undefined, true );
}
}
},
// bubbling is internal
trigger: function( event, data, elem /*, bubbling */ ) {
// Event object or event type
var type = event.type || event,
bubbling = arguments[3];
if ( !bubbling ) {
event = typeof event === "object" ?
// jQuery.Event object
event[ jQuery.expando ] ? event :
// Object literal
jQuery.extend( jQuery.Event(type), event ) :
// Just the event type (string)
jQuery.Event(type);
if ( type.indexOf("!") >= 0 ) {
event.type = type = type.slice(0, -1);
event.exclusive = true;
}
// Handle a global trigger
if ( !elem ) {
// Don't bubble custom events when global (to avoid too much overhead)
event.stopPropagation();
// Only trigger if we've ever bound an event for it
if ( jQuery.event.global[ type ] ) {
// XXX This code smells terrible. event.js should not be directly
// inspecting the data cache
jQuery.each( jQuery.cache, function() {
// internalKey variable is just used to make it easier to find
// and potentially change this stuff later; currently it just
// points to jQuery.expando
var internalKey = jQuery.expando,
internalCache = this[ internalKey ];
if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
jQuery.event.trigger( event, data, internalCache.handle.elem );
}
});
}
}
// Handle triggering a single element
// don't do events on text and comment nodes
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
return undefined;
}
// Clean up in case it is reused
event.result = undefined;
event.target = elem;
// Clone the incoming data, if any
data = jQuery.makeArray( data );
data.unshift( event );
}
event.currentTarget = elem;
// Trigger the event, it is assumed that "handle" is a function
var handle = jQuery._data( elem, "handle" );
if ( handle ) {
handle.apply( elem, data );
}
var parent = elem.parentNode || elem.ownerDocument;
// Trigger an inline bound script
try {
if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
event.result = false;
event.preventDefault();
}
}
// prevent IE from throwing an error for some elements with some event types, see #3533
} catch (inlineError) {}
if ( !event.isPropagationStopped() && parent ) {
jQuery.event.trigger( event, data, parent, true );
} else if ( !event.isDefaultPrevented() ) {
var old,
target = event.target,
targetType = type.replace( rnamespaces, "" ),
isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
special = jQuery.event.special[ targetType ] || {};
if ( (!special._default || special._default.call( elem, event ) === false) &&
!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
try {
if ( target[ targetType ] ) {
// Make sure that we don't accidentally re-trigger the onFOO events
old = target[ "on" + targetType ];
if ( old ) {
target[ "on" + targetType ] = null;
}
jQuery.event.triggered = event.type;
target[ targetType ]();
}
// prevent IE from throwing an error for some elements with some event types, see #3533
} catch (triggerError) {}
if ( old ) {
target[ "on" + targetType ] = old;
}
jQuery.event.triggered = undefined;
}
}
},
handle: function( event ) {
var all, handlers, namespaces, namespace_re, events,
namespace_sort = [],
args = jQuery.makeArray( arguments );
event = args[0] = jQuery.event.fix( event || window.event );
event.currentTarget = this;
// Namespaced event handlers
all = event.type.indexOf(".") < 0 && !event.exclusive;
if ( !all ) {
namespaces = event.type.split(".");
event.type = namespaces.shift();
namespace_sort = namespaces.slice(0).sort();
namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
}
event.namespace = event.namespace || namespace_sort.join(".");
events = jQuery._data(this, "events");
handlers = (events || {})[ event.type ];
if ( events && handlers ) {
// Clone the handlers to prevent manipulation
handlers = handlers.slice(0);
for ( var j = 0, l = handlers.length; j < l; j++ ) {
var handleObj = handlers[ j ];
// Filter the functions by class
if ( all || namespace_re.test( handleObj.namespace ) ) {
// Pass in a reference to the handler function itself
// So that we can later remove it
event.handler = handleObj.handler;
event.data = handleObj.data;
event.handleObj = handleObj;
var ret = handleObj.handler.apply( this, args );
if ( ret !== undefined ) {
event.result = ret;
if ( ret === false ) {
event.preventDefault();
event.stopPropagation();
}
}
if ( event.isImmediatePropagationStopped() ) {
break;
}
}
}
}
return event.result;
},
props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix: function( event ) {
if ( event[ jQuery.expando ] ) {
return event;
}
// store a copy of the original event object
// and "clone" to set read-only properties
var originalEvent = event;
event = jQuery.Event( originalEvent );
for ( var i = this.props.length, prop; i; ) {
prop = this.props[ --i ];
event[ prop ] = originalEvent[ prop ];
}
// Fix target property, if necessary
if ( !event.target ) {
// Fixes #1925 where srcElement might not be defined either
event.target = event.srcElement || document;
}
// check if target is a textnode (safari)
if ( event.target.nodeType === 3 ) {
event.target = event.target.parentNode;
}
// Add relatedTarget, if necessary
if ( !event.relatedTarget && event.fromElement ) {
event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
}
// Calculate pageX/Y if missing and clientX/Y available
if ( event.pageX == null && event.clientX != null ) {
var doc = document.documentElement,
body = document.body;
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
}
// Add which for key events
if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
event.which = event.charCode != null ? event.charCode : event.keyCode;
}
// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
if ( !event.metaKey && event.ctrlKey ) {
event.metaKey = event.ctrlKey;
}
// Add which for click: 1 === left; 2 === middle; 3 === right
// Note: button is not normalized, so don't use it
if ( !event.which && event.button !== undefined ) {
event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
}
return event;
},
// Deprecated, use jQuery.guid instead
guid: 1E8,
// Deprecated, use jQuery.proxy instead
proxy: jQuery.proxy,
special: {
ready: {
// Make sure the ready event is setup
setup: jQuery.bindReady,
teardown: jQuery.noop
},
live: {
add: function( handleObj ) {
jQuery.event.add( this,
liveConvert( handleObj.origType, handleObj.selector ),
jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
},
remove: function( handleObj ) {
jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
}
},
beforeunload: {
setup: function( data, namespaces, eventHandle ) {
// We only want to do this special case on windows
if ( jQuery.isWindow( this ) ) {
this.onbeforeunload = eventHandle;
}
},
teardown: function( namespaces, eventHandle ) {
if ( this.onbeforeunload === eventHandle ) {
this.onbeforeunload = null;
}
}
}
}
};
To clarify, I don't like this behavior. I think it's unnecessary, especially if I never intend to use mousemove in the first place.
This kind of thing matters in some situations.
In the developer tools, go to the Sources tab, then on the right open up Event Listener Breakpoints from the accordion menu. Make sure nothing is selected. I had this problem because somehow mouse/click events were selected, so it was stopping there every time.
This is not an intrinsic part of jQuery's event handling code, but instead only occurs on some sites.
Presumably those sites are using some specific feature that ends up listening to all mouse moves, e.g. on the document object or the <body /> or the like. A good candidate for what could cause this would be the (mis)use of .live(); in general .delegate() is preferable, but sometimes .live() is unavoidable.
Regardless, whichever feature it is that causes this, StackOverflow et al. are willing to accept this cost. As you build up your own site, you can periodically check the Developer Tools timeline, and if this kind of behavior appears, you can make your own decision on cost/benefit.