3

我有嵌套 div 的情况。我有一个父 div(有一个 onclick() 事件)和一些动态填充的 div。我了解到,通过“冒泡”,onclick() 事件应该通过 DOM 向上传播,从而在所有父项中触发 onclick() 事件。我所做的所有研究都表明,有很多人正在努力防止这种情况发生,而我却无法让它发挥作用。我可以让 onclick() 工作的唯一方法是在 div 的边缘附近单击,大概是子 div 不存在的地方,我直接单击父级。

我在下面包含了适用的代码。页面上可以有多达 9 个,即所谓的“小部件”,但我已经删除了所有代码,除了引用第一个“小部件”。

更新:当我尝试从 JavaScript 函数中提取所有内容并将其直接放入 HTML 代码中时,它可以正常工作。但是,这样做会迫使我放弃所需的功能,因此我将尝试避免这种解决方法。

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

更新#2:我创建了一个模仿我在代码中看到的响应的小提琴(下面的#5)。使用 fiddle 时,您会注意到在 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/

4

2 回答 2

0

如果您的 on-click 没有以某种方式具体引用 DIV,则可以始终将 onclick 添加到其他嵌套的 div.... 否则,您需要发布更多的 html。

于 2013-03-13T16:24:20.007 回答
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 函数以简单地在内部 div 内的 <h1> 和 <h2> 节点之间进行交换。

我已经把整个东西放在一个闭包中,以阻止它用除了 initializeWidgets 和 hoverWidgets 函数之外的任何东西污染全局范围。此实现仅在它注册为 onLoad 函数的处理程序时才有效,因为它的构造函数部分需要在 html 尝试将它们附加为事件处理程序之前运行并创建这两个函数。

如果您发现此解决方案对您的需求来说很复杂,您仍然应该能够通过使用 javascript 来创建自己的解决方案来本地创建和操作 div 和 h1/h2 标签,而不是直接写入 innerHTML 属性。

这是有关如何执行此操作的指南

于 2013-03-13T16:50:18.013 回答