zepto
zepto copied to clipboard
the event data assert has a bug on Chrome 60+
Uncaught TypeError: Cannot assign to read only property 'data' of object '#<InputEvent>'
the bug this if you delegate event , with bind data
object
div#a
div#b: input(delegate)
then will throw the error on Chrome
Could you please provide a full example and point out where it fails and what the expected result is? Ideally use something like https://codepen.io. Thanks!
@madrobby difference data https://jsfiddle.net/CloudyWolf/4s31thg3/
Hey, I'm running into a similar issue here. When using Zepto with jqueryMask plugin in mobile (Android/Chrome 60), I'm getting the same error message. I figured out that Zepto try to set an undefined
data to a read-only prop from an #<InputEvent>
type. The problem is occurring in this block of code:
https://github.com/madrobby/zepto/blob/master/src/event.js#L68
Wrapping this line with try-catch
I could get things working, but it does not solves the problem.
try{
e.data = data;
}
catch(error) {
console.log(error);
}
`function fixEvent(e) {
const Event = function(src){
// Event object
if ( src && src.type ) {
this.originalEvent = src;
this.type = src.type;
// Events bubbling up the document may have been marked as prevented
// by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = src.defaultPrevented ||
src.defaultPrevented === undefined &&
src.returnValue === false ?
returnTrue :
returnFalse;
this.target = ( src.target && src.target.nodeType === 3 ) ?
src.target.parentNode :
src.target;
this.currentTarget = src.currentTarget;
this.relatedTarget = src.relatedTarget;
// Event type
} else {
this.type = src;
}
this.timeStamp = src && src.timeStamp || Date.now();
};
Event.prototype = {
constructor: $.Event,
isDefaultPrevented: returnFalse,
isPropagationStopped: returnFalse,
isImmediatePropagationStopped: returnFalse,
isSimulated: false,
preventDefault: function() {
var e = this.originalEvent;
this.isDefaultPrevented = returnTrue;
if ( e && !this.isSimulated ) {
e.preventDefault();
}
},
stopPropagation: function() {
var e = this.originalEvent;
this.isPropagationStopped = returnTrue;
if ( e && !this.isSimulated ) {
e.stopPropagation();
}
},
stopImmediatePropagation: function() {
var e = this.originalEvent;
this.isImmediatePropagationStopped = returnTrue;
if ( e && !this.isSimulated ) {
e.stopImmediatePropagation();
}
this.stopPropagation();
}
};
//each and addProp
function addProp( name, hook) {
Object.defineProperty(Event.prototype, name, {
enumerable: true,
configurable: true,
get: isFunction( hook ) ?
function() {
if ( this.originalEvent ) {
return hook( this.originalEvent );
}
} :
function() {
if ( this.originalEvent ) {
return this.originalEvent[ name ];
}
},
set: function( value ) {
Object.defineProperty( this, name, {
enumerable: true,
configurable: true,
writable: true,
value: value
} );
}
} );
};
$.each({
altKey: true,
bubbles: true,
cancelable: true,
changedTouches: true,
ctrlKey: true,
detail: true,
eventPhase: true,
metaKey: true,
pageX: true,
pageY: true,
shiftKey: true,
view: true,
"char": true,
charCode: true,
key: true,
keyCode: true,
button: true,
buttons: true,
clientX: true,
clientY: true,
offsetX: true,
offsetY: true,
pointerId: true,
pointerType: true,
screenX: true,
screenY: true,
targetTouches: true,
toElement: true,
touches: true,
which: function( event ) {
var button = event.button;
// Add which for key events
if ( event.which == null && rkeyEvent.test( event.type ) ) {
return event.charCode != null ? event.charCode : event.keyCode;
}
if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
if ( button & 1 ) {
return 1;
}
if ( button & 2 ) {
return 3;
}
if ( button & 4 ) {
return 2;
}
return 0;
}
return event.which;
}
}, addProp);
return new Event(e);
}
function returnTrue() {
return true;
}
function returnFalse() {
return false;
}
// ... e = fixEvent(e); // ... `