ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript – 没有属性更改时,jQuery中没有触发CSS转换事件

2019-06-30 08:20:42  阅读:170  来源: 互联网

标签:jquery javascript css css-transitions


我遇到了一个有趣的案例,没有在W3C CSS Transitions规范或MDN CSS Transitions文档中明确涵盖,我认为我会分享,因为它花了我一点时间.

如果您将CSS转换属性“更改”为相同的值,则不会触发转换事件.当我想到我可以看到为什么这将是默认行为,但它很容易导致毫无戒心的开发人员的问题,如下所示:
$(“#test”).css(“opacity”,“1”).bind(“transitionend”,doneFn);

在上面的代码中,如果所讨论的元素恰好具有1的不透明度,则永远不会调用doneFn.另见http://jsfiddle.net/studgeek/Xj8TB/.

要做到这一点是一个问题,有一个很好的解决方法来处理这个问题吗?

您可以将属性值与现有属性值进行比较,但这比现有属性值要好得多,因为css属性值可以采用如此多的形式 – 不同的单位,甚至像auto这样的字符串值.所以你真的必须测试对象的实际状态,当然需要为每个属性做不同的事情.啊.

解决方法:

一个解决方法是制作自己的jQuery方法来设置一个可以为你处理一切的CSS值.它将获取属性的当前值,设置新值,检查值是否已更改.如果没有,则会手动触发完成功能:

// globally set this to the right transition event for the current browser
// modernizr has ways of using feature detection to know which is the right way to set this
var transitionEvent = "webkitTransitionEnd";

jQuery.fn.transitionTo = function(prop, value, completeFn) {
    var origValue, item;
    for (var i = 0, len = this.length; i < len; i++) {
        item = jQuery(this[i]);
        origValue = item.css(prop);
        item.css(prop, value);

        // if value hasn't changed           
        if (origValue == item.css(prop)) {
            completeFn.apply(this[i]);
        } else {
            this.one(transitionEvent, completeFn);
        }
    }
}

在上面的示例中,它将像这样工作:

$("#test").transitionTo("opacity", "1", doneFn);

这里的工作示例:http://jsfiddle.net/jfriend00/LHdGR/

可以扩展此插件以支持传递多个属性的映射,例如.css()也支持.

我能想到的唯一另一个选择是读取transtionDuration并设置一个稍长于此的超时值.如果transitionEnd事件触发,则取消超时.如果它不触发,超时可以手动触发transitionEnd事件.这个代码可以像这样工作:

var transitionEvent = "webkitTransitionEnd";
var transitionDuration = "WebkitTransitionDuration";

// get transition duration in decimal seconds
// this only returns the first transition time if there are multiple ones specified
jQuery.fn.getDuration = function() {
    var val = this.css(transitionDuration);
    if (!val) {
        val = "0s";
    }
    var num = parseFloat(val);
    var units = val.replace(/\d\., /g, "");
    if (units.indexOf("ms") == 0) {
        num /= 1000;
    }
    return(num);
}

// set a guaranteed transition event that will always fire, even if
// no CSS transition is triggered
jQuery.fn.setTransitionEvent = function(completeFn) {
    var item, duration;
    for (var i = 0, len = this.length; i < len; i++) {
        item = jQuery(this[i]);
        duration = Math.ceil((Number(item.getDuration()) + 0.1) * 1000);
        (function(t, o) {
            var timeout = setTimeout(function() {
                completeFn.apply(o);
                o.unbind(transitionEvent);
            }, duration);
            o.one(transitionEvent, function() {
                clearTimeout(timeout);
            });
        })(duration, item);
    }
}

这里的工作示例:http://jsfiddle.net/jfriend00/hxevW/

标签:jquery,javascript,css,css-transitions
来源: https://codeday.me/bug/20190630/1334793.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有