gpt4 book ai didi

javascript - 同一个函数用不同的参数调用了两次,但只执行了最后一次

转载 作者:行者123 更新时间:2023-11-29 17:39:55 31 4
gpt4 key购买 nike

我有 2 个 div 需要制作动画:

<div class="d"></div>
<div class="p"></div>

第一个 div 的宽度应变为 70%,第二个 div 的宽度应变为 30%。但是当我尝试一个接一个地制作一个 div 的动画时,首先调用 70% 的函数然后调用 30% 的函数,它们的宽度都变成 30%。

Javascript 代码:

Anim({
target: document.getElementsByClassName('d')[0],
drawFunc: (progress, element) => {
element.style.width = (progress * 70) + '%';
}
});

Anim({
target: document.getElementsByClassName('p')[0],
drawFunc: (progress, element) => {
element.style.width = (progress * 30) + '%';
}
});

我不明白为什么会发生这种情况以及如何使这两个功能正常工作。

代码片段(如果需要):

(() => {
"use strict";

const init = (params) => {
const start = performance.now();
const element = params.target || null;

requestAnimationFrame(function animate(time) {
let timeFraction = (time - start) / params.duration;

if (timeFraction > 1) {
timeFraction = 1;
}

const progress = params.timingFunc(timeFraction, params.timingArg);

params.drawFunc(progress, element);

if (timeFraction < 1) {
requestAnimationFrame(animate);
}

if (params.callback) {
if (timeFraction >= 1) {
params.callback();
}
}
});
};
const timingFunctions = {
linear: (timeFraction) => {
return timeFraction;
}
};
const paces = {
easeIn: (func) => {
return timingFunctions[func];
}
};
const defaultParams = {
duration: 1000,
timingFunc: paces.easeIn('linear'),
timingArg: null,
delay: null,
callback: null
};
const makeParams = (def, add) => {
let params = def;

if (add) {
for (let i in add) {
if (Object.prototype.hasOwnProperty.call(add, i)) {
params[i] = add[i];
}
}
}

return params;
};

function Anim(paramArgs) {
const params = makeParams(defaultParams, paramArgs);

if ('timingFunc' in paramArgs) {
params.timingFunc = (typeof paramArgs.timingFunc === 'function') ? paramArgs.timingFunc : paces[paramArgs.timingFunc.pace](paramArgs.timingFunc.func);
}

if (!params.delay) {
init(params);
} else {
setTimeout(() => {
init(params);
}, params.delay);
}
}

window.Anim = Anim;
})();

Anim({
target: document.getElementsByClassName('d')[0],
drawFunc: (progress, element) => {
element.style.width = (progress * 70) + '%';
}
});

Anim({
target: document.getElementsByClassName('p')[0],
drawFunc: (progress, element) => {
element.style.width = (progress * 30) + '%';
}
});
.d, .p {
background-color: red;
height: 50px;
width: 0;
margin-top: 10px;
}
<div class="d"></div>
<div class="p"></div>

最佳答案

问题在于两个 Anim 调用具有相同的 params 对象。两个 params 对象都有完全相同的回调 drawFunc

为什么?因为在 makeParams 中你这样做:

let params = def;

然后您分配给 params,这又会改变原始的 defaultParams(此处别名为 def)。当第二个函数调用 Anim 时,第二次调用的回调 drawFunc 被分配给 defaultParams 对象。由于所有 params 对象基本上都是对 defaultParams 的引用,它们也会被改变,并且最后一次调用 Anim 的回调被分配给所有

要解决此问题,只需使用 Object.assign 克隆 def:

let params = Object.assign({}, def);

旁注: target 属性也在 params 对象中改变,但在改变之前,它被分配给一个新变量在 init 中:

const element = params.target || null;

因此,即使它在 params 对象中发生了变化,您也不会真正注意到,因为所有后续代码都使用变量 element 而不是 params.target

工作代码:

(() => {
"use strict";

const init = (params) => {
const start = performance.now();
const element = params.target || null;

requestAnimationFrame(function animate(time) {
let timeFraction = (time - start) / params.duration;

if (timeFraction > 1) {
timeFraction = 1;
}

const progress = params.timingFunc(timeFraction, params.timingArg);

params.drawFunc(progress, element);

if (timeFraction < 1) {
requestAnimationFrame(animate);
}

if (params.callback) {
if (timeFraction >= 1) {
params.callback();
}
}
});
};
const timingFunctions = {
linear: (timeFraction) => {
return timeFraction;
}
};
const paces = {
easeIn: (func) => {
return timingFunctions[func];
}
};
const defaultParams = {
duration: 1000,
timingFunc: paces.easeIn('linear'),
timingArg: null,
delay: null,
callback: null
};
const makeParams = (def, add) => {
let params = Object.assign({}, def);

if (add) {
for (let i in add) {
if (Object.prototype.hasOwnProperty.call(add, i)) {
params[i] = add[i];
}
}
}

return params;
};

function Anim(paramArgs) {
const params = makeParams(defaultParams, paramArgs);

if ('timingFunc' in paramArgs) {
params.timingFunc = (typeof paramArgs.timingFunc === 'function') ? paramArgs.timingFunc : paces[paramArgs.timingFunc.pace](paramArgs.timingFunc.func);
}

if (!params.delay) {
init(params);
} else {
setTimeout(() => {
init(params);
}, params.delay);
}
}

window.Anim = Anim;
})();

Anim({
target: document.getElementsByClassName('d')[0],
drawFunc: (progress, element) => {
element.style.width = (progress * 70) + '%';
}
});

Anim({
target: document.getElementsByClassName('p')[0],
drawFunc: (progress, element) => {
element.style.width = (progress * 30) + '%';
}
});
.d, .p {
background-color: red;
height: 50px;
width: 0;
margin-top: 10px;
}
<div class="d"></div>
<div class="p"></div>

相关问题: How do I correctly clone a JavaScript object?

关于javascript - 同一个函数用不同的参数调用了两次,但只执行了最后一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53733654/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com