找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3339|回复: 20

[求助] 一个项目js效果求助

[复制链接]
发表于 2013-7-11 20:40:47 | 显示全部楼层 |阅读模式
80体力
本帖最后由 chocho 于 2013-7-13 11:32 编辑

 提示:您可以先修改部分代码再运行

如代码  


我想要阻止 l i 下面的元素事件冒泡到ul  (因为li可能有n个)

同时 l i 的事件要允许他冒泡到ul

在 l i   里的元素结构可能会有变化 最好不要对li里的元素有耦合现象存在

请高手指教  悬赏提高一下  希望有办法解决





最佳答案

查看完整内容

  个人觉得代码还可以精简, 我用23行代码,实现了这个功能, 也请楼主帮忙测试一下有漏洞没有[html] JS事件触发判断试验 * { margin:0;padding:0;border:0;list-style:none; } #worksLB { width:1000px; height:270px; overflow:hidden; color:#ffcc00; } #worksLB li { height:230px; width:280px; cursorointer; overflow:hidden; float:left; margin:20px; background:#333333; } #worksLB img { w ...
发表于 2013-7-11 20:40:48 | 显示全部楼层
本帖最后由 yypz 于 2013-7-13 20:25 编辑

 
个人觉得代码还可以精简,
我用23行代码,实现了这个功能,
也请楼主帮忙测试一下有漏洞没有
  1. var liBox=document.getElementById('worksLB')
  2. var traceBox=document.getElementById('tracediv')
  3. liBox.onmouseover=liBox.onmouseout=function(event) {
  4.         var e=event||window.event
  5.         var eventNode=e.target||e.srcElement
  6.         var eventNodeName=eventNode.nodeName.toLowerCase()
  7.         if(eventNodeName=="li"||eventNodeName=="img"||eventNodeName=="span"){
  8.                 var liObj=eventNode
  9.                 if(eventNodeName=="img"||eventNodeName=="span"){liObj=eventNode.parentNode}
  10.                 if(e.type=="mouseover"){
  11.                         var relObj=e.relatedTarget||e.fromElement
  12.                         if(relObj==null||liObj!=relObj&&liObj!=relObj.parentNode){
  13.                                 liObj.style.background="#ff0000"
  14.                                 traceBox.innerHTML+=liObj.getElementsByTagName("span")[1].innerHTML+"进 "
  15.                         }
  16.                 }else if(e.type=="mouseout"){
  17.                         var relObj=e.relatedTarget||e.toElement
  18.                         if(relObj==null||liObj!=relObj&&liObj!=relObj.parentNode){
  19.                                 liObj.style.background="#000000"
  20.                                 traceBox.innerHTML+=liObj.getElementsByTagName("span")[1].innerHTML+"出 "
  21.                         }
  22.                 }
  23.         }
  24. }
复制代码

 提示:您可以先修改部分代码再运行

代码及预览截图(全屏).jpg
回复

使用道具 举报

发表于 2013-7-11 23:04:15 | 显示全部楼层

 提示:您可以先修改部分代码再运行

回复

使用道具 举报

 楼主| 发表于 2013-7-12 08:48:54 | 显示全部楼层
GaFish 发表于 2013-7-11 23:04
[html]


你好  首先谢谢你的帮助 代码很清楚 非常感谢


我还想问一下 就是我的代码为什么在鼠标运动速度过快时会有问题  或者说我的是有逻辑错误吗

一直找不出原因 ...

谢谢
回复

使用道具 举报

发表于 2013-7-12 09:07:56 | 显示全部楼层
chocho 发表于 2013-7-12 08:48
你好  首先谢谢你的帮助 代码很清楚 非常感谢

你在目标节点的判断上存在BUG
回复

使用道具 举报

 楼主| 发表于 2013-7-12 18:44:25 | 显示全部楼层
GaFish 发表于 2013-7-12 09:07
你在目标节点的判断上存在BUG

你 好  谢谢你的回答  可能是我没说清楚 你能帮我再看一下代码吗

当鼠标在红色与黑色区域来回走时 我不想要运行事件程序...

就是在li内元素间的鼠标运动 不要触发事件

谢谢

 提示:您可以先修改部分代码再运行

回复

使用道具 举报

 楼主| 发表于 2013-7-12 18:45:41 | 显示全部楼层
GaFish 发表于 2013-7-12 09:07
你在目标节点的判断上存在BUG

你 好  谢谢你的回答  可能是我没说清楚 你能帮我再看一下代码吗

当鼠标在红色与黑色区域来回走时 我不想要运行事件程序...

就是在li内元素间的鼠标运动 不要触发事件

谢谢

 提示:您可以先修改部分代码再运行

回复

使用道具 举报

发表于 2013-7-13 07:14:31 | 显示全部楼层
我觉得用mouseover和mouseout来解这个难题基本无望。
因为如果LI里面有子元素,鼠标在子元素与LI之间划过仍然会触发mouseover和mouseout事件
而且如果是鼠标从左边或者上面移入此子元素时,时侦测到的e.offsetX和e.offsetY为0到几像素的样子
所以判断鼠标位置来区别是鼠标移入移出整个LI,还是鼠标在LI内的子元素之间移入移出都几乎是不可能的

如果用LI和它的最外层元素级容器DIV都绝对定位,然后用mousemove+位置判断:
(e.pageX||e.clientX)-LI.offsetLeft-document.getElementById("DIV容器").offsetLeft
(e.pageY||e.clientY)-LI.offsetTop-document.getElementById("DIV容器").offseHeight

进行不间断的鼠标位置判断来标识鼠标是否移入移出整个LI,倒是有可能实现,
但其复杂程度可想而知,我觉得有些得不尝失。
建议楼主还是换个思路来解决问题,可能更为简单便捷些。
回复

使用道具 举报

 楼主| 发表于 2013-7-13 09:21:51 | 显示全部楼层
yypz 发表于 2013-7-13 07:14
我觉得用mouseover和mouseout来解这个难题基本无望。
因为如果LI里面有子元素,鼠标在子元素与LI之间划过仍 ...

这个问题 有其他方法解决木有呀

好痛苦啊 每次都会有这个问题 过不去
回复

使用道具 举报

发表于 2013-7-13 10:27:36 | 显示全部楼层
  1. <script>

  2. var EventUtil={
  3.         getEvent:function(event){return event?event:window.event;},
  4.         //返回鼠标相对于事件对象的 X 坐标
  5.         getTarget:function(event){return event.target||event.srcElement;}
  6.         //取消事件默认行为

  7.         }
  8. var doc=document;
  9. var worksLB=doc.getElementById('worksLB');
  10. var flag = null;
  11. var show=doc.getElementById('show');


  12.                                                 worksLB.onmouseover=function(e){
  13.                                                         e=EventUtil.getEvent(e);
  14.                                                         var obj=EventUtil.getTarget(e);
  15.                                                         if(obj.nodeName!='IMG'){return false;}
  16.                                                         flag = 1;
  17.                                                         show.style.display='none';
  18.                                                         }
  19.                                                 worksLB.onmouseout=function(e){
  20.                                                     if(flag===1){
  21.                                                             show.style.display='block';
  22.                                                             flag = null;
  23.                                                     }
  24. }
  25.                                                        
  26.                                                        
  27. </script>
复制代码
回复

使用道具 举报

 楼主| 发表于 2013-7-13 11:12:40 | 显示全部楼层
DoBest 发表于 2013-7-13 10:27


谢谢这位仁兄的回答 但是...
如果li里面有其他元素怎么办啊 一一判断  而且是要鼠标经过里 就触发事件 经过img时事件不冒泡到ul  不是经过img才触发事件...



回复

使用道具 举报

发表于 2013-7-13 12:32:45 | 显示全部楼层
chocho 发表于 2013-7-13 09:21
这个问题 有其他方法解决木有呀

好痛苦啊 每次都会有这个问题 过不去

如果LI中几个子元素(图片、文字)上面的链接地址是一致的,
不妨用一块与整个LI所占面积一样大的透明的DIV(高宽均100%)覆盖在子元素上面,
然后判断这个透明DIV的mouseover和mouseout来试试。

另外,LI最好不用padding,而是设置LI内部子元素的margin
回复

使用道具 举报

发表于 2013-7-13 13:49:35 | 显示全部楼层
思维错误。
回复

使用道具 举报

 楼主| 发表于 2013-7-13 14:41:52 | 显示全部楼层

查找了很多博客 终于实现了(不知道能不能经得起大家的检验  帮我看看还有什么缺陷)

问题是这样的 我再说一下

一个ul的列表 每个li要写事件 有很多li  考虑性能 所以把事件写在ul上 (事件委托)

li下面又有很多节点 在li内部节点之间的鼠标事件不能冒泡到ul上面

我的解决思路是这样的

事件发生了 如果是ul触发的 就false掉  如果不是的 就取得li元素

然后再循环 判断触发事件的元素的“相关节点”的父节点 直到找到和li匹配的

如果找到就false 如果没找到就运行事件程序

不知道说清楚没  直接看代码吧

如果有问题 大家提出来

 提示:您可以先修改部分代码再运行

回复

使用道具 举报

 楼主| 发表于 2013-7-13 14:42:52 | 显示全部楼层
yypz 发表于 2013-7-13 12:32
如果LI中几个子元素(图片、文字)上面的链接地址是一致的,
不妨用一块与整个LI所占面积一样大的透明的DI ...

谢谢你的回答 帮我看看这样可以不  或者还有哪些地方可以改一下

http://bbs.blueidea.com/forum.ph ... p;extra=#pid5642482

谢谢

回复

使用道具 举报

发表于 2013-7-13 15:23:20 | 显示全部楼层
chocho 发表于 2013-7-13 14:42
谢谢你的回答 帮我看看这样可以不  或者还有哪些地方可以改一下

http://bbs.blueidea.com/forum.php?m ...

IE和谷歌都看过了,没有任何问题,不错。

奇了怪了,昨天我试的时候,怎么alert(e.target)是undefined呢
要早知能得到e.target,那解决起来还不容易。
直接就可以判断触发事件的节点名,代码也不用写得如此繁复。
回复

使用道具 举报

发表于 2013-7-13 15:30:41 | 显示全部楼层
都没看到阻止冒泡。
只看到好多泡泡。
回复

使用道具 举报

 楼主| 发表于 2013-7-13 17:16:59 | 显示全部楼层

 提示:您可以先修改部分代码再运行

回复

使用道具 举报

 楼主| 发表于 2013-7-14 10:34:47 | 显示全部楼层
yypz 发表于 2013-7-13 20:23
 
个人觉得代码还可以精简,
我用23行代码,实现了这个功能,

谢谢 这个不错 只是如果li下的html有改动就要改下js了

学习了
回复

使用道具 举报

发表于 2013-7-15 09:40:32 | 显示全部楼层
chocho 发表于 2013-7-14 10:34
谢谢 这个不错 只是如果li下的html有改动就要改下js了

学习了

楼主的需求怎么感觉和 JQuery里面的 mouseenter 和 mouseleave 一样?
楼主看一下下面的效果正确不?

 提示:您可以先修改部分代码再运行

回复

使用道具 举报

 楼主| 发表于 2013-7-15 12:39:33 | 显示全部楼层
faeng220 发表于 2013-7-15 09:40
楼主的需求怎么感觉和 JQuery里面的 mouseenter 和 mouseleave 一样?
楼主看一下下面的效果正确不?[html ...

就是要实现这个 mouseenter 和 mouseleave   呵呵
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备19000417号-2 )

GMT+8, 2021-12-6 03:30 , Processed in 0.076170 second(s), 9 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表