Javascript 如何查看DOM中的更改AngularJS

Javascript 如何查看DOM中的更改AngularJS,javascript,dom,angularjs,Javascript,Dom,Angularjs,这似乎是一个愚蠢的问题,但我需要知道如何查看页面的整个DOM,并在页面发生变化时重新编译它。本质上这就是AngularJS默认使用数据绑定所做的,但我需要在DOM中的任何内容发生更改时,而不仅仅是绑定发生更改。原因是我有一个完全用HTML、Javascript和PHP构建的应用程序。它是一个单页应用程序,它有一个主页,并将PHP注入该页面内的DIV包装器中 我想对它做一些修改,但我想让我的代码与原始代码完全分离。要做到这一点,我需要能够在任何时候注入具有自己DOM结构的新PHP文件时重新编译DO

这似乎是一个愚蠢的问题,但我需要知道如何查看页面的整个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);
             }
         });
     }
});
我将watch属性添加到
标记中,但它似乎不起作用,当dom更改时,不会记录任何内容。最后,我想用$compile替换console.log,但我首先需要让手表正常工作。有人能指出我做错了什么吗

这是个坏主意,但我会逗你的。 所以,正如我在上面的评论中所说的,做你想做的事情是个坏主意。也就是说,如果您仍然想这样做,您可以通过将函数作为第一个参数传入来
$watch
几乎任何东西

下面的代码将检查
标记内的HTML是否已更改。请注意,这是一个可怕的想法

$scope.$watch(函数(){
返回document.body.innerHTML;
},功能(val){
//TODO:在这里写代码,割腕等等。
});
上面的手表会在HTML中的任何内容发生变化时触发

  • 当输入中的值发生变化时
  • 当下拉列表中的选择更改时
  • 当属性在html中的任何元素中发生更改时
  • 等等
其他信息:目前,在很多浏览器中,没有一种好的方法来监视已加载的新DOM元素。最好的方法仍然是在添加新的DOM元素时触发某些事件。

如前所述,您可以为DOM突变事件添加侦听器,如
domsubtreemeding

e、 g.
element.addEventListener(“domsubtreemedited”,函数(ev){…},false)

更新


实际上,他们建议改为使用。

我知道这是一个老话题,但我在尝试使用
ng bind HTML从模型中动态检测填充HTML代码的元素内容的更改时遇到了类似的问题
如何使用jqLite将一些自定义数据关联到
ng bind html
元素的子元素,以检测内容是否被替换(因此自定义数据丢失)?。

这将是
指令
的代码,用于观察填充了
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
            }
        });
    };
})
我希望有帮助。
欢迎评论。

拉法

正如吴斯坦威所提到的,变异观察者是一条路要走。以下是一个片段:

.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());
            }
        }
    }
}

这似乎是一个非常糟糕的设计。为什么不使用
ng inlude
或routing加载PHP并将其放入div?我没有构建原始应用程序,如果我这样做了,我会这样做。事实上,我只是想对已经存在的内容进行一些更改。当然,您可以在原始应用程序的标签中添加一个ng app=“myModule”?我感谢您的幽默,我确实希望以正确的方式这样做。例如,我可以使用ng include portal.php,问题是我不知道如何在不重写整个内容的情况下正确地执行此操作。我正在处理的应用程序是一个集群,我真的不知道有什么更好的方法。我想如果我知道更多关于为什么需要这样做的细节,我可以给你一个不那么刺耳的答案。哈哈。
到目前为止,在几乎所有浏览器中,都没有一种很好的方法来监视已加载的新DOM元素。
-那么
MutationObserver呢?除了IE,它有相当好的支持,我可以看出这将是一个多么糟糕的想法。我需要找到一种不同的方法。这对于最后的调试很好。