脚本从指令添加到 dom 不触发

Script added from directive into dom not firing

本文关键字:dom 指令 添加 脚本      更新时间:2023-09-26

>我创建了一个简单的指令,用于生成一个 svg 不确定微调器。包含在页面上的脚本效果很好。svg 和脚本完美生成。脚本不会触发。

我有生成的输出的这个庞然大物

<svg width="64" height="64" viewBox="0 0 64 64">
  <g transform="translate(32, 32)"> 
    <circle id="myId" 
      fill="none" 
      stroke="#000000" 
      opacity=".8" 
      stroke-width="5" 
      stroke-linecap="round" 
      stroke-miterlimit="10" 
      cx="0" cy="0" r="29.5"
      >
    </circle>
  </g>
</svg>
<script>
  var line = document.getElementById("myId");
  var initialTheta = 0;
  var thetaDelta = 1;
  myId.currentTheta = initialTheta;
  var requestAnimationFrameID = requestAnimationFrame(doCircAnim);
  function doCircAnim() {
    myId.setAttribute("transform", "rotate(" + myId.currentTheta + ")");
    myId.setAttribute("stroke-dasharray", myId.currentTheta);
    myId.currentTheta += thetaDelta;
    if(myId.currentTheta > 180){ myId.currentTheta = 0}
    requestAnimationFrameID = requestAnimationFrame(doCircAnim);
  }
</script>

演示正确的行为,它应该作为一个独立的元素工作 - 它确实如此。这是由与 plunk 无关的指令生成的,但它应该是相当不言自明的。动画脚本是从Microsoft的 svg 动画入门页面中提取的,因为它是所有必需的(进行了一些调整)。

我尝试了一大堆事情,要么没有成功,要么是新一批错误然后失败了。我相信这之前已经以某种方式回答过,所以如果有,请接受我的道歉,但我未能找到解决方案。

提前谢谢。

基于原始显示行为的新 plunk带选项的运行指令

(function(){
  'use strict';
  angular.module('loader', [])
  .directive('loader', ['$window', function($window){
    return {
      restrict: 'E',
      link: function (scope, element, attrs){
         ...
      }
    }
  }
})();

感谢Mark Keats的这个,以及这个董事会和我的同事的所有其他建议。

虽然脚本本质上没有任何问题,但 Angular 使用 jqLite 处理注入的方式是问题出现的地方,因为它被输入到 DOM 并且只是留在那里,因为它使用了无法运行脚本的 innerHTML 方法。

因此,从 DOM 中删除脚本是唯一的方法。令人高兴的是,由于您可以将原版 js 与棱角分明的东西一起使用而不会产生不良影响,因此将脚本移动到指令正文就可以了。加载程序的每个实例都有一个唯一的 ID,并且只有一个版本的脚本,因此它们都访问同一个版本 - 而不是每个实例有一个脚本。我已经更新了上面的 plunk 以反映这一点,以便永远不会有非工作版本。损坏的脚本仍在第一个引用的 plunk 中。

(function(){
  'use strict';
  angular.module('loader', [])
  .directive('loader', ['$window', function($window){
    var animationIndex = 0;
  return {
    restrict: 'E',
    link: function (scope, element, attrs){
      var shape = attrs.ccId;
      var type = attrs.ccType;
      var width = attrs.ccStrokeWidth || 6;
      var diameter = attrs.ccDiameter || 24;
      var stroke = attrs.ccStroke;
      var opacity = attrs.ccOpacity || 1/5;
      var elemWidth = element[0].clientWidth;
      var originOffset = (diameter === false)? 32 : diameter / 2;
      var radius = originOffset - ((width / 2) + 2);
      var reset = (type === 'line')? elemWidth : diameter * Math.PI;
      var animationTarget;
      var thetaDelta = 1;
      function doAnim() {
        if(type === 'circle') {
          animationTarget.setAttribute("transform", "rotate(" + animationTarget.currentTheta + ")");
          animationTarget.currentTheta += .1
        }
        else {animationTarget.currentTheta += .6}
        animationTarget.setAttribute("stroke-dasharray", animationTarget.currentTheta);
        animationTarget.currentTheta += thetaDelta
        if(animationTarget.currentTheta > reset){ animationTarget.currentTheta = 0}
        requestAnimationFrame(doAnim);
      }
      // <cc-loader cc-id="myId" cc-type="[circle,line]" cc-opacity="[default = .2]" cc-diameter="[int - circle type only]" cc-stroke="[# colour value]" cc-stroke-width="[default = 5]"></cc-loader>
      if (type == 'line') {
        element.html('<svg' +
          ' width="'+elemWidth+'" height="'+width+'" viewBox="0 0 '+elemWidth+' '+width+'">' +
            '<g transform="translate('+ -width * 2+', '+width / 2+')">' +
            '<line' +
              ' id="'+shape + animationIndex +'"' +
              ' fill="none"' + 
              ' stroke="'+stroke+'"' + 
              ' opacity="'+opacity+'"' +
              ' stroke-width="'+width+'"' + 
              ' stroke-linecap="round"' + 
              ' stroke-miterlimit="10"' + 
              ' x1="'+width+'"' + 
              ' y1="0"' + 
              ' x2="'+elemWidth+'"' + 
              ' y2="0"' +
              '>' +
            '</line>' +
            '</g>' +
          '</svg>');
        animationTarget = document.getElementById(shape+animationIndex);
        animationTarget.currentTheta = 0;
        doAnim();
        animationIndex++;
      }
      else if (type == 'circle') {
        element.html('<svg' +
          ' width="'+diameter+'" height="'+diameter+'" viewBox="0 0 '+diameter+' '+diameter+'">' +
            '<g transform="translate('+originOffset+', '+originOffset+')">' +
              ' <circle' +
              ' id="'+shape + animationIndex +'"' +
              ' fill="none"' +
              ' stroke="'+stroke+'"' +
              ' opacity="'+opacity+'"' +
              ' stroke-width="'+width+'"' +
              ' stroke-linecap="round"' +
              ' stroke-miterlimit="10"' +
              ' cx="0"' +
              ' cy="0"' +
              ' r="'+radius+'">' +
            '</circle>' +
          '</g>' +
        '</svg>');
        animationTarget = document.getElementById(shape+animationIndex);
        animationTarget.currentTheta = 0;
        doAnim();
        animationIndex++;
      }
      else {
        element.html('Types allowed for this element are ''line'' and ''circle''');
      }
    },
  };
}]);
})();

现在在GitHub上。如果您想让它变得更好,请随意播放并发送拉取请求