差分进化变异算子_进化新的变异

差分进化变异算子

我曾经是DOM Mutation Events的忠实拥护者 。 它们为脚本提供了一种独特的方式来监视DOM中的更改,而与导致它们的事件或操作无关。 因此,诸如DOMNodeInsertedDOMAttrModified类的事件将分别响应节点的添加或属性更改而触发。

但是,如果您从未使用过突变事件,那真的就不足为奇了,因为在大多数情况下,是添加这些节点或更改那些属性的原因,为什么您首先需要对您引起的事件进行React性事件?

因此,它们通常用于解决库和框架中的问题,例如响应匿名闭包引起的更改。 对于许多浏览器扩展来说 ,它们也是一个库存,它们提供了检测文档何时更改的最简单,有时甚至是唯一的方法。

语法非常简单,就像其他事件一样:

element.addEventListener('DOMNodeInserted', function(e)
{
  console.log('Added ' + e.target.nodeName
    + ' to ' + element.nodeName);

}, false);

但是,这种简单性掩盖了一个潜在的问题-突变事件的实施不充分,并且使浏览器开发遇到性能和稳定性问题。 它们触发频率太高,它们缓慢且难以优化,并且它们是许多潜在崩溃错误的源头。

这就是为什么突变事件已被弃用大约两年的原因,并且名义上完全不允许Firefox附加组件包含它们。 实际上,当我去年发布Dust-Me Selectors的更新时,我必须获得特别许可才能继续使用它们!

请注意, DOMContentLoaded 不是突变事件,它只是具有类似的名称。 该事件不存在此类问题,因此不建议使用该事件。

你不能放下一个好主意

尽管存在这些问题,但突变事件的想法仍然是一个好主意 ,不久之后Mozilla和Google的开发人员提出了一项新提案 ,该提案很快就被DOM 4规范接受。

新的API称为MutationObserver ,它比突变事件复杂得多,但是这种复杂性大大提高了控制和精度。

这是一个简单的示例,它响应document.body节点的添加,并向控制台写入每个更改的摘要:

var watcher = new MutationObserver(function(mutations) 
{
  mutations.forEach(function(mutation)
  {
    for(var i = 0; i < mutation.addedNodes.length; i ++)
    {
      console.log('Added ' + mutation.addedNodes[i].nodeName + ' to ' + mutation.target.nodeName);
    }
  });
});

向观察者回调传递了一个对象,该对象包含有关突变的数据,其每个成员代表一个更改。 这与突变事件不同,后者会为每个更改单独触发回调!

每个突变对象中包含的数据取决于观察到的内容。 在这种情况下,我们仅关注目标元素的子项(由配置对象中的childList参数指定)的变化,因此,突变对象具有addedNodes属性,该属性是对每个添加节点的引用的集合。

这是该示例的演示,可在Firefox 14或更高版本以及Chrome 18或更高版本中运行

该演示有一个按钮,您可以单击该按钮以将新段落添加到页面,并且每次发生时,观察者都会做出响应。 当然,在实践中,您不会这样做-您只需要使用click事件来触发它是什么-但关键是观察者可以响应任何事物 (包括(尤其是)您没有的脚本) 引起的更改其他控制。

我敢肯定,您可以开始想象用户脚本和浏览器扩展的潜力,从而能够准确地响应DOM中的任何更改,无论它们是由脚本编写还是由直接的用户交互(例如,当用户输入到contentEditable区域)。

一些令人惊讶的可能性

现在,如果您查看Firefox中的演示,您会注意到该控制台已经显示了多个变化,甚至在您单击该按钮之前。 发生这种情况是因为观察者本身没有包装在DOMContentLoaded ,所以它在脚本执行后立即开始工作。 我偶然发现了这一点,这仅仅是因为我更愿意在可能的情况下使用这种方式编写脚本,并且我意识到这种突变是浏览器在<body>添加了节点,即在包含<script>之后的每个节点都添加了一个节点。

Chrome不会这样做-我只能怀疑它是故意阻止的-因为就我们对DOM脚本的工作方式而言,它非常有意义。 我们知道脚本是同步执行的,这就是为什么可以在完成渲染之前将其添加到<body>的原因。 因此,如果我们开始观察DOM的变化,即使该变化是由浏览器自己的呈现引起的,我们也应该获得此后发生的每个变化的通知。

这使我想到了几年前一个想法 ,即一个可以在文档加载和呈现过程中为几个不同点提供回调的库。 我从来没有提出过这个想法,因为它会遭受如此残酷的黑客攻击-但是使用变异观察者将是微不足道的。 我们要做的就是在主体的开头添加观察者,然后我们可以坐下来观察浏览器逐个节点绘制它!

签出(在Firefox 14或更高版本中):

每天都有更多可能性

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

但是实际上,大多数变异观察者并不需要那么广泛,事实上,他们的技巧和精确度是他们美丽的一部分。 浏览器不必报告每个微小的变化,只需要我们过滤数据以找到我们想要的内容(这对我们来说是乏味的,对浏览器来说效率很低)。 使用变异观察者,您只需要处理您所关心的事情,并且只要您需要了解的时间就可以。

这是另一个示例,它firstChild元素的文本(即元素的firstChild文本节点)的更改,然后在发生更改时立即停止监视:

(new MutationObserver(function(mutations, self) 
{
  mutations.forEach(function(mutation)
  {
    console.log('Changed text from "' + mutation.oldValue + '" to "' + mutation.target.nodeValue + '"');
  });

  self.disconnect();

})).observe(element.firstChild, { characterData : true, characterDataOldValue : true });

请注意,我在那里使用了稍微不同的语法-而不是将实例化保存到变量中,而是将其括在方括号中,因此我们可以将observe()命令直接链接到末尾。 在观察者内部,对实例本身的引用将传递给回调,然后我们可以使用该引用断开连接。

结论

这是对突变观察者的广泛介绍,相当详细地介绍了如何使用它们。 我什至没有提到Chrome的实现WebKitMutationObserver前缀(现在可以作为WebKitMutationObserver )的WebKitMutationObserver 。 但我想主要关注此新API的背景,并开始对各种可能性感到兴奋!

如果有需求,我将写一篇后续文章来详细研究它们,但现在,我建议您访问MDNMutationObserver文档Mozilla Hacks博客上还有另一篇好文章。

当我听到突变事件正在消失时,我感到非常震惊,因为还有什么可以做同样的工作? 事实证明,毕竟还有别的东西-而且要好一百倍!

翻译自: https://www.sitepoint.com/evolving-a-new-mutation/

差分进化变异算子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值