Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 重写jQuery';s.on(';mouseenter';)转换为纯JS变体_Javascript_Jquery - Fatal编程技术网

Javascript 重写jQuery';s.on(';mouseenter';)转换为纯JS变体

Javascript 重写jQuery';s.on(';mouseenter';)转换为纯JS变体,javascript,jquery,Javascript,Jquery,我有一个包含其他div元素的容器div: <div id="container"> <div class="child"></div> <div class="child"></div> <div class="child"></div> </div> 也就是说,我如何才能监听鼠标悬停在哪个子鼠标上以应用于它myFunction?我尝试了以下方法,但这仅适用于容器div的myFuncti

我有一个包含其他div元素的容器div:

<div id="container">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
也就是说,我如何才能监听鼠标悬停在哪个子鼠标上以应用于它
myFunction
?我尝试了以下方法,但这仅适用于容器div的
myFunction

container.addEventListener('mouseenter',函数(事件){
让hoveredElement=event.target;
if(hoveredElement.tagName==='DIV'){
myFunction(hoveredElement);
}
});
#容器{宽度:200px;}
#容器>div{高度:100px;背景色:红色;}

您需要从
e.target
开始,遍历祖先,调用找到的每个
div
上的处理程序。当到达绑定元素时,停止遍历祖先

同时将事件类型更改为
mouseover
,因为
mouseenter
不会冒泡,因此
事件。target
始终是绑定元素

const container=document.querySelector(“容器”);
container.addEventListener('mouseover',函数(事件){
设el=event.target;
做{
如果(el.tagName==='DIV'){
myFunction.call(el,event);
}
}而((el=el.parentNode)!==this);
});
函数myFunction(事件){
console.log(this.id);
}

将鼠标悬停以调用该函数

这一个不能调用


我在Chrome上调试了jQuery,而jQuery
mouseenter
事件实际上在引擎盖下使用了一个
mouseover
事件。

在jQuery源代码第4095行中,有一行在每次触发事件时运行:

jQuery.event.dispatch.apply(元素、参数)

如果您在那里暂停并检查
参数
,您会发现它是一个类型为
mouseover
的MouseEvent

这是有意义的,因为您正在使用jQuery的委托事件处理程序语法,而且jQuery非常聪明,可以用
mouseover
替换
mouseenter

因此,您的解决方案本质上就是要做jQuery正在做的事情——使用
mouseover

container.addEventListener('mouseover',函数(事件){
log(“鼠标越过目标”,event.target);
log(“mouseover currentTarget”,event.currentTarget);
});
container.addEventListener('mouseenter',函数(事件){
log(“mouseenter目标”,event.target);
log(“mouseenter currentTarget”,event.currentTarget);
});
$('#container').on('mouseenter','.child',函数(事件){
log('jquery mouseenter target',event.target);
log('jquery mouseenter currentTarget',event.currentTarget);
log('jquery mouseenter delegateTarget',event.delegateTarget);
});
.child{
边框:1px实心#007;
高度:50px;
}

您尝试的是一种称为事件委派的实践。考虑到目前JavaScript的状态,这很容易做到。为了复制您习惯的JavaScript语法,我创建了一个可返回的对象来使用

使用
$get(query)
获取要对其执行委派的元素。在那里,您可以使用
on
方法和参数
(事件、子元素查询、函数)

当您为
方法上的
编写函数时,通常会向它传递
事件
参数,但下一个参数将是元素的索引,在本例中,鼠标悬停

参数没有安全防护措施,因为这不是问题的一部分,只需一点润滑脂即可轻松解决:)

let$get=(查询)=>{
if(document.querySelector(查询)){
设returnableObj={
元素:document.querySelector(查询),
名单(q){
返回数组.from(this.ele.queryselectoral(q))
},
获取索引(ele){
返回函数(q){
让我们创建索引;
returnableObj.list(q.filter)(itm,ind)=>{
设bool=ele.isSameNode(itm);
如果(bool)foundIndex=ind;
返回布尔;
});
返回foundIndex>=0?foundIndex:false;
}
}
}
returnableObj.on=函数(evt、childquery、fn){
此.ele.addEventListener(evt,函数(e){
if(e.target.matches(childquery)){
让myIndex=returnableObj.getIndex(e.target)(childquery);
fn(e,myIndex);
}
});
}
返回可返回的OBJ;
}else警报(“无效查询”);
}
设ele=$get(“#mydiv”);
ele.on(“mouseover”,“.child”,函数(e,ind){
警报(‘花生酱!孩子’+(ind+1));
})
h1、h2、h3{
宽度:200px;
}

你好
我想要一些糖果吗?
孩子2我选择你,神龙
儿童3,记分牌

@KevinB你说得对。这不是复制粘贴错误,而是书写错误。div有一个
id=“container”
它可以工作!但老实说,我不明白我的函数中的
this
如何知道引用子
div
,而不将
this
作为输入。@Liliane:我使用
.call()
调用了
myFunction
,可以手动设置
this
的值。因此我将
el
作为第一个参数传递给
.call()
,在
myFunction
中将其设置为
this
,并将
event
作为第二个参数传递给
.call()
,并将其作为
myFunction
中的第一个参数传递,如果我将
mouseenter
更改为
mouseover
,则我的初始解决方案有效。然后,不需要do/while和
.call()
@Liliane:是的,如果您想在
mouseenter
上模拟jQuery的委托,您确实需要循环。在里面
$('#container').on('mouseenter', 'div', myFunction)
let $get = (query) => {
  if (document.querySelector(query)) {
    let returnableObj = {
      ele: document.querySelector(query),
      list(q) {
        return Array.from(this.ele.querySelectorAll(q))
      },
      getIndex(ele) {
        return function(q) {
          let foundIndex;
          returnableObj.list(q).filter((itm, ind) => {
            let bool = ele.isSameNode(itm);
            if (bool) foundIndex = ind;
            return bool;
          });
          return foundIndex >= 0 ? foundIndex : false;
        }
      }
    }
    returnableObj.on = function(evt, childquery, fn) {
      this.ele.addEventListener(evt, function(e) {
        if (e.target.matches(childquery)) {
          let myIndex = returnableObj.getIndex(e.target)(childquery);
          fn(e, myIndex);
        }
      });
    }
    return returnableObj;
  } else alert('invalid query');
}