如何观察 DOM 的变化 AngularJS
How to watch the DOM for changes AngularJS
这似乎是一个愚蠢的问题,但我需要知道如何观察页面的整个 DOM,并在它更改时重新编译它。 从本质上讲,这就是 AngularJS 默认通过使用数据绑定所做的,但是每当 DOM 中的任何内容发生更改时,我都需要发生这种情况,而不仅仅是绑定。 原因是因为我有一个完全用HTML,Javascript和PHP构建的应用程序。 它是一个单页应用程序,它有一个主页,并将PHP注入到该页面内的DIV包装器中。
我想对它进行一些修改,但希望将我的代码与原始代码完全分开。 为此,我需要能够在注入具有自己的 DOM 结构的新 PHP 文件时重新编译 DOM。 到目前为止,我所拥有的似乎不起作用。
app.directive("watch", function () {
return function (scope, element, attr) {
scope.$watch("watch", function(oldValue, newValue) {
if(newValue) {
console.log("there is a new value");
console.log("the new value is " + newValue);
}
});
}
});
我将监视属性添加到 <body>
标签中,但它似乎不起作用,当 dom 更改时,不会记录任何内容。 最终我想用$compile替换控制台.log但我首先需要让手表工作。 有人可以指出我做错了什么吗?
这是个坏主意,但我会幽默你。
因此,正如我在上面的评论中所说,做你想做的事情是一个坏主意。 也就是说,如果你仍然想这样做,你可以通过将函数作为第一个参数传入来$watch
任何东西。
下面的代码将检查 <body>
标记中的 HTML 是否已更改。请注意,这是一个可怕的想法。
$scope.$watch(function () {
return document.body.innerHTML;
}, function(val) {
//TODO: write code here, slit wrists, etc. etc.
});
上面的手表将在 HTML 中的任何内容更改时触发。
- 当输入中的值更改时
- 当下拉列表中的选择更改时
- 当 HTML 中的任何元素中的属性发生更改时。
- 等。
附加信息:截至目前,在很多浏览器中,还没有一种很好的方法来监视已加载的新 DOM 元素。最好的方法仍然是在添加新的 DOM 元素时触发一些东西。
正如Steinway Wu所提到的,MutationObserver是必经之路。这是一个片段:
.directive('myDirective', function() {
return {
...
link: function(scope, element, attrs) {
var observer = new MutationObserver(function(mutations) {
// your code here ...
});
observer.observe(element[0], {
childList: true,
subtree: true
});
}
};
});
我创建了一个小型实用程序服务
这是代码
GenericService.js
我们有这个
angular.module('GenericServiceModule', [])
.factory('$utilsService', function () {
var utilService = {};
utilService.observeDomChange = function (domElement, doThisOnChange, observationOptions) {
var defaultOptions = {
// attributes: true, // attribute changes will be observed | on add/remove/change attributes
// attributeOldValue: true, // will show oldValue of attribute | on add/remove/change attributes | default: null
// we need this because in .find() sizzle modifies id temporarily, https://github.com/jquery/jquery/issues/2620
//attributeFilter: ['style'], // filter for attributes | array of attributes that should be observed, in this case only style
// characterData: true, // data changes will be observed | on add/remove/change characterData
// characterDataOldValue: true, // will show OldValue of characterData | on add/remove/change characterData | default: null
childList: true, // target childs will be observed | on add/remove
subtree: true // target childs will be observed | on attributes/characterData changes if they observed on target
};
var options = observationOptions || defaultOptions;
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(function anElementIWatchChanged(mutations) {
doThisOnChange();
});
// removing the dom element won't be triggered
observer.observe(domElement, options);
};
return utilService;
});
简单地说,你可以像这样使用它
$utilsService.observeDomChange($element[0], doSomething());
下面是一个用法示例
angular.module(
...
.directive('myCustomDirective', function ($utilsService) {
return {
restrict: 'A',
//...
controller: function ($scope, $element) {
//...
$scope.$on('$viewContentLoaded', function (event, viewName) {
$utilsService.observeDomChange($element[0], doSomething());
}
}
}
}
如此处所述(突变事件(,您可以为 DOM 突变事件添加侦听器,例如 DOMSubtreeModified
。
例如 element.addEventListener("DOMSubtreeModified", function (ev) {...}, false)
更新
实际上,他们建议使用突变观察者。
这是一个古老的话题,但是在尝试使用 ng-bind-html
从模型中动态检测填充 HTML 代码的元素内容的变化时,我遇到了类似的问题。
使用 jqLite 的data()
将一些自定义数据关联到 ng-bind-html
元素的子元素以检测内容是否被替换(因此自定义数据丢失(怎么样?
这将是一个directive
的代码,用于观察填充ng-bind-html
的元素的变化:
.directive("myOnDomContentChanges", function($window) {
var DATA_KEY_NAME = "myOnDomContentChangesKey";
return function(scope, element, attrs){
scope.$watch(function(){
var res = null;
var children = element.children();
if(children && children.length > 0){
var childData = children.data(DATA_KEY_NAME);
res = (typeof childData !== "undefined" ? childData : false );
}
return res;
}, function(watchData){
if(watchData === false){ //Only run when false
var children = element.children();
if(children && children.length > 0){
children.data(DATA_KEY_NAME, true); //Set custom data to true
}
//New HTML binding detected
//Write your code here
}
});
};
})
我希望它有所帮助。
欢迎评论。
拉法
- AngularJS:当过滤值发生变化时刷新DOM
- 如何在呈现页面后使用 Java 脚本检测 dom 元素值的值是否有任何变化(例如,任何输入或复选框值更改)
- Angular js-当值发生变化时高亮显示dom
- Angular2指令:如何检测DOM变化
- Angularjs 指令更新到 DOM 属性值的变化
- 如何观察 DOM 的变化 AngularJS
- 使用 mutationObserver 似乎无法跟踪 DOM 中不断变化的表
- 如何扫描成千上万的网站并分析每个网站的变化's JavaScript对页面的影响's DOM
- 当聚合物元素中的布尔属性发生变化时,如何用sort重新运行dom repeat
- 如何告诉elm外部DOM的变化
- 使用纯Javascript检测DOM元素的位置变化
- 当阵列发生变化时,Polymer 1.0 dom repeat未得到正确通知
- 影子dom脚本,以监视主机的变化
- 如何检测DOM元素的class属性何时发生变化
- 在angular 1.4.4中,为什么作用域变量的变化不需要$watch或$apply就能传播到DOM ?
- 仅当$scope数据发生变化时更新DOM
- dom-repeat中元素的聚合物变化不反映在父数组中
- 如何在没有jQuery的情况下检测DOM元素的变化
- DOM的变化并没有反映在文档的innerHTML中
- 当DOM动态变化时,如何处理带有' data-* '属性的JavaScript事件