2013-12-10 20 views
17

在我的關閉函數中,我想在css轉換完成後執行所有DOM清理工作。但是可能沒有任何轉換正在運行/可能是多階段轉換 - (保持樣式表不在我的手中)。我可以檢測一個任意的CSS轉換是否已經開始

我將如何去寫一個功能類似下面

function close() { 
    myEl.removeClass('open'); 
    if (animation is running/about to be run) { 
    // wait for transition to end, then recursively check to see if another 
    // one has started, wait for that ... 
    // then 
    cleanUpDOM(); 
    } else { 
    cleanUpDOM(); 
    } 
} 

我的想法至今都包裹在超時/ requestAnimationFrame初步檢查,以便給動畫一個機會下手,然後檢查看看它是否在運行。不幸的是,沒有transitionstart事件,我不知道如何檢查轉換是否已經開始。

編輯答案推薦的jQuery是無關緊要的jQuery動畫是動畫的JavaScript,CSS不轉變

+0

如果你知道你可以決定哪些屬性被動畫如果動畫過程中通過比較它的CSS樣式值(也稱爲目標)是什麼樣的元素當前屬性值? – milks

+0

@milks總的來說,我不知道什麼是被轉換的,或者甚至是什麼都被轉換了。 (最糟糕的情況實際上更棘手 - 我可能甚至不知道過渡是否在外部元素上,例如在疊加層中,內部內容區域可能縮小到某一點,儘管外部疊加層只是保持黑色......但是這種情況並不是現在非常重要) – wheresrhys

+0

我認爲這是http://stackoverflow.com/questions/2087510/callback-on-css-transition –

回答

1

關於transitionStart和transitionEnd事件:

的轉變無法從無處開始。通常在某個事件之後開始轉換,其中您通過按類或其他方式更改樣式來更改DOM元素的狀態。所以你知道什麼時候開始轉換,因爲你在你的代碼中啓動它。

在轉換過程中,用戶I/O不會阻塞,因此轉換是異步的,然後轉換將結束,您不知道對不對。所以你需要transitionEnd事件來做一些事情,然後在JavaScript中完成轉換。

關於transitionEnd事件: 只看該jsfiddle

+4

我不明確地在我的'js'代碼中啓動它。我在'js'中添加了一個類,它在'css'中應用了一些樣式,它可能會涉及到一個轉換,所以我的js'不知道是否啓動了轉換 – wheresrhys

+0

您可以檢查轉換支持(帶有前綴還是不帶)由[Modernizr](http://modernizr.com/)。如果支持轉換,你可以檢查'transitionDelay','transitionDuration'和'transitionProperty'的樣式對象,並獲得值以知道是否會轉換開始。 – Pinal

+0

你無法確定轉換何時開始,因爲這是瀏覽器執行的異步操作,你不知道什麼時候執行。看看:https://stackoverflow.com/questions/27275872/race-condition-with-css-transitions-and-transitionend-event-cannot-find-a-solu – demian85

1

這裏是我的解決方案至今 - 有點哈克並且僅適用時元素可能轉變是已知的,並且不與transition-property: all工作......但這是一個良好的開端

function toCamelStyleProp (str) { 
    return str.replace(/(?:\-)([a-z])/gi, function ($0, $1) { 
     return $1.toUpperCase(); 
    }); 
} 

function toHyphenatedStyleProp (str) { 
    return str.replace(/([A-Z])/g, function (str,m1) { 
     return '-' + m1.toLowerCase(); 
    }).replace(/^ms-/,'-ms-'); 
} 

function getPrefixedStyleProp (prop) { 
    prop = toCamelStyleProp(prop); 
    prop = Modernizr.prefixed(prop); 
    return toHyphenatedStyleProp(prop); 
} 

function getStyleProperty (el, prop) { 
    return getComputedStyle(el,null).getPropertyValue(getPrefixedStyleProp(prop)); 
} 

function doAfterTransition ($wrapper, cssClass, mode, $transitioningEl, callback) { 
    $transitioningEl = $transitioningEl || $wrapper; 

    var transitioningEl = $transitioningEl[0], 
     duration = +getStyleProperty(transitioningEl, 'transition-duration').replace(/[^\.\d]/g, ''), 
     transitioners = getStyleProperty(transitioningEl, 'transition-property').split(' '), 
     initialState = [], 
     changedState = [], 
     i, 
     callbackHasRun = false, 

     //makes sure callback doesn't get called twice by accident 
     singletonCallback = function() { 
      if (!callbackHasRun) { 
       callbackHasRun = true; 
       callback(); 
      } 
     }; 

    // if no transition defined just call the callback 
    if (duration === 0) { 
     $wrapper[mode + 'Class'](cssClass); 
     callback(); 
     return; 
    } 

    for (i = transitioners.length - 1;i>=0;i--) { 
     initialState.unshift(getStyleProperty(transitioningEl, transitioners[i])); 
    } 

    $wrapper[mode + 'Class'](cssClass); 

    setTimeout(function() { 
     for (i = transitioners.length - 1;i>=0;i--) { 
      changedState.unshift(getStyleProperty(transitioningEl, transitioners[i])); 
     } 

     for (i = transitioners.length - 1;i>=0;i--) { 
      if (changedState[i] !== initialState[i]) { 
       $transitioningEl.transitionEnd(singletonCallback); 

       // failsafe in case the transitionEnd event doesn't fire 
       setTimeout(singletonCallback, duration * 1000); 
       return; 
      } 
     } 
     singletonCallback(); 
    }, 20); 
} 
-1

如果你打算做的CSS過渡,你可以檢查出的jQuery插件過境http://ricostacruz.com/jquery.transit/

非常強大和有用的,你可以得到變換x值。例如,css('x')。

-1

animation.css我發現這個。

動畫結束時,您還可以檢測:

$('#yourElement').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', doSomething); 

read full doc here

1

沒有辦法(我知道的),以檢測是否轉換​​在後臺目前正不知道該元素正在過渡。但是,如果您可以遠離過渡到關鍵幀動畫,那麼您將擁有如此需要的事件 - animationStart和animationEnd,然後很容易找出是否有正在運行的動畫。

1

你試過JQuery僞「:動畫」?

如果($(ELEM)。是( ':動畫')){...}

查看更多http://api.jquery.com/animated-selector/

+1

這將只適用於jQuery的JavaScript動畫https: //github.com/jquery/jquery/blob/master/src/effects/animatedSelector.js - 看看它如何在jQuery中有一個計時器 – wheresrhys

-1

你可以使用jQuery這將是例如更容易你可以使用.animate這樣

(function(){ 
      var box = $('div.box') 
      $('button').on('click', function(){ 
       box.animate({ 'font-size' : '40px'}) 
       .animate({'color': 'red'}); 
      }) 
     })(); 

或者乾脆做一個回調函數

0

這是一個等待頁面Html變得穩定的函數。即當所有動畫完成時。在下面的例子中,它等待Html不變,持續200毫秒,最大超時時間爲2秒。

調用具有功能...

waitUntilHtmlStable(yourCallback, 200, 2000); 

功能...

waitUntilHtmlStable = function (callback, unchangedDuration, timeout, unchangedElapsed, html) { 
    var sleep = 50; 
    window.setTimeout(function() { 
     var newHtml = document.documentElement.innerHTML; 
     if (html != newHtml) unchangedElapsed = 0; 
     if (unchangedElapsed < unchangedDuration && timeout > 0) 
      waitUntilHtmlStable(callback, unchangedDuration, timeout - interval, unchangedElapsed + interval, newHtml); 
     else 
      callback(); 
    }, sleep); 
}; 

在我來說,我希望確保新的元素,其中存在。如果你想跟蹤動畫運動然後更改document.documentElement.innerHTML到

JSON.stringify(Array.prototype.slice.call(document.documentElement.getElementsByTagName("*"), 0) 
.map(function(e) { 
     var x = e; 
     var r = x.getBoundingClientRect(); 
     while (r.width == 0 || r.height == 0) { 
      x = x.parentNode; 
      r = x.getBoundingClientRect(); 
     } 
     return r; 
    })); 
相關問題