草庐IT

事件委托

大笨熊 2023-03-28 原文

什么是事件委托:

通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的。

原理: 利用冒泡的原理,把事件加到父级上,触发执行效果。 

例如:要点击删除 ul 下的 li ,一般是都要给每个小li 绑定点击事件,然后再进行判断是否删除。代码如下: 

  <body>
    <input type="text" />

    <ul>
      <li>苹果</li>
      <li>香蕉</li>
      <li>鸭梨</li>
    </ul>

    <script>
      
    let ulList =document.querySelector("ul")
    let liList=document.querySelectorAll("li")
    for(let i=0;i<liList.length;i++){
      liList[i].onclick=function(){
        ulList.removeChild(this)
      }
    } 
    </script>

利用 事件委托删除:(js部分)

      let ul = document.querySelector('ul')
      ul.addEventListener('click', function (e) {
        ul.removeChild(e.target)
      })

则只需 给小 li 的亲父级绑定一个点击事件,利用冒泡,来进行删除。 

 

DOM事件流(event flow )存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。

事件捕获(event capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件。

事件冒泡(dubbed bubbling):与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点。就像水里的泡泡一样,从最里面一直冒到最外面。

无论是事件捕获还是事件冒泡,它们都有一个共同的行为,就是事件传播,就很像多诺米骨牌一样。只要就一个倒了,那么后面就会产生连锁反应。

阻止事件冒泡:

①e.stopPropagation()

在点击事件中 添加  e.stopPropagation() 。 即可阻止冒泡

主要代码如下:

<style>
    .big{
      width: 500px;
      height: 500px;
      background-color: red;
    }
    .center{
      width: 300px;
      height: 300px;
      background-color: green;
    }
    .small{
      width: 150px;
      height: 150px;
      background-color: blueviolet;
    }
  </style>
</head>
<body>
  <div class="big">
    <div class="center">
      <div class="small"></div>
    </div>
  </div>

  <script>
    let big =document.querySelector('.big')
    let center =document.querySelector('.center')
    let small =document.querySelector('.small')

    big.addEventListener('click',function(e){
      console.log(e.target);
      console.log(this);
      console.log("我是big");
    })
    center.addEventListener('click',function(e){
      console.log("我是center");
      e.stopPropagation()

    })
    small.addEventListener('click',function(e){
      console.log("我是small");
    })
  </script>
</body>

②window.event.cancelBubble = true (谷歌,IE8兼容,火狐不支持)

其它代码与①一致,只展示修改部分:

    center.addEventListener('click',function(e){
      console.log("我是center");
      window.event.cancelBubble = true  //(谷歌,IE8兼容,火狐不支持)
    })

③合并取消:return false

在javascript的return false只会阻止默认行为,而是用jQuery的话则既阻止默认行为又防止对象冒泡。

如有错误,欢迎指正!!!

有关事件委托的更多相关文章

  1. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  2. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  3. ruby-on-rails - 事件管理员和自定义方法 - 2

    这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

  4. ruby-on-rails - 在不重新查询数据库的情况下重新排序 Rails 中的事件记录? - 2

    例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果

  5. ruby-on-rails - Ruby 长时间运行的进程对队列事件使用react - 2

    我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby​​脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几

  6. ruby - 将属性方法委托(delegate)给父对象 - 2

    我有以下类(class):classAlphabetattr_reader:letter_freqs,:statistic_letterdefinitialize(lang)@lang=langcaselangwhen:en@alphabet=('A'..'Z').to_a@letter_freqs={...}when:ru@alphabet=('А'..'Я').to_a.insert(6,'Ё')@letter_freqs={...}...end@statistic_letter=@letter_freqs.max_by{|k,v|v}[0]endendfoo=Alphabet.n

  7. ruby-on-rails - 使用 Rails 事件记录获取二级模型 - 2

    我有一个帖子属于城市的关系,城市又属于一个州,例如:classPost现在我想找到所有帖子及其所属的城市和州。我编写了以下查询来获取带有城市的帖子,但不知道如何在同一查找器中获取带有城市的相应州:@post=Post.find:all,:include=>[:city]感谢任何帮助。谢谢。 最佳答案 Post.all(:include=>{:city=>:state}) 关于ruby-on-rails-使用Rails事件记录获取二级模型,我们在StackOverflow上找到一个类似的问

  8. ruby - 在没有数据库的情况下伪造一个事件记录模型 - 2

    我觉得我错过了什么。我正在编写一个ruby​​gem,它允许与事件记录进行交互,作为其主要功能的附加功能。在为其编写测试用例时,我需要能够指定虚拟事件记录模型来测试此功能。如果我可以获得一个事件记录模型的实例,它不需要与数据库的任何连接,可以有关系,所有这些东西,但不需要我在数据库中设置表,那就太棒了。我对测试还很陌生,在Rails测试之外我也很陌生,但似乎我应该能够相当轻松地完成类似的事情,但我什么也没找到。谁能告诉我我错过了什么?我看过工厂、制造商、固定装置,所有这些似乎都想达到目标。人们如何在您只需要AR对象进行测试的地方测试gem? 最佳答案

  9. ruby-on-rails - 在事件记录库中添加某些方法的首选方法是什么? - 2

    我想创建一个模块,为从事件记录库继承的类提供一些通用方法。以下是我们可以实现的两种方式。1)moduleCommentabledefself.extended(base)base.class_evaldoincludeInstanceMethodsextendClassMethodsendendmoduleClassMethodsdeftest_commentable_classmethodputs'testclassmethod'endendmoduleInstanceMethodsdeftest_commentable_instance_methodputs'testinstanc

  10. sql - 如何查询具有 3 个标签的事件? - 2

    我有以下模型:activity.rbtag.rbtagging.rb标签是事件和标签的连接模型。我想搜索具有2个或更多标签的事件。我如何在Rails中执行此操作?例如:我有tag1=Christmas,tag2=Florida,tag3=John如果存在,我想找到tag1、tag2和tag3存在的Activity。[编辑]我最终做了什么:tags=[tag1,tag2,tag3]activities=[]tags.eachdo|tag|activities如果任何组值的大小等于tags.size,则该事件包含所有标签。 最佳答案 如

随机推荐