Below are the diffs from Visual.js which include four new functions
for sliding elements on/off to the left/right and two for sliding
pairs of elements together, one on and one off, and one for sliding
pairs of elements in a direction relative to their position in the
DOM.
The diffs also include the changes I discussed in my previous post
about issues with slideDown and blindDown.
I have tested these on divs whose width are 100% of the browser window
on both Firefox 3rc2 and Safari 3.1.1. I have not tested with any
variation of IE. I also have not tested with divs with a smaller than
100% width though there's nothing to suggest it won't work right.
Index: Visual.js
===================================================================
--- Visual.js (revision 1383)
+++ Visual.js (working copy)
@@ -1431,14 +1431,16 @@
scaleContent: false,
scaleX: false,
scaleFrom: 0,
- scaleMode: {originalHeight: s.getElementHeight(element),
- originalWidth: s.getElementWidth(element)},
restoreAfterFinish: true,
- afterSetupInternal: function (effect) {
+ beforeSetupInternal: function (effect) {
elemClip = d.makeClipping(effect.element);
- s.setStyle(effect.element, {height: '0px'});
s.showElement(effect.element);
+ effect.options.scaleMode = {originalHeight:
s.getElementHeight(element),
+ originalWidth: s.getElementWidth(element)};
},
+ afterSetupInternal: function (effect) {
+ s.setStyle(effect.element, {height: '0px'});
+ },
afterFinishInternal: function (effect) {
d.undoClipping(effect.element, elemClip);
}
@@ -1582,18 +1584,20 @@
scaleContent: false,
scaleX: false,
scaleFrom: 0,
- scaleMode: {originalHeight: s.getElementHeight(element),
- originalWidth: s.getElementWidth(element)},
restoreAfterFinish: true,
+ beforeSetupInternal: function (effect) {
+ elemClip = d.makeClipping(effect.element);
+ s.showElement(effect.element);
+ scaleMode = {originalHeight: s.getElementHeight(element),
+ originalWidth: s.getElementWidth(element)};
+ },
afterSetupInternal: function (effect) {
d.makePositioned(effect.element);
d.makePositioned(effect.element.firstChild);
if (/Opera/.test(navigator.userAgent)) {
s.setStyle(effect.element, {top: ''});
}
- elemClip = d.makeClipping(effect.element);
s.setStyle(effect.element, {height: '0px'});
- s.showElement(effect.element);
},
afterUpdateInternal: function (effect) {
s.setStyle(effect.element.firstChild,
@@ -1665,7 +1669,450 @@
}, options);
return new MochiKit.Visual.Scale(element, 0, options);
};
+/** @id MochiKit.Visual.slideOnLeft */
+MochiKit.Visual.slideOnLeft = function (element, /* optional */
options) {
+ /***
+ Slide an element on moving from right to left.
+ It must have a single inner child to work correctly
+
+ ***/
+ if (!element.hasChildNodes()) {
+ throw "MochiKit.Visual.slideOnLeft must be used on a element
with a child";
+ }
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ var elemClip;
+ element = d.getElement(element);
+ d.removeEmptyTextNodes(element);
+
+ /* don't want s.getElementWidth/Height, want the raw values for
full restore */
+ var originalStyle = {
+ height: element.style.height,
+ width: element.style.width,
+ left: element.style.left,
+ innerWidth: element.firstChild.style.width
+ };
+
+ options = b.update({
+ scaleContent: false,
+ scaleY: false,
+ scaleFrom: 0,
+ restoreAfterFinish: true,
+ beforeSetupInternal: function (effect) {
+ elemClip = d.makeClipping(effect.element);
+ s.showElement(effect.element);
+ scaleMode = {
+ originalHeight: s.getElementHeight(effect.element),
+ originalWidth: s.getElementWidth(effect.element)
+ };
+ },
+ afterSetupInternal: function (effect) {
+ s.setStyle(effect.element, {
+ width: '0px',
+ left: effect.dims[1]
+ });
+ s.setStyle(effect.element.firstChild, {
+ width: scaleMode.originalWidth
+ });
+ d.makePositioned(effect.element);
+ d.makePositioned(effect.element.firstChild);
+ if (/Opera/.test(navigator.userAgent)) {
+ s.setStyle(effect.element, {left: ''});
+ }
+ },
+ afterUpdateInternal: function (effect) {
+ s.setStyle(effect.element, {
+ left: (effect.dims[1] -
s.getElementWidth(effect.element)) + 'px'
+ });
+ },
+ afterFinishInternal: function (effect) {
+ d.undoClipping(effect.element, elemClip);
+ // IE will crash if child is undoPositioned first
+ if (/MSIE/.test(navigator.userAgent)) {
+ d.undoPositioned(effect.element);
+ d.undoPositioned(effect.element.firstChild);
+ } else {
+ d.undoPositioned(effect.element.firstChild);
+ d.undoPositioned(effect.element);
+ }
+ s.setStyle(effect.element, {
+ height: originalStyle.height,
+ width: originalStyle.width,
+ left: originalStyle.left
+ });
+ s.setStyle(effect.element.firstChild, {
+ width: originalStyle.innerWidth
+ });
+ }
+ }, options);
+
+ return new MochiKit.Visual.Scale(element, 100, options);
+}
+
+/** @id MochiKit.Visual.slideOnRight */
+MochiKit.Visual.slideOnRight = function (element, /* optional */
options) {
+ /***
+
+ Slide an element on moving from left to right.
+ It must have a single inner child to work correctly
+
+ ***/
+ if (!element.hasChildNodes()) {
+ throw "MochiKit.Visual.slideOnRight must be used on a element
with a child";
+ }
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ var elemClip;
+ element = d.getElement(element);
+ d.removeEmptyTextNodes(element);
+
+ /* don't want s.getElementWidth/Height, want the raw values for
full restore */
+ var originalStyle = {
+ height: element.style.height,
+ width: element.style.width,
+ innerRight: element.firstChild.style.right,
+ innerWidth: element.firstChild.style.width
+ };
+
+ options = b.update({
+ scaleContent: false,
+ scaleY: false,
+ scaleFrom: 0,
+ restoreAfterFinish: true,
+ beforeSetupInternal: function (effect) {
+ elemClip = d.makeClipping(effect.element);
+ s.showElement(effect.element);
+ scaleMode = {
+ originalHeight: s.getElementHeight(effect.element),
+ originalWidth: s.getElementWidth(effect.element)
+ };
+ },
+ afterSetupInternal: function (effect) {
+ s.setStyle(effect.element, {width: '0px'});
+ s.setStyle(effect.element.firstChild, {
+ width: scaleMode.originalWidth,
+ right: effect.dims[1]
+ });
+ d.makePositioned(effect.element);
+ d.makePositioned(effect.element.firstChild);
+ if (/Opera/.test(navigator.userAgent)) {
+ s.setStyle(effect.element, {left: ''});
+ }
+ },
+ afterUpdateInternal: function (effect) {
+ s.setStyle(effect.element.firstChild, {
+ right: (effect.dims[1] -
s.getElementWidth(effect.element)) + 'px'
+ });
+ },
+ afterFinishInternal: function (effect) {
+ d.undoClipping(effect.element, elemClip);
+ // IE will crash if child is undoPositioned first
+ if (/MSIE/.test(navigator.userAgent)) {
+ d.undoPositioned(effect.element);
+ d.undoPositioned(effect.element.firstChild);
+ } else {
+ d.undoPositioned(effect.element.firstChild);
+ d.undoPositioned(effect.element);
+ }
+ s.setStyle(effect.element, {
+ height: originalStyle.height,
+ width: originalStyle.width
+ });
+ s.setStyle(effect.element.firstChild, {
+ right: originalStyle.innerRight,
+ width: originalStyle.innerWidth
+ });
+ }
+ }, options);
+
+ return new MochiKit.Visual.Scale(element, 100, options);
+}
+
+/** @id MochiKit.Visual.slideOffLeft */
+MochiKit.Visual.slideOffLeft = function (element, /* optional */
options) {
+ /***
+
+ Slide an element off moving from right to left.
+ It must have a single inner child to work correctly
+
+ ***/
+ if (!element.hasChildNodes()) {
+ throw "MochiKit.Visual.slideOffLeft must be used on a element
with a child";
+ }
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ var elemClip;
+ element = d.getElement(element);
+ d.removeEmptyTextNodes(element);
+
+ /* don't want s.getElementWidth/Height, want the raw values for
full restore */
+ var originalStyle = {
+ height: element.style.height,
+ width: element.style.width,
+ right: element.style.right,
+ left: element.style.left,
+ innerRight: element.firstChild.style.right
+ };
+
+ options = b.update({
+ scaleContent: false,
+ scaleY: false,
+ scaleFrom: 100,
+ restoreAfterFinish: true,
+ beforeSetupInternal: function (effect) {
+ elemClip = d.makeClipping(effect.element);
+ s.showElement(effect.element);
+ scaleMode = {
+ originalHeight: s.getElementHeight(effect.element),
+ originalWidth: s.getElementWidth(effect.element),
+ };
+ },
+ afterSetupInternal: function (effect) {
+ s.setStyle(effect.element, {left: '0px'});
+ s.setStyle(effect.element.firstChild, {width:
scaleMode.originalWidth});
+ d.makePositioned(effect.element);
+ d.makePositioned(effect.element.firstChild);
+ if (/Opera/.test(navigator.userAgent)) {
+ s.setStyle(effect.element, {right: ''});
+ }
+ },
+ afterUpdateInternal: function (effect) {
+ s.setStyle(effect.element.firstChild, {
+ right: (effect.dims[1] -
s.getElementWidth(effect.element)) + 'px'
+ });
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.element);
+ d.undoClipping(effect.element, elemClip);
+ d.undoPositioned(effect.element.firstChild);
+ d.undoPositioned(effect.element);
+ s.setStyle(effect.element, {
+ width: originalStyle.width,
+ height: originalStyle.height,
+ right: originalStyle.right,
+ left: originalStyle.left
+ });
+ s.setStyle(effect.element.firstChild, {
+ right: originalStyle.innerRight
+ });
+ }
+ }, options);
+ return new MochiKit.Visual.Scale(element, 0, options);
+};
+
+/** @id MochiKit.Visual.slideOffRight */
+MochiKit.Visual.slideOffRight = function (element, /* optional */
options) {
+ /***
+
+ Slide an element off moving from left to right.
+ It must have a single inner child to work correctly
+
+ ***/
+ if (!element.hasChildNodes()) {
+ throw "MochiKit.Visual.slideOffRight must be used on a
element with a child";
+ }
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ var elemClip;
+ element = d.getElement(element);
+ d.removeEmptyTextNodes(element);
+
+ /* don't want s.getElementWidth/Height, want the raw values for
full restore */
+ var originalStyle = {
+ height: element.style.height,
+ width: element.style.width,
+ right: element.style.right,
+ left: element.style.left,
+ innerWidth: element.firstChild.style.width
+ };
+
+ options = b.update({
+ scaleContent: false,
+ scaleY: false,
+ scaleFrom: 100,
+ restoreAfterFinish: true,
+ beforeSetupInternal: function (effect) {
+ elemClip = d.makeClipping(effect.element);
+ s.showElement(effect.element);
+ scaleMode = {
+ originalHeight: s.getElementHeight(effect.element),
+ originalWidth: s.getElementWidth(effect.element),
+ };
+ },
+ afterSetupInternal: function (effect) {
+ s.setStyle(effect.element, {left: '0px'});
+ s.setStyle(effect.element.firstChild, {width:
scaleMode.originalWidth});
+ d.makePositioned(effect.element);
+ d.makePositioned(effect.element.firstChild);
+ if (/Opera/.test(navigator.userAgent)) {
+ s.setStyle(effect.element, {right: ''});
+ }
+ },
+ afterUpdateInternal: function (effect) {
+ s.setStyle(effect.element, {
+ left: (effect.dims[1] -
s.getElementWidth(effect.element)) + 'px'
+ });
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.element);
+ d.undoClipping(effect.element, elemClip);
+ d.undoPositioned(effect.element.firstChild);
+ d.undoPositioned(effect.element);
+ s.setStyle(effect.element, {
+ width: originalStyle.width,
+ height: originalStyle.height,
+ right: originalStyle.right,
+ left: originalStyle.left
+ });
+ s.setStyle(effect.element.firstChild, {
+ width: originalStyle.innerWidth
+ });
+ }
+ }, options);
+ return new MochiKit.Visual.Scale(element, 0, options);
+};
+
+/** @id MochiKit.Visual.slidePairLeft */
+MochiKit.Visual.slidePairLeft = function (elements, /* optional */
options) {
+ /***
+
+ Slide the first element off and the second element off from right
to left.
+
+ ***/
+ if (elements[0] != elements[1]) {
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ var v = MochiKit.Visual;
+ elements = [d.getElement(elements[0]),
d.getElement(elements[1])];
+ var parent = elements[1].parentNode;
+ var originalStyle = {
+ position: [
+ elements[0].style.position,
+ elements[1].style.position
+ ],
+ parentWidth: parent.style.width,
+ parentHeight: parent.style.height
+ };
+ options = b.update({
+ beforeSetupInternal: function (effect) {
+ },
+ afterSetupInternal: function (effect) {
+ s.setStyle(effect.effects[0].element.parentNode, {
+ width:
Math.max(s.getElementWidth(effect.effects[0].element),
+
s.getElementWidth(effect.effects[1].element)),
+ height:
Math.max(s.getElementHeight(effect.effects[0].element),
+
s.getElementHeight(effect.effects[1].element))
+ });
+ s.setStyle(effect.effects[0].element, {position:
'absolute'});
+ s.setStyle(effect.effects[1].element, {position:
'absolute'});
+ },
+ afterFinishInternal: function (effect) {
+ s.setStyle(effect.effects[0].element, {
+ position: originalStyle.position[0]
+ });
+ s.setStyle(effect.effects[1].element, {
+ position: originalStyle.position[1]
+ });
+ s.setStyle(parent, {
+ width: originalStyle.parentWidth,
+ height: originalStyle.parentHeight
+ });
+ }
+ }, options);
+ return new v.Parallel(
+ [v.slideOffLeft(elements[0]),
v.slideOnLeft(elements[1])],
+ options);
+ } else {
+ return null;
+ }
+}
+
+/** @id MochiKit.Visual.slidePairRight */
+MochiKit.Visual.slidePairRight = function (elements, /* optional */
options) {
+ /***
+
+ Slide the first element off and the second element off from left
to right.
+
+ ***/
+ if (elements[0] != elements[1]) {
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ elements = [d.getElement(elements[0]),
d.getElement(elements[1])];
+ var parent = elements[1].parentNode;
+ var originalStyle = {
+ position: [
+ elements[0].style.position,
+ elements[1].style.position
+ ],
+ parentWidth: parent.style.width,
+ parentHeight: parent.style.height
+ };
+ options = b.update({
+ beforeSetupInternal: function (effect) {
+ },
+ afterSetupInternal: function (effect) {
+ s.setStyle(effect.effects[0].element.parentNode, {
+ width:
Math.max(s.getElementWidth(effect.effects[0].element),
+
s.getElementWidth(effect.effects[1].element)),
+ height:
Math.max(s.getElementHeight(effect.effects[0].element),
+
s.getElementHeight(effect.effects[1].element))
+ });
+ s.setStyle(effect.effects[0].element, {position:
'absolute'});
+ s.setStyle(effect.effects[1].element, {position:
'absolute'});
+ },
+ afterFinishInternal: function (effect) {
+ s.setStyle(effect.effects[0].element, {
+ position: originalStyle.position[0]
+ });
+ s.setStyle(effect.effects[1].element, {
+ position: originalStyle.position[1]
+ });
+ s.setStyle(parent, {
+ width: originalStyle.parentWidth,
+ height: originalStyle.parentHeight
+ });
+ }
+ }, options);
+ return new MochiKit.Visual.Parallel(
+ [slideOffRight(elements[0]), slideOnRight(elements[1])],
+ options);
+ } else {
+ return null;
+ }
+}
+
+/** @id MochiKit.Visual.slidePairRight */
+MochiKit.Visual.slidePair = function (elements, /* optional */
options) {
+ /***
+
+ Slide the first element on and the second element off. Direction
is based
+ on relative position of the two elements in the child node list.
It assumes
+ both are siblings.
+
+ ***/
+ if (elements[0] != elements[1]) {
+ for (sibling = elements[0].nextSibling;
+ sibling && sibling != elements[1];
+ sibling = sibling.nextSibling) {
+ }
+ if (sibling == elements[1]) {
+ return MochiKit.Visual.slidePairRight(elements, options);
+ } else {
+ return MochiKit.Visual.slidePairLeft(elements, options);
+ }
+ } else {
+ return null;
+ }
+}
+
+
// Bug in opera makes the TD containing this element expand for a
instance
// after finish
/** @id MochiKit.Visual.squish */
@@ -1995,6 +2442,13 @@
"shake",
"slideDown",
"slideUp",
+ "slideOnLeft",
+ "slideOnRight",
+ "slideOffLeft",
+ "slideOffRight",
+ "slidePairLeft",
+ "slidePairRight",
+ "slidePair",
"squish",
"grow",
"shrink",
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"MochiKit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---