8

这似乎是一个愚蠢的问题,但我需要知道如何查看页面的整个 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 属性,<body>但它似乎不起作用,当 dom 更改时,没有任何记录。最终我想用 $compile 替换 console.log,但我首先需要让手表工作。有人可以指出我做错了什么吗?

4

5 回答 5

32

这是个坏主意,但我会取笑你。

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

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

$scope.$watch(function () {
   return document.body.innerHTML;
}, function(val) {
   //TODO: write code here, slit wrists, etc. etc.
});

只要HTML 中的任何内容发生更改,上面的手表就会触发。

  • 当输入中的值发生变化时
  • 当下拉列表中的选择发生变化时
  • 当 html 中任何元素的属性发生变化时。
  • 等等

附加信息:截至目前,在很多浏览器中,并没有真正好的方法来监视已加载的新 DOM 元素。最好的方法仍然是在添加新的 DOM 元素时触发某些东西。

于 2013-10-10T19:40:04.677 回答
11

正如 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
            });
        }
    };
});
于 2015-08-10T19:46:56.500 回答
2

我创建了一个小型实用程序服务

这是代码

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());
            }
        }
    }
}
于 2018-07-22T11:23:44.907 回答
0

如此处所述(突变事件),您可以为 DOM 突变事件添加侦听器,例如DOMSubtreeModified.

例如element.addEventListener("DOMSubtreeModified", function (ev) {...}, false)

更新

实际上,他们建议改用Mutation Observer

于 2014-06-19T17:09:11.183 回答
0

我知道这是一个老话题,但是当我尝试从使用ng-bind-html. 使用 jqLit​​e

将一些自定义数据关联到元素的子元素 以检测内容是否被替换(因此自定义数据丢失)怎么样? 这将是 a 的代码,用于观察用 填充的元素的变化:ng-bind-htmldata()

directiveng-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
            }
        });
    };
})

我希望它有所帮助。
欢迎评论。
  拉法

于 2014-09-02T12:51:30.500 回答