单击子div时未调用父onclick()事件

时间:2013-03-12 23:42:47

标签: javascript html dom onclick parent-child

我遇到过嵌套div的情况。我有一个父div(有一个onclick()事件)和一些内部动态填充的div。我理解通过'冒泡',onclick()事件应该通过DOM传播,触发所有父节点中的onclick()事件。我所做的所有研究都显示了一群试图阻止这种情况的人,而我无法让它发挥作用。我可以让onclick()工作的唯一方法是在div的边缘附近点击,大概是在孩子div不存在的地方,我直接点击父母。

我在下面列出了适用的代码。页面上可以有多达9个这样的所谓“窗口小部件”,但除了引用第一个“窗口小部件”之外,我删除了所有代码。

更新:当我尝试从JavaScript函数中取出所有内容并将其直接放入HTML代码时,它就像我期望的那样工作。但是,这样做会迫使我放弃所需的功能,所以我将尽力避免这种解决方法。

下面有一个新的小提琴基本上显示了我的目的,即使事件没有像我期望的那样调用JS函数。

更新#2:我创建了一个小提琴(下面的#5),模仿我在代码中看到的响应。当使用小提琴时,你会注意到在点击div的中心时没有给出警告,但是当你在div的外边界附近点击时,你终于得到了响应。

问题已解决:

根据Racheet的回答,这个问题已经解决了。我创建了一个最终的小提琴,其中包含功能齐全的代码供参考: http://jsfiddle.net/v3MGX/8/

JAVASCRIPT:

function initializeWidgets(){

var widget1 = "Professional";

widget1 = 
    "<div class='outer'><div class='middle'>
    <div class='inner'><h1>" + widget1 + "</h1></div></div></div>";

document.getElementById("widget1").innerHTML = widget1;
}

function hoverWidgets(widgetID){
var w = new Array();
w[0] = "Work Experience, Educational History, and Resume Download";

w[widgetID-1] = "<div class='outer'><div class='middle'>
    <div class='inner'><h2>" + w[widgetID-1] + "</h2></div></div></div>";

document.getElementById("widget"+widgetID).innerHTML = w[widgetID-1];

}

适用的HTML:

<div class="widget" id="widget1" onclick="alert(1);" onmouseover="hoverWidgets('1')"
onmouseout="initializeWidgets()"></div>

当前的好词: http://jsfiddle.net/v3MGX/5/

最终的好消息: http://jsfiddle.net/v3MGX/8/

2 个答案:

答案 0 :(得分:0)

如果您的点击不是以某种方式特定地引用DIV,可以随时将onclick添加到其他嵌套的div ...否则,您需要发布更多的html。

答案 1 :(得分:0)

我已经和你的例子玩了很多,并解决了问题。这是我的解决方案:

http://jsfiddle.net/v3MGX/7/

    window.initializeWidgets = (function() {
    /*THIS SECTION IS YOUR WIDGET CONSTRUCTOR*/

    //Set up your constants for this widget
    var widget1 = "Professional";
    var widget2 = "Work Experience, Educational History, and Resume Download";

    //first you grab your old element
    var widgetSmallElement = document.getElementById("widget1");

    //then you make your new elements
    var outer = document.createElement("div");
    outer.setAttribute('class','middleSmall');
    var inner = document.createElement("div");
    inner.setAttribute('class','innerSmall');
    var heading = document.createElement("h1");
    heading.innerHTML = widget1;
    var subHeading = document.createElement("h2");
    subHeading.innerHTML = widget2;

    //now you chain the above and then add them to the document
    inner.appendChild(heading);
    outer.appendChild(inner);
    widgetSmallElement.appendChild(outer);

    //This is your new, simplified hoverWidgets handler
    window.hoverWidgets = function (widgetID) {
        inner.replaceChild(subHeading,inner.firstChild);        
    };

    /*THIS SECTION IS THE RETURN VALUE FROM YOUR CONSTRUCTOR*/
    return function() {
        //this is the function actually given to the onClick and onMouseout handler as the initializeWidgets funciton.
        inner.replaceChild(heading,inner.firstChild);
    };

})();

您遇到的问题是由于您创建内部div的方式。当您通过将html作为字符串写入DOM节点的innerHTML属性来在javascript中创建html元素时,那里的旧节点将被删除,并创建一个新节点来替换它。

当删除旧节点时,附加到它的事件处理程序也会被删除,因此当您的鼠标悬停运行时,它们实际上正在删除并重新创建各种内部div,及其现有的事件处理程序。因此,您在html中分配的onclick处理程序对于那些内部节点不存在。

通过直接写入innerHTML属性将html添加到文档中通常是一个坏主意。

我已经重写了解决方案,以便它在JavaScript中本地创建节点,然后重新编写initializeWidgets和hoverWidgets函数,以简单地在&lt; h1&gt;之间交换。和&lt; h2&gt;内部div中的节点。

我把整个事情放在一个闭包中,以阻止它使用initializeWidgets和hoverWidgets函数来控制全局范围。只有当它被注册为onLoad函数的处理程序时,此实现才有效,因为它的构造函数部分需要在html尝试将它们作为事件处理程序附加之前运行并创建这两个函数。

如果您发现此解决方案可以满足您的需求,您仍然可以使用javascript本地创建和操作div和h1 / h2标记,而不是通过直接写入innerHTML属性来创建自己的解决方案

Here's a guide on how to do that