AngularJS获取getElementById()不起作用及HTML与controller加载顺序问题

本文探讨了AngularJS项目中富文本插件加载失败的问题,详细介绍了使用$timeout延时处理和通过directive监听两种解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AngularJS项目需要引入富文本插件,富文本插件需要获取HTMLdom的id进行富文本插件初始化,所以最开始采用getElementById()方法想要获取id,但是console报出获取不到id,写法如下:

define(["app", "wangEditor"], function (app, E) {
    app.controller("savingEdit", ["$scope", "$rootScope",'$timeout',
        function ($scope, $rootScope,$timeout) {
            //富文本编辑器,引入wangEditor组建,并初始化
            var editeditor;
            $scope.myEditorClick = function () {
                //初始化E
                editeditor = new E(document.getElementById("myEditEditor"));
                //渲染富文本编辑器
                editeditor.create();
            }
            $scope.myEditorClick();
        }
    ]);
});

<div id="myEditEditor"></div>

上面这种写法会报myEditEditor为空id。

经过分析,我推测是因为AngularJS在加载controller时,对应的HTML文件并没有加载完成,他们可能是同时加载的。在网上搜索了很多办法,最后我总结出如下两种办法实现id的正常获取:

1.$timeout延时处理

这个办法显而易见,既然直接加载获取不到,那就价格延时,等html加载了在执行js渲染。代码如下:

define(["app", "wangEditor"], function (app, E) {
    app.controller("savingEdit", ["$scope", "$rootScope",'$timeout',
        function ($scope, $rootScope,$timeout) {
            //富文本编辑器,引入wangEditor组建,并初始化
            var editeditor;
            $scope.myEditorClick = function () {
                //初始化E
                editeditor = new E(document.getElementById("myEditEditor"));
                //渲染富文本编辑器
                editeditor.create();
            }
            $timeout(function () {
                $scope.myEditorClick();
            },300);
        }
    ]);
});

<div id="myEditEditor"></div>

2.通过directive监听html文本是否渲染完成

大家一般是监听ng-repeat是否渲染完最后一条来监听,你也可以监听其他html是否渲染完成。以ng-repeat为例,代码如下:

app.directive('repeatFinish',function(){
    return {
        link: function(scope,element,attr){
            console.log(scope.$index)
            if(scope.$last == true){
                scope.$eval( attr.repeatFinish )
            }
        }
    }
})

<div id="box">
    <span ng-repeat="item in data" repeat-finish="renderFinish()">{{item.str}}</span>
</div>



### 无法通过 `getElementById` 方法获取元素的原因 #### 原因分析 1. **目标元素尚未加载完成** 如果尝试调用 `getElementById` 的时机早于目标元素被浏览器渲染的时间,则会导致找不到对应的 DOM 节点。这是因为 JavaScript 执行时,DOM 尚未完全构建完毕[^1]。 2. **动态生成的内容未注册到 DOM 中** 对于通过 AJAX 或其他异步方式动态附加至页面的 HTML 节点,即使这些节点已经存在于内存中,但如果它们还未挂载到文档对象模型 (DOM),则也无法通过 `getElementById` 访问。 3. **重复 ID 导致冲突** 若同一页面中有多个拥有相同 ID 的元素,这违反了 HTML 标准规定(ID 应当全局唯一),从而可能导致不可预测的行为,甚至某些情况下根本无法正常选取任何一项作为匹配结果。 4. **脚本执行位置不当** 当 `<script>` 标签位于 HTML 文档顶部而非底部或者没有采用适当的延迟策略(如 window.onload 或者DOMContentLoaded事件监听器),可能会因为上述原因提前运行而导致失败情形发生[^3]. --- ### 解决方案 #### 方案一:确保脚本在 DOM 加载完成后执行 可以通过等待整个网页结构加载结束再启动相关逻辑处理过程来规避此风险。例如利用 `window.onload` 或更轻量级的 `DOMContentLoaded` 事件: ```javascript document.addEventListener("DOMContentLoaded", function() { var elem = document.getElementById("exampleId"); }); ``` 这种方式可以有效防止由于过早查询引发的问题。 #### 方案二:检查并修正潜在的多重 ID 使用情况 遍历当前文档内的所有节点列表,并打印出那些不符合标准设定条件下的实例以便后续调整优化: ```javascript var allElements = document.querySelectorAll("[id]"); allElements.forEach(function(element){ console.log(`Element with id=${element.id} found`); }); // 这里可以根据实际需求进一步筛选重复项进行修改操作 ``` 同时也要注意,在开发阶段就应该遵循最佳实践原则——即保证每一个组件都具备独一无二的身份标识符(ID)。 #### 方案三:改用更加灵活的选择机制 如果单纯依赖单一属性难以精确定位某个特定控件的话,考虑组合运用多种特征参数共同构成复合型路径表达式不失为一种明智之举。就像 Selenium 提供的功能那样,允许基于多维度约束缩小范围直至锁定最终目标为止[^2]: ```xpath find_element_by_xpath("//input[@id='kw' and @class='su']/span/input") ``` 虽然这是针对 WebDriver API 编写测试代码的例子,但对于纯前端项目同样适用类似的思路转换成 CSS Selectors 形式的语法即可实现相似效果。 #### 方案四:确认资源文件正确引入顺序 最后别忘了核实外部 JS 文件是否按照预期先后次序加载成功以及是否存在网络请求异常等情况干扰正常使用流程。 --- ### 总结 综上所述,未能借助 `getElementById` 成功检索指定实体的主要诱因大致可分为几类:一是时间节点把握不准;二是数据源本身存在问题比如含有冗余记录或是缺失必要字段等;三是编程手法不够严谨致使程序健壮性下降。因此建议开发者们平时养成良好习惯的同时还要不断积累经验教训以提高解决问题的能力效率。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值