简体   繁体   English

按类而不是ID获取元素以影响多个项目(HTML画布图)

[英]Get element by class not ID to effect multiple items (HTML Canvas Graphs)

I'm using PHP to create a foreach loop for stats using HTML5 Canvas. 我正在使用PHP使用HTML5 Canvas为统计信息创建一个foreach循环。 Now everything is working great except the JavaSscript I found to create the Canvas Graph, it gets an element by id and so only manually targets one item, not sure how I can change up this code to target any amount of items created by the PhP foreach loop. 现在一切正常,除了我发现创建Canvas Graph的JavaSscript,它通过id获取一个元素,因此只能手动定位一个项目,不确定我如何更改此代码以定位由PhP foreach创建的任何数量的项目环。

Here is the JavaScript I found along with the HTML element (ignore the PhP variables in the data-attributes, they are returning data): 这是我与HTML元素一起找到的JavaScript(忽略数据属性中的PhP变量,它们正在返回数据):

 var el = document.getElementById('graph'); // get canvas //var el = document.getElementsByClassName("chart"); var options = { percent: el.getAttribute('data-percent') || 25, color: el.getAttribute('data-color') || 0, size: el.getAttribute('data-size') || 90, lineWidth: el.getAttribute('data-line') || 3, rotate: el.getAttribute('data-rotate') || 0 } var canvas = document.createElement('canvas'); var span = document.createElement('span'); span.textContent = options.percent + '%'; if (typeof(G_vmlCanvasManager) !== 'undefined') { G_vmlCanvasManager.initElement(canvas); } var ctx = canvas.getContext('2d'); canvas.width = canvas.height = options.size; el.appendChild(span); el.appendChild(canvas); ctx.translate(options.size / 2, options.size / 2); // change center ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); // rotate -90 deg //imd = ctx.getImageData(0, 0, 240, 240); var radius = (options.size - options.lineWidth) / 2; var drawCircle = function(color, lineWidth, percent) { percent = Math.min(Math.max(0, percent || 1), 1); ctx.beginPath(); ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false); ctx.strokeStyle = color; ctx.lineCap = 'round'; // butt, round or square ctx.lineWidth = lineWidth ctx.stroke(); }; drawCircle('#eeeeee', 1, 100 / 100); drawCircle(options.color, options.lineWidth, options.percent / 100); 
 <div class="chart" id="graph" data-percent="<?php echo $percentage; ?>" data-color="<?php echo $color; ?>" style="color: <?php echo $color; ?>;"></div> 

using get element by class name returns an error: Uncaught TypeError: el.getAttribute is not a function 通过类名称使用get元素将返回错误:未捕获的TypeError:el.getAttribute不是函数

Ok, so getElementsByClassName returns a NodeList object. 好的,所以getElementsByClassName返回一个NodeList对象。 What you need to do is turn it into an array and loop over all it's elements and execute your code for each of them. 您需要做的是将其转换为数组,并遍历所有元素,并对每个元素执行代码。 Here is a minimally-changed version of how your code should work: 这是代码工作方式的最小变化版本:

 // Get all the elements with 'chart' class as a NodeList object var elements = document.getElementsByClassName("chart"); // Turn the NodeList into an array elements = Array.prototype.slice.call(elements); // Loop over all the elements elements.forEach(function (el) { var options = { percent: el.getAttribute('data-percent') || 25, color: el.getAttribute('data-color') || 0, size: el.getAttribute('data-size') || 90, lineWidth: el.getAttribute('data-line') || 3, rotate: el.getAttribute('data-rotate') || 0 } var canvas = document.createElement('canvas'); var span = document.createElement('span'); span.textContent = options.percent + '%'; if (typeof(G_vmlCanvasManager) !== 'undefined') { G_vmlCanvasManager.initElement(canvas); } var ctx = canvas.getContext('2d'); canvas.width = canvas.height = options.size; el.appendChild(span); el.appendChild(canvas); ctx.translate(options.size / 2, options.size / 2); // change center ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); // rotate -90 deg //imd = ctx.getImageData(0, 0, 240, 240); var radius = (options.size - options.lineWidth) / 2; var drawCircle = function(color, lineWidth, percent) { percent = Math.min(Math.max(0, percent || 1), 1); ctx.beginPath(); ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false); ctx.strokeStyle = color; ctx.lineCap = 'round'; // butt, round or square ctx.lineWidth = lineWidth ctx.stroke(); }; drawCircle('#eeeeee', 1, 100 / 100); drawCircle(options.color, options.lineWidth, options.percent / 100); }); 
 <div class="chart" data-percent="100" data-color="red" style="color: red;"></div> <div class="chart" data-percent="30" data-color="red" style="color: red;"></div> 

However, this code should definitely be refactored. 但是,此代码绝对应该重构。 For instance, there is no point in declaring drawCircle function on every iteration. 例如,在每次迭代中声明drawCircle函数都没drawCircle

Also read up on getElementByClassName , and forEach . 另请阅读getElementByClassNameforEach

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM