使用 jQuery/javascript 停止条形动画
Stop bar animation with jQuery/javascript
对 JS 完全陌生,jQuery 在这里。代码遍历每个条形,当您按下 Reset 按钮时,它应该将条形缩小为零。但是,我试图让这个条形图动画停止,但是一旦你按下按钮,它就会通过动画并再次重置回之前的位置。如有任何帮助,我们将不胜感激!
function barGraph(data) {
//Create graph
var graph = document.createElement("div");
graph.id = "barGraph";
//inserting bar graph before previous 'label' div
const target = document.querySelector('#labels');
target.parentNode.insertBefore(graph, labels);
//Styling for graph
graph.style.position = "relative";
graph.style.marginTop = "20px";
graph.style.height = "500px";
graph.style.backgroundColor = "Gainsboro";
graph.style.borderBottomStyle = "solid";
graph.style.borderBottomWidth = "1px";
graph.style.overflow = "hidden";
//Iterating through each bar
var position = 50;
var width = 75;
for (i = 0; i < data.length; i += 1) {
var spendData = data[i];
var bar = document.createElement("div");
//set a unique id for each of the bars
bar.id = data[i].category;
//Styling for bar
bar.style.position = "absolute";
bar.style.left = position + "px";
bar.style.width = width + "px";
bar.style.backgroundColor = spendData.color;
bar.style.height = (spendData.amount) / 5 + "px";
bar.style.bottom = "0px";
bar.innerHTML = "$" + spendData.amount;
bar.style.fontSize = "11px";
bar.style.color = "Azure";
bar.style.fontWeight = "800";
bar.style.fontFamily = "Arial, Helvetica, sans-serif";
bar.style.textAlign = "center";
bar.style.padding = "1em";
//Appending to the graph
graph.appendChild(bar);
//Set bar width
position += (width * 2);
}
return graph;
}
window.onload = function() {
var data = [{
category: "Food and Dining",
amount: "2005.00",
color: "CadetBlue"
},
{
category: "Auto and Transport",
amount: "1471.31",
color: "CornflowerBlue"
},
{
category: "Shopping",
amount: "892.86",
color: "DarkCyan"
},
{
category: "Bills and Utilities",
amount: "531.60",
color: "DarkSeaGreen"
},
{
category: "Mortgage",
amount: "1646.00",
color: "LightSeaGreen"
},
{
category: "Entertainment",
amount: "179.52",
color: "YellowGreen"
}
];
document.getElementById("resetGraph").addEventListener("click", function() {
for (i = 0; i < data.length; i++) {
var bar = document.getElementById(data[i].category);
if (bar) {
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000);
}
}
});
var graph = barGraph(data);
//document.div.appendChild(graph);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="labels"></div>
<button id="resetGraph">Reset graph</button>
<script src="js/spending-graph.js"></script>
已更新
有趣的问题! AFAICT 问题是你混淆了 jQuery's .animate()
with the native Javascript .animate()
.
你的问题被标记为 jQuery-animate,你明确地提到了它,你传递给 .animate()
的参数格式正是 jQuery 所期望的。
但是您的动画代码 运行ning 是针对 HTML DOM 元素,而不是 jQuery 元素:
// bar here is an HTML DOM Element, not a jQuery object:
var bar = document.getElementById(data[i].category);
// That means this will run JS .animate, not jQuery's:
bar.animate( ... );
如果您只是针对 jQuery 对象将其更改为 运行,它(几乎)会按预期工作:
var bar = $('#' + data[i].category);
bar.animate( ... );
我说差不多因为还有一个问题:
bar.id = data[i].category;
这会根据您的纯英文类别创建 HTML ID,其中包括空格,例如“Food and Dining”。 According to the spec:
id's value must not contain whitespace (spaces, tabs etc.).
至少在尝试使用带空格的 ID 作为 jQuery 选择器时,这很重要,但它不起作用。因此,我们只使用数组索引,它也保证是唯一的,带有前缀,这样我们就知道我们指的是什么:
bar.id = 'bar-' + i;
这是包含这 2 处更改的工作片段。
注意:最后一个 document.div.appendChild(graph);
抛出错误 - 也许这是一次调试尝试,没有必要,我已在此处注释掉它。
function barGraph(data) {
//Create graph
var graph = document.createElement("div");
graph.id = "barGraph";
//inserting bar graph before previous 'label' div
const target = document.querySelector('#labels');
target.parentNode.insertBefore(graph, labels);
//Styling for graph
graph.style.position = "relative";
graph.style.marginTop = "20px";
graph.style.height = "500px";
graph.style.backgroundColor = "Gainsboro";
graph.style.borderBottomStyle = "solid";
graph.style.borderBottomWidth = "1px";
graph.style.overflow = "hidden";
//Iterating through each bar
var position = 50;
var width = 75;
for (i = 0; i < data.length; i += 1) {
var spendData = data[i];
var bar = document.createElement("div");
//set a unique id for each of the bars
// UPDATED - category includes spaces, just use array index
// bar.id = data[i].category;
bar.id = 'bar-' + i;
//Styling for bar
bar.style.position = "absolute";
bar.style.left = position + "px";
bar.style.width = width + "px";
bar.style.backgroundColor = spendData.color;
bar.style.height = (spendData.amount) / 5 + "px";
bar.style.bottom = "0px";
bar.innerHTML = "$" + spendData.amount;
bar.style.fontSize = "11px";
bar.style.color = "Azure";
bar.style.fontWeight = "800";
bar.style.fontFamily = "Arial, Helvetica, sans-serif";
bar.style.textAlign = "center";
bar.style.padding = "1em";
//Appending to the graph
graph.appendChild(bar);
//Set bar width
position += (width * 2);
}
return graph;
}
window.onload = function() {
var data = [{
category: "Food and Dining",
amount: "2005.00",
color: "CadetBlue"
},
{
category: "Auto and Transport",
amount: "1471.31",
color: "CornflowerBlue"
},
{
category: "Shopping",
amount: "892.86",
color: "DarkCyan"
},
{
category: "Bills and Utilities",
amount: "531.60",
color: "DarkSeaGreen"
},
{
category: "Mortgage",
amount: "1646.00",
color: "LightSeaGreen"
},
{
category: "Entertainment",
amount: "179.52",
color: "YellowGreen"
}
];
document.getElementById("resetGraph").addEventListener("click", function() {
for (i = 0; i < data.length; i++) {
// UPDATED: 1. use new format ID without spaces
// UPDATED: 2. use jQuery selector/animation
// UPDATED: 3. use bar.length to test if selector matched anything
var bar = $('#bar-' + i);
if (bar.length) {
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000);
}
}
});
var graph = barGraph(data);
//document.div.appendChild(graph);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="labels"></div>
<button id="resetGraph">Reset graph</button>
那么您的原始代码中发生了什么?我不知道。 Javascript.animate()
是运行ning的原生,不是jQuery的。 Javascipt .animate()
method的第一个参数应该是:
Either an array of keyframe objects, or a keyframe object whose properties are arrays of values to iterate over.
您的代码传递的是一个对象,而不是数组,因此 .animate()
会期望后者,即“关键帧对象”。 Keyframe Formats 规范提供了更多细节和一些“关键帧对象”的示例:
element.animate({
opacity: [ 0, 1 ], // [ from, to ]
color: [ "#fff", "#000" ] // [ from, to ]
}, 2000);
您的对象不符合此格式 - 每个属性只是一个字符串,而不是 start/stop 值的数组。关键帧文档还描述了 Implicit to/from keyframes:
In newer browser versions, you are able to set a beginning or end state for an animation only (i.e. a single keyframe), and the browser will infer the other end of the animation if it is able to.
我猜这就是正在发生的事情,不知何故?浏览器正在推断起始值的隐式结束帧?
我尝试更新您的代码以使用正确的关键帧格式,因此您可以使用本机 .animate()
并一起跳过 jQuery,但它不起作用 - 条形重置为它们的动画后的原始高度,就像你原来的代码一样,我不知道为什么:
document.getElementById("resetGraph").addEventListener("click", function() {
var bar, startHeight;
for (i = 0; i < data.length; i++) {
bar = document.getElementById('bar-' + i);
if (bar) {
startHeight = window.getComputedStyle(bar).height;
bar.animate({
height: [startHeight, '0px'],
padding: ['1em', '0']
}, 2000);
}
}
});
Dom 的 animate() 函数将 return 一个 AnimationPlaybackEvent 对象。我们可以使用 onFinish 方法来重置 dom 元素的高度和宽度或者隐藏它。
您能否在 bar.animate() 函数后添加以下行到您的代码中。
.onfinish=function(e){
e.currentTarget.effect.target.style.visibility ="hidden"
};
喜欢下面的片段。
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000).onfinish=function(e){
e.currentTarget.effect.target.style.visibility ="hidden"
};
对 JS 完全陌生,jQuery 在这里。代码遍历每个条形,当您按下 Reset 按钮时,它应该将条形缩小为零。但是,我试图让这个条形图动画停止,但是一旦你按下按钮,它就会通过动画并再次重置回之前的位置。如有任何帮助,我们将不胜感激!
function barGraph(data) {
//Create graph
var graph = document.createElement("div");
graph.id = "barGraph";
//inserting bar graph before previous 'label' div
const target = document.querySelector('#labels');
target.parentNode.insertBefore(graph, labels);
//Styling for graph
graph.style.position = "relative";
graph.style.marginTop = "20px";
graph.style.height = "500px";
graph.style.backgroundColor = "Gainsboro";
graph.style.borderBottomStyle = "solid";
graph.style.borderBottomWidth = "1px";
graph.style.overflow = "hidden";
//Iterating through each bar
var position = 50;
var width = 75;
for (i = 0; i < data.length; i += 1) {
var spendData = data[i];
var bar = document.createElement("div");
//set a unique id for each of the bars
bar.id = data[i].category;
//Styling for bar
bar.style.position = "absolute";
bar.style.left = position + "px";
bar.style.width = width + "px";
bar.style.backgroundColor = spendData.color;
bar.style.height = (spendData.amount) / 5 + "px";
bar.style.bottom = "0px";
bar.innerHTML = "$" + spendData.amount;
bar.style.fontSize = "11px";
bar.style.color = "Azure";
bar.style.fontWeight = "800";
bar.style.fontFamily = "Arial, Helvetica, sans-serif";
bar.style.textAlign = "center";
bar.style.padding = "1em";
//Appending to the graph
graph.appendChild(bar);
//Set bar width
position += (width * 2);
}
return graph;
}
window.onload = function() {
var data = [{
category: "Food and Dining",
amount: "2005.00",
color: "CadetBlue"
},
{
category: "Auto and Transport",
amount: "1471.31",
color: "CornflowerBlue"
},
{
category: "Shopping",
amount: "892.86",
color: "DarkCyan"
},
{
category: "Bills and Utilities",
amount: "531.60",
color: "DarkSeaGreen"
},
{
category: "Mortgage",
amount: "1646.00",
color: "LightSeaGreen"
},
{
category: "Entertainment",
amount: "179.52",
color: "YellowGreen"
}
];
document.getElementById("resetGraph").addEventListener("click", function() {
for (i = 0; i < data.length; i++) {
var bar = document.getElementById(data[i].category);
if (bar) {
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000);
}
}
});
var graph = barGraph(data);
//document.div.appendChild(graph);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="labels"></div>
<button id="resetGraph">Reset graph</button>
<script src="js/spending-graph.js"></script>
已更新
有趣的问题! AFAICT 问题是你混淆了 jQuery's .animate()
with the native Javascript .animate()
.
你的问题被标记为 jQuery-animate,你明确地提到了它,你传递给 .animate()
的参数格式正是 jQuery 所期望的。
但是您的动画代码 运行ning 是针对 HTML DOM 元素,而不是 jQuery 元素:
// bar here is an HTML DOM Element, not a jQuery object:
var bar = document.getElementById(data[i].category);
// That means this will run JS .animate, not jQuery's:
bar.animate( ... );
如果您只是针对 jQuery 对象将其更改为 运行,它(几乎)会按预期工作:
var bar = $('#' + data[i].category);
bar.animate( ... );
我说差不多因为还有一个问题:
bar.id = data[i].category;
这会根据您的纯英文类别创建 HTML ID,其中包括空格,例如“Food and Dining”。 According to the spec:
id's value must not contain whitespace (spaces, tabs etc.).
至少在尝试使用带空格的 ID 作为 jQuery 选择器时,这很重要,但它不起作用。因此,我们只使用数组索引,它也保证是唯一的,带有前缀,这样我们就知道我们指的是什么:
bar.id = 'bar-' + i;
这是包含这 2 处更改的工作片段。
注意:最后一个 document.div.appendChild(graph);
抛出错误 - 也许这是一次调试尝试,没有必要,我已在此处注释掉它。
function barGraph(data) {
//Create graph
var graph = document.createElement("div");
graph.id = "barGraph";
//inserting bar graph before previous 'label' div
const target = document.querySelector('#labels');
target.parentNode.insertBefore(graph, labels);
//Styling for graph
graph.style.position = "relative";
graph.style.marginTop = "20px";
graph.style.height = "500px";
graph.style.backgroundColor = "Gainsboro";
graph.style.borderBottomStyle = "solid";
graph.style.borderBottomWidth = "1px";
graph.style.overflow = "hidden";
//Iterating through each bar
var position = 50;
var width = 75;
for (i = 0; i < data.length; i += 1) {
var spendData = data[i];
var bar = document.createElement("div");
//set a unique id for each of the bars
// UPDATED - category includes spaces, just use array index
// bar.id = data[i].category;
bar.id = 'bar-' + i;
//Styling for bar
bar.style.position = "absolute";
bar.style.left = position + "px";
bar.style.width = width + "px";
bar.style.backgroundColor = spendData.color;
bar.style.height = (spendData.amount) / 5 + "px";
bar.style.bottom = "0px";
bar.innerHTML = "$" + spendData.amount;
bar.style.fontSize = "11px";
bar.style.color = "Azure";
bar.style.fontWeight = "800";
bar.style.fontFamily = "Arial, Helvetica, sans-serif";
bar.style.textAlign = "center";
bar.style.padding = "1em";
//Appending to the graph
graph.appendChild(bar);
//Set bar width
position += (width * 2);
}
return graph;
}
window.onload = function() {
var data = [{
category: "Food and Dining",
amount: "2005.00",
color: "CadetBlue"
},
{
category: "Auto and Transport",
amount: "1471.31",
color: "CornflowerBlue"
},
{
category: "Shopping",
amount: "892.86",
color: "DarkCyan"
},
{
category: "Bills and Utilities",
amount: "531.60",
color: "DarkSeaGreen"
},
{
category: "Mortgage",
amount: "1646.00",
color: "LightSeaGreen"
},
{
category: "Entertainment",
amount: "179.52",
color: "YellowGreen"
}
];
document.getElementById("resetGraph").addEventListener("click", function() {
for (i = 0; i < data.length; i++) {
// UPDATED: 1. use new format ID without spaces
// UPDATED: 2. use jQuery selector/animation
// UPDATED: 3. use bar.length to test if selector matched anything
var bar = $('#bar-' + i);
if (bar.length) {
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000);
}
}
});
var graph = barGraph(data);
//document.div.appendChild(graph);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="labels"></div>
<button id="resetGraph">Reset graph</button>
那么您的原始代码中发生了什么?我不知道。 Javascript.animate()
是运行ning的原生,不是jQuery的。 Javascipt .animate()
method的第一个参数应该是:
Either an array of keyframe objects, or a keyframe object whose properties are arrays of values to iterate over.
您的代码传递的是一个对象,而不是数组,因此 .animate()
会期望后者,即“关键帧对象”。 Keyframe Formats 规范提供了更多细节和一些“关键帧对象”的示例:
element.animate({
opacity: [ 0, 1 ], // [ from, to ]
color: [ "#fff", "#000" ] // [ from, to ]
}, 2000);
您的对象不符合此格式 - 每个属性只是一个字符串,而不是 start/stop 值的数组。关键帧文档还描述了 Implicit to/from keyframes:
In newer browser versions, you are able to set a beginning or end state for an animation only (i.e. a single keyframe), and the browser will infer the other end of the animation if it is able to.
我猜这就是正在发生的事情,不知何故?浏览器正在推断起始值的隐式结束帧?
我尝试更新您的代码以使用正确的关键帧格式,因此您可以使用本机 .animate()
并一起跳过 jQuery,但它不起作用 - 条形重置为它们的动画后的原始高度,就像你原来的代码一样,我不知道为什么:
document.getElementById("resetGraph").addEventListener("click", function() {
var bar, startHeight;
for (i = 0; i < data.length; i++) {
bar = document.getElementById('bar-' + i);
if (bar) {
startHeight = window.getComputedStyle(bar).height;
bar.animate({
height: [startHeight, '0px'],
padding: ['1em', '0']
}, 2000);
}
}
});
Dom 的 animate() 函数将 return 一个 AnimationPlaybackEvent 对象。我们可以使用 onFinish 方法来重置 dom 元素的高度和宽度或者隐藏它。
您能否在 bar.animate() 函数后添加以下行到您的代码中。
.onfinish=function(e){
e.currentTarget.effect.target.style.visibility ="hidden"
};
喜欢下面的片段。
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000).onfinish=function(e){
e.currentTarget.effect.target.style.visibility ="hidden"
};