以编程方式更改动画规则中的 webkit 转换值

IT技术 javascript css safari webkit mobile-safari
2021-03-02 12:06:19

我有这个样式表:

        @-webkit-keyframes run {
            0% {
                -webkit-transform: translate3d(0px, 0px, 0px);
            }            
            100% {
                -webkit-transform: translate3d(0px, 1620px, 0px);
            }
        }

现在,我想根据一些参数修改 1620px 的值。像这样:

        @-webkit-keyframes run {
            0% {
                -webkit-transform: translate3d(0px, 0px, 0px);
            }            
            100% {
                -webkit-transform: translate3d(0px, height*i, 0px);
            }
        }

我更希望能够使用 JavaScript 和 jQuery,尽管纯 CSS 解决方案也可以。

这是针对在其移动 Apple Safari 浏览器中运行的 iPhone 游戏。

6个回答

使用 CSSOM

var style = document.documentElement.appendChild(document.createElement("style")),
rule = " run {\
    0%   {\
        -webkit-transform: translate3d(0, 0, 0); }\
        transform: translate3d(0, 0, 0); }\
    }\
    100% {\
        -webkit-transform: translate3d(0, " + your_value_here + "px, 0);\
        transform: translate3d(0, " + your_value_here + "px, 0);\
    }\
}";
if (CSSRule.KEYFRAMES_RULE) { // W3C
    style.sheet.insertRule("@keyframes" + rule, 0);
} else if (CSSRule.WEBKIT_KEYFRAMES_RULE) { // WebKit
    style.sheet.insertRule("@-webkit-keyframes" + rule, 0);
}

如果要修改已包含的样式表中的关键帧规则,请执行以下操作:

var
      stylesheet = document.styleSheets[0] // replace 0 with the number of the stylesheet that you want to modify
    , rules = stylesheet.rules
    , i = rules.length
    , keyframes
    , keyframe
;

while (i--) {
    keyframes = rules.item(i);
    if (
        (
               keyframes.type === keyframes.KEYFRAMES_RULE
            || keyframes.type === keyframes.WEBKIT_KEYFRAMES_RULE
        )
        && keyframes.name === "run"
    ) {
        rules = keyframes.cssRules;
        i = rules.length;
        while (i--) {
            keyframe = rules.item(i);
            if (
                (
                       keyframe.type === keyframe.KEYFRAME_RULE
                    || keyframe.type === keyframe.WEBKIT_KEYFRAME_RULE
                )
                && keyframe.keyText === "100%"
            ) {
                keyframe.style.webkitTransform =
                keyframe.style.transform =
                    "translate3d(0, " + your_value_here + "px, 0)";
                break;
            }
        }
        break;
    }
}

如果您不知道顺序但知道 CSS 文件的 URL,请替换document.styleSheets[0].document.querySelector("link[href='your-css-url.css']").sheet

也许我说得太早了。我不断收到此错误:未捕获错误:SYNTAX_ERR:DOM 异常 12,我也收到未捕获错误:SYNTAX_ERR:DOM 异常 1
2021-04-19 12:06:19
最后的 insertRule 行应该将它添加到索引 0 而不是 1,这就是 DOM Exception 1 的原因
2021-04-26 12:06:19
If来自第一部分的 's 可能应该重新排序。参见stackoverflow.com/questions/20007992/...
2021-05-06 12:06:19
非常精彩!很好的答案!这对我帮助很大!
2021-05-08 12:06:19

您是否尝试过<style>在 html 文档头部的元素中声明 css 的关键帧部分然后你可以给这个元素一个 id 或其他任何东西,并在你喜欢的时候用 javaScript 改变它的内容。像这样的东西:

<style id="keyframes">
        @-webkit-keyframes run {
            0%    { -webkit-transform: translate3d(0px,0px,0px); }            
            100%  { -webkit-transform: translate3d(0px, 1620px, 0px); }
        }
</style>

然后你的 jquery 可以像往常一样改变它:

$('#keyframes').text('whatever new values you want in here');
Javascript 相当于这个伟大的解决方案: document.getElementById('keyframes').innerHTML = "new css animation values" ;
2021-05-14 12:06:19

好吧,从你的例子来看,在我看来 CSS 动画可能有点矫枉过正。改用过渡:

-webkit-transition: -webkit-transform .4s linear; /* you could also use 'all' instead of '-webkit-transform' */

然后通过 js 对元素应用一个新的变换:

$("<yournode>")[0].style.webkitTransform = "translate3d(0px,"+ (height*i) +"px,0px)";

它应该动画。

@Tokimon 我为你修好了。谢谢你的回答,对我很有帮助。
2021-04-21 12:06:19
应该是$("<yournode>")[0] .style。 webkitTransform
2021-04-28 12:06:19

我不知道您何时想要修改这些值(即使用变量),但这里有 3 到 4 个解决方案和 1 个不可能的解决方案(目前)。

  • 服务器端计算:为了不时提供不同的 CSS,您可以告诉 PHP 或任何服务器端语言解析.css文件以及.phpor.html然后在 PHP 标记之间使用 PHP 变量。当心文件缓存:为了避免它,你可以加载一个样式表,比如 style.css?1234567890random-or-time 它会产生一个明显不同的文件,因此不会被缓存

  • SASS也是一个需要 Ruby 的服务器端解决方案,它将为您提供现有的语法,可能比其他人已经关于问题和解决方案的手工解决方案更简洁

  • LESS是一个客户端解决方案,它将加载您的 .less 文件和一个 less.js 文件,该文件将解析前者并为您提供 CSS 中的变量,无论您的服务器是什么。它也可以与 node.js 一起在服务器端工作

  • 显示页面时动态修改CSS
    对于 2D,有来自 Ben Barnett 的jquery-animate-enhanced2d-transformCSS3 旋转是相反的(他们在可能的情况下使用 CSS3,并且在没有此类功能的情况下,他们回退到现有的 jQuery .animate() 和 IE矩阵过滤器)但就是这样。
    您可以为 jQuery 创建一个插件,该插件将使用一些参数来管理您想要通过 3D 转换实现的目标,并避免在 DOM 中修改长而复杂的 CSS 规则的麻烦

  • 仅 CSS:您可以使用仅适用于 Firefox 4.0 的-moz-calc [ 1 ][ 2 ] 和仅适用于...的-webkit-transform ......好吧没关系:-)

“你可以为 jQuery 创建一个插件来管理一些参数”是极端的矫枉过正。对于这个用例,CSSOM 实际上非常简单。他只是insertRule将单曲CSSStyleRule放入CSSStyleSheet. 这是一个函数调用。
2021-04-19 12:06:19
calc() 也适用于 IE9。此外,在每个现代浏览器中转换工作,而不仅仅是 Webkit(当然还有适当的前缀)。
2021-04-26 12:06:19
感谢您的详细回答!我想在页面加载后随时修改这些值,所以不幸的是,服务器端解决方案不是一个选项。我会看看你提到的其他解决方案。
2021-05-06 12:06:19

尝试这样的事情:

var height = {你想要检测的任何高度设置};
element.style.webkitTransform = "translate3d(0px," + height*i + ",0px)";
谢谢,但这实际上并不是我正在寻找的。我宁愿更改现有动画规则中的值
2021-04-29 12:06:19