mozilla中独有的读写器(definegetter、definesetter)以及可以给element,event等加上prototype原型,使得在ie里用的方法同样在mozilla中可以适用,下面贴出常用的一些代码
例如
obj.insertadjacenthtml, currentstyle, obj.attachevent, obj.detachevent等等。
版权属于erik arvidsson, webfx
复制代码 代码如下:
if (browser.ismozilla) { // set up ie environment for moz
extendeventobject();
emulateattachevent();
emulateeventhandlers([click, dblclick, mouseover, mouseout,
mousedown, mouseup, mousemove,
keydown, keypress, keyup]);
emulatecurrentstyle();
/*emulatedocumentall();
emulateelement()
*/
// it is better to use a constant for event.button
event.left = 0;
event.middle = 1;
event.right = 2;
}
else {
event = {};
// ie is returning wrong button number
event.left = 1;
event.middle = 4;
event.right = 2;
}
/*
* extends the event object with srcelement, cancelbubble, returnvalue,
* fromelement and toelement
*/
function extendeventobject() {
event.prototype.__definesetter__(returnvalue, function (b) {
if (!b) this.preventdefault();
return b;
});
event.prototype.__definesetter__(cancelbubble, function (b) {
if (b) this.stoppropagation();
return b;
});
event.prototype.__definegetter__(srcelement, function () {
var node = this.target;
while (node.nodetype != 1) node = node.parentnode;
return node;
});
event.prototype.__definegetter__(fromelement, function () {
var node;
if (this.type == mouseover)
node = this.relatedtarget;
else if (this.type == mouseout)
node = this.target;
if (!node) return;
while (node.nodetype != 1) node = node.parentnode;
return node;
});
event.prototype.__definegetter__(toelement, function () {
var node;
if (this.type == mouseout)
node = this.relatedtarget;
else if (this.type == mouseover)
node = this.target;
if (!node) return;
while (node.nodetype != 1) node = node.parentnode;
return node;
});
event.prototype.__definegetter__(offsetx, function () {
return this.layerx;
});
event.prototype.__definegetter__(offsety, function () {
return this.layery;
});
}
/*
* emulates element.attachevent as well as detachevent
*/
function emulateattachevent() {
htmldocument.prototype.attachevent =
htmlelement.prototype.attachevent = function (stype, fhandler) {
var shorttypename = stype.replace(/on/, );
fhandler._ieemueventhandler = function (e) {
window.event = e;
return fhandler();
};
this.addeventlistener(shorttypename, fhandler._ieemueventhandler, false);
};
htmldocument.prototype.detachevent =
htmlelement.prototype.detachevent = function (stype, fhandler) {
var shorttypename = stype.replace(/on/, );
if (typeof fhandler._ieemueventhandler == function)
this.removeeventlistener(shorttypename, fhandler._ieemueventhandler, false);
else
this.removeeventlistener(shorttypename, fhandler, true);
};
}
/*
* this function binds the event object passed along in an
* event to window.event
*/
function emulateeventhandlers(eventnames) {
for (var i = 0; i document.addeventlistener(eventnames[i], function (e) {
window.event = e;
}, true); // using capture
}
}
/*
* simple emulation of document.all
* this one is far from complete. be cautious
*/
function emulateallmodel() {
var allgetter = function () {
var a = this.getelementsbytagname(*);
var node = this;
a.tags = function (stagname) {
return node.getelementsbytagname(stagname);
};
return a;
};
htmldocument.prototype.__definegetter__(all, allgetter);
htmlelement.prototype.__definegetter__(all, allgetter);
}
function extendelementmodel() {
htmlelement.prototype.__definegetter__(parentelement, function () {
if (this.parentnode == this.ownerdocument) return null;
return this.parentnode;
});
htmlelement.prototype.__definegetter__(children, function () {
var tmp = [];
var j = 0;
var n;
for (var i = 0; i n = this.childnodes[i];
if (n.nodetype == 1) {
tmp[j++] = n;
if (n.name) { // named children
if (!tmp[n.name])
tmp[n.name] = [];
tmp[n.name][tmp[n.name].length] = n;
}
if (n.id) // child with id
tmp[n.id] = n
}
}
return tmp;
});
htmlelement.prototype.contains = function (oel) {
if (oel == this) return true;
if (oel == null) return false;
return this.contains(oel.parentnode);
};
}
function emulatecurrentstyle() {
htmlelement.prototype.__definegetter__(currentstyle, function () {
return this.ownerdocument.defaultview.getcomputedstyle(this, null);
/*
var cs = {};
var el = this;
for (var i = 0; i cs.__definegetter__(properties[i], encapsulateobjects(el, properties[i]));
}
return cs;
*/
});
}
function emulatehtmlmodel() {
// this function is used to generate a html string for the text properties/methods
// it replaces '\n' with
as well as fixes consecutive white spaces
// it also repalaces some special characters
function converttexttohtml(s) {
s = s.replace(/\&/g, &).replace(/, /g, >).replace(/\n/g,
);
while (/\s\s/.test(s))
s = s.replace(/\s\s/, );
return s.replace(/\s/g, );
}
htmlelement.prototype.insertadjacenthtml = function (swhere, shtml) {
var df; // : documentfragment
var r = this.ownerdocument.createrange();
switch (string(swhere).tolowercase()) {
case beforebegin:
r.setstartbefore(this);
df = r.createcontextualfragment(shtml);
this.parentnode.insertbefore(df, this);
break;
case afterbegin:
r.selectnodecontents(this);
r.collapse(true);
df = r.createcontextualfragment(shtml);
this.insertbefore(df, this.firstchild);
break;
case beforeend:
r.selectnodecontents(this);
r.collapse(false);
df = r.createcontextualfragment(shtml);
this.appendchild(df);
break;
case afterend:
r.setstartafter(this);
df = r.createcontextualfragment(shtml);
this.parentnode.insertbefore(df, this.nextsibling);
break;
}
};
htmlelement.prototype.__definesetter__(outerhtml, function (shtml) {
var r = this.ownerdocument.createrange();
r.setstartbefore(this);
var df = r.createcontextualfragment(shtml);
this.parentnode.replacechild(df, this);
return shtml;
});
htmlelement.prototype.__definegetter__(canhavechildren, function () {
switch (this.tagname) {
case area:
case base:
case basefont:
case col:
case frame:
case hr:
case img:
case br:
case input:
case isindex:
case link:
case meta:
case param:
return false;
}
return true;
});
htmlelement.prototype.__definegetter__(outerhtml, function () {
var attr, attrs = this.attributes;
var str = for (var i = 0; i attr = attrs[i];
if (attr.specified)
str += + attr.name + '=' + attr.value + '';
}
if (!this.canhavechildren)
return str + >;
return str + > + this.innerhtml + + this.tagname + >;
});
htmlelement.prototype.__definesetter__(innertext, function (stext) {
this.innerhtml = converttexttohtml(stext);
return stext;
});
var tmpget;
htmlelement.prototype.__definegetter__(innertext, tmpget = function () {
var r = this.ownerdocument.createrange();
r.selectnodecontents(this);
return r.tostring();
});
htmlelement.prototype.__definesetter__(outertext, function (stext) {
this.outerhtml = converttexttohtml(stext);
return stext;
});
htmlelement.prototype.__definegetter__(outertext, tmpget);
htmlelement.prototype.insertadjacenttext = function (swhere, stext) {
this.insertadjacenthtml(swhere, converttexttohtml(stext));
};
}