【问题标题】:Uncaught TypeError: Cannot read property 'setAttribute' of null未捕获的类型错误:无法读取 null 的属性“setAttribute”
【发布时间】:2017-12-18 15:23:37
【问题描述】:

因为我是菜鸟,所以还在学习 JS,所以请多多包涵。

我有一个带有 2 个圆形 SVG 仪表的网络应用程序,目前可以使用,我在用户登录之前收到了这个问题。

我的问题:我明白了 “未捕获的类型错误:无法读取 null 的属性‘setAttribute’”像疯了一样触发 对于控制台中的pathElementTwo.setAttribute('d', describeArc(26, 0, arcTwo));,因为该特定弧只需要在用户登录时加载的区域。这只会在登录前在控制台中疯狂地触发,登录后它会消失。

如何解决此问题,以使控制台不会在用户登录之前疯狂启动?

非常感谢任何帮助。谢谢!

JS

function describeArc(radius, startAngle, endAngle) {
    // Helper function, used to convert the (startAngle, endAngle) arc
    // dexcription into cartesian coordinates that are used for the
    // SVG arc descriptor.
    function polarToCartesian(radius, angle) {
        return {
            x: radius * Math.cos(angle),
            y: radius * Math.sin(angle),
        };
    }

    // Generate cartesian coordinates for the start and end of the arc.
    var start = polarToCartesian(radius, endAngle);
    var end = polarToCartesian(radius, startAngle);

    // Determine if we're drawing an arc that's larger than a 1/2 circle.
    var largeArcFlag = endAngle - startAngle <= Math.PI ? 0 : 1;

    // Generate the SVG arc descriptor.
    var d = [
        'M', start.x, start.y,
        'A', radius, radius, 1, largeArcFlag, 0, end.x, end.y
    ].join(' ');    

    return d;
}

var arc = 0;
var arcTwo = 0;

setInterval(function() {
    // Update the ticker progress.
    arc += Math.PI / 1000;
    arcTwo += Math.PI / 1000;

    if (arc >= 2 * Math.PI) { arc = 0; }
    if (arcTwo >= 2 * Math.PI) { arcTwo = 0; }


    // Update the SVG arc descriptor.
    var pathElement = document.getElementById('arc-path');
    var pathElementTwo = document.getElementById('arc-path-two');

    pathElement.setAttribute('d', describeArc(26, 0, arc));
   pathElementTwo.setAttribute('d', describeArc(26, 0, arcTwo));

    }, 400 / 0)

HTML

<div class="ticker-body">
                <svg viewBox="19, -19 65 35" class="gauge-background" 
fill="none">
                    <circle r="10"/>
                </svg>

                <svg viewBox="-39, -39 700 75" class="gauge" fill="none">
                    <path id="arc-path" transform="rotate(-90)" stroke-
linecap="circle" />
                </svg>
                </div>
                <div class="overlay-collect"></div>
                <div class="hot-offer-btn"></div>

<div class="ticker-body-two">
                        <svg viewBox="4, -19 65 35" class="gauge-background-
two" fill="none">
                            <circle r="10"/>
                        </svg>

                        <svg viewBox="-51, -34 450 75" class="gauge-two" 
fill="none">
                            <path id="arc-path-two" transform="rotate(-90)" 
stroke-linecap="circle" />
                        </svg>
                        </div>

【问题讨论】:

  • 该错误意味着getElementById 没有返回对象。你能发布你的html吗? setInterval 上的第二个参数可能不应该是除以 0
  • 请分享html
  • 问问自己为什么pathElementTwo 还不存在。你在等到 DOM 准备好了吗?如果是外部 SVG,您是否在等待它加载后再尝试访问其 DOM?
  • @PaulLeBeau LeBeau 我需要 pathElementTwo 仅在用户登录后才启动,而不是在登录前启动。这是我的问题。该区域在登录前位于隐藏的 div 中。我该如何解决这个问题?

标签: javascript jquery svg


【解决方案1】:

基本上,如果你还没有准备好,你只需要添加一些东西来使构建短路。

使用您拥有的代码的一种简单方法是仅使用 return 如果 !pathElement

setInterval(function() {
  // Update the SVG arc descriptor.
  var pathElement = document.getElementById('arc-path');
  var pathElementTwo = document.getElementById('arc-path-two');

  if (!pathElement || !pathElementTwo) {
    return; // don't do the rest
  }

  // Update the ticker progress.
  arc += Math.PI / 1000;
  arcTwo += Math.PI / 1000;

  if (arc >= 2 * Math.PI) { arc = 0; }
  if (arcTwo >= 2 * Math.PI) { arcTwo = 0; }

  pathElement.setAttribute('d', describeArc(26, 0, arc));
  pathElementTwo.setAttribute('d', describeArc(26, 0, arcTwo));
}, 400 / 0)

现在,如果pathElementpathElementTwonull,它就会退出函数并停止执行操作。

出于两个原因,我还将变量拉到函数的顶部。

首先,为了便于阅读和避免潜在错误,在顶部声明作用域的所有变量是一种很好的约定。

另一个原因,尤其是在这种情况下,是为了让您可以尽早跳出。如果我们无法对它做任何事情,则无需进行其他数学运算。

【讨论】:

  • 谢谢!您的解决方案有效,但是我需要 'pathElement.setAttribute('d', describeArc(26, 0, arc));'在登录前运行。我怎样才能做到这一点?
  • 'pathElement.setAttribute('d', describeArc(26, 0, arc));'是用户登录前第一个 svg gauge 需要运行的地方。我现在如何让特定的弧线运行而不会在控制台中发疯?
  • if (pathElementTwo == null) 解决了我的问题!谢谢!
  • 废话.. 我的窗口被缓存了,看起来好像不起作用:/
猜你喜欢
  • 2021-11-18
  • 2018-12-03
  • 1970-01-01
  • 2022-01-19
  • 2021-12-01
  • 2022-07-02
  • 2022-06-14
  • 2022-10-23
相关资源
最近更新 更多