- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要一个特殊的类似 transitionend
的事件,该事件在所有转换完成后触发一次,或者如果 CSS 中没有定义转换则立即触发。
这是我到目前为止所想到的:
(function($){
$.event.special.transitionsComplete = {
setup: function(data, namespaces, eventHandle){
var queue = [],
style = window.getComputedStyle(this, null),
computedProps = style.getPropertyValue('transition-property').split(', '),
computedDurations = style.getPropertyValue('transition-duration').split(', '),
$node = $(this);
// only count properties with duration higher than 0s
for(var i = 0; i < computedDurations.length; i++)
if(computedDurations[i] !== '0s')
queue.push(computedProps[i]);
// there are transitions
if(queue.length > 0){
$node.on('webkitTransitionEnd.x transitionend.x', function(e){
queue.splice(queue.indexOf(e.originalEvent.propertyName));
if(queue.length < 1)
$node.trigger('transitionsComplete');
});
// no transitions, fire (almost) immediately
}else{
setTimeout(function(){
$node.trigger('transitionsComplete');
}, 5);
}
},
teardown: function(namespaces){
$(this).off('.x');
}
};
})(jQuery);
我做了一个活生生的例子here .
唯一的问题是,它仅在元素本身具有转换属性时才有效,忽略子元素的转换。如果我将 transitionsComplete
切换为 transitionend
,则父级事件处理程序和子级事件处理程序都会在子级转换完成后运行。有没有某种方法,或者更好的方法来确定一个元素或其子元素是否发生转换?如果可能的话,我想避免手动检查子项并检查它们的转换属性。 (无论如何,这都是不可靠的,因为即使有些 child 有过渡,也不意味着他们在那时会很活跃)
最佳答案
我用过 treeWalker api遍历原始节点(根)和所有子节点(仅限元素),过滤掉没有转换的元素,并将转换属性收集到队列
( fiddle )。正如您所看到的,我已经解决了 complete-div
和 complete-p
之间的时间差,并且它们现在同时触发(几乎 - 几毫秒) .
有两个警告,我没有解决方法:
.visible
添加到 div
来触发的,并且其他通过添加.invisible
,它们都会被添加到队列
中。该事件永远不会触发,因为队列
永远不会为空 - 我不知道如何解决这个问题。padding
例如),可以使用 transition-property
触发多个 transitionend
事件,例如 padding-top
、padding-right
等...这个将导致数组很快清空,如 splice(-1, 1)
从数组末尾删除项目。我有一个 workaround , 但这可能会导致问题,因为它可能会删除队列
。最好的解决方法是不要通过快捷方式进行转换属性。treeWalker 的代码基于 Ban Nadel 的 - Finding HTML Comment Nodes In The DOM Using TreeWalker .
最后的代码:
(function ($) {
$.event.special.transitionsComplete = {
setup: function (data, namespaces, eventHandle) {
var TRANSITION_PROPERTY = 'transition-property';
var TRANSITION_DURATION = 'transition-duration';
var root = this;
var queue = [];
var $node = $(this);
function filter(node) { // filter for treeWalker
/*** filters transitions which are a string with one '0s'. If more then '0s' is defined it will be catched when creating the queue ***/
var computedDuration = window.getComputedStyle(node, null)
.getPropertyValue(TRANSITION_DURATION);
return computedDuration === '0s' ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
}
filter.acceptNode = filter; // for webkit and firefox
/** create the treeWalker to traverse only elements **/
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, filter, false);
/** traverse all elements using treeWalker.nextNode(). First node is the root **/
do {
var style = window.getComputedStyle(treeWalker.currentNode, null);
var computedProps = style.getPropertyValue(TRANSITION_PROPERTY).split(', ');
var computedDurations = style.getPropertyValue(TRANSITION_DURATION).split(', ');
/** push all props with duration which is not 0s **/
computedDurations.forEach(function (duration, index) {
duration !== '0s' && queue.push(computedProps[index]);
});
} while (treeWalker.nextNode()); // iterate until no next node
// no transitions, fire (almost) immediately
if (queue.length === 0) {
setTimeout(function () {
$node.trigger('transitionsComplete');
}, 5);
return; // return out of the function to skip the transitions block
}
// there are transitions
$node.on('webkitTransitionEnd.x transitionend.x', function (e) {
var propertyName = e.originalEvent.propertyName;
var indexOfProp = queue.indexOf(propertyName);
queue.splice(indexOfProp, 1);
if (queue.length < 1) {
console.log('Transitions Complete');
$node.trigger('transitionsComplete');
}
});
},
teardown: function (namespaces) {
$(this).off('.x');
}
};
})(jQuery);
关于javascript - 始终触发且仅触发一次的 "transitionend"事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32469577/
我正在尝试使用 jQuery 和 css 转换对一些动画进行排序。看起来容器宽度应该在小部件完成从“顶部”css 更改的转换之前进行动画处理,但它们是一起触发的。 为什么 widget
我想在项目上的波纹动画执行后执行一个函数。我目前正在使用以下代码: Proceed 这是一张带有图像和文本的卡片。当
我向 div 添加了一个 transitionend 事件监听器。此 div 具有在某些元素上具有过渡效果的子元素。我希望 transitionend 事件只针对我添加它的元素触发,这是一个错误吗?或
我有多个元素,每个元素都以(某种程度上)持续时间进行动画处理。我使用 CSS3 转换动画,使用 jQuery 库和来自 David Walsh 的 transitionend 辅助函数. 我的问题是
我有一些 javascript 会触发一些样式更改,从而导致 CSS 转换。 我应该如何挂接一个将在转换完成后执行的回调。显然,在旧版浏览器中,它会立即转换,但这些浏览器也无法识别 transitio
我有以下代码,我的问题是 transitionend 事件被触发了两次。我不知道是什么原因造成的。我怀疑 vendor 前缀导致了它,但事实并非如此。即使我只留下 transitionend 和 tr
我想了解为什么以下代码会以指数方式复制 transitionend 的返回值。 这对我来说没有任何意义,因为它们应该具有相同的行为并且应该只执行一次。 下面评论了预期的行为。 (function()
我需要一个特殊的类似 transitionend 的事件,该事件在所有转换完成后触发一次,或者如果 CSS 中没有定义转换则立即触发。 这是我到目前为止所想到的: (function($){ $.
在下面的示例中,我正在使用 CSS 进行 background-color 转换,并尝试处理两个 div 的 transitionend 事件。 不幸的是,transitionend 不会为 div2
我有一个 HTML 元素,我附加了一个 webkitTransitionEnd 事件。 function transEnd(event) { alert( "Finished transiti
我似乎无法让这个过渡的开始部分起作用,只有结束部分。 我之所以按照我的方式构建我的 html,是因为我需要使用 display: none 和 display:block 来实际删除元素文档流。使用
我为 CSS 关键帧动画创建了一个非常基本的测试,包括“ontransitionend”的事件监听器 - 但无论我使用什么变体,这个“过渡结束”监听器都不会触发。 (我的完整代码包含所有 vendor
我正在尝试编写一些具有 webkitTransitionEnd eventListener 回调函数的东西,但由于某种原因 eventListener 被触发了两次(doSomething 被执行了两
我有一个小应用程序,它使用 CSS3 添加和删除 .is-active 动画部分,我需要从中删除 .is-active元素 .resulting-page 然后在 transitionend 上将 .
closeContent() function 有一些问题,我不知道如何在每次单击 .show-content< 时阻止它运行. transitionend 基本上不应该踢两次。 任何帮助将不胜感激。
我想创建一个自定义事件来处理 transitionend 事件的所有不同 vendor 前缀版本(即 webkitTransitionEnd、mozTransitionEnd 、msTransitio
我有两个 div 元素,即 .parentDiv 和 .childDiv 我正在使用 css transition 来为两者设置动画。 .childDiv 应首先为其不透明度设置动画,然后在 tran
检查一下: http://jsfiddle.net/jqs4yy0p/ JS $('div').addClass('switch').on('transitionend', function(e){
我试图让 mouseover 事件监听器仅在 css 转换结束时触发。我尝试在 css 转换结束时提醒一条随机消息,它确实按预期工作(仅在结束时显示消息)。但出于某种原因,mouseover 事件甚至
我有一个切换器,我正在使用 jQuery 调用其 checked 状态。每次我单击从未选中切换到选中时,控制台都会记录 “do this!” 两次。为什么此函数会触发两次?让它触发一次的解决方法是什么
我是一名优秀的程序员,十分优秀!