Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/451.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将事件附加到动态呈现的元素_Javascript_Html_Events_Dom_Addeventlistener - Fatal编程技术网

JavaScript将事件附加到动态呈现的元素

JavaScript将事件附加到动态呈现的元素,javascript,html,events,dom,addeventlistener,Javascript,Html,Events,Dom,Addeventlistener,我有两个文件index.html和all.js all.js index.html <button id="btn2" onclick="show()">Show</button> <script type="text/javascript"> function show(){ var btn = document.createElement("BUTTON"); btn.setAttribute("id", "

我有两个文件
index.html
all.js

all.js

index.html

<button id="btn2" onclick="show()">Show</button>
<script type="text/javascript">
    function show(){
        var btn = document.createElement("BUTTON");
            btn.setAttribute("id", "btn1");
            btn.innerHTML = "Hit me !";
        document.getElementById("btn2");
        document.body.insertBefore(btn, btn2);

        //now call attachClickEvent function to add event listner to btn1
        //(both displayMessage() and attachClickEvent() functions are loaded now)
        attachClickEvent('btn1', displayMessage);
    }
</script>
<script type="text/javascript" src="all.js"></script>
示例1:-工作示例

<button id="btn1">Hit me !</button>
<script type="text/javascript" src="all.js"></script>
<button id="btn2" onclick="show()">Show</button>
<script type="text/javascript">
    function show(){
        var btn = document.createElement("BUTTON");
            btn.setAttribute("id", "btn1");
            btn.innerHTML = "Hit me !";
        document.getElementById("btn2");
        document.body.insertBefore(btn, btn2);
    }
</script>
<script type="text/javascript" src="all.js"></script>
不幸的是,我不能分割声誉,我只能把它给其中一个,我想把这个给弗拉卡夫,因为他是第一个发布我正在寻找的解决方案的人,当我要求他这样做时,他也对它做了一些更改。我还对阿鲁纳的回答进行了评价,因为他值得这样做

我已经在一个单独的分支上发布了解决方案,我还使用收到的其他解决方案在此回购上创建了几个其他分支,因为它们可能在其他情况下有用。

用于侦听dom更改并将事件添加到
addedNodes

函数displayMessage(){
警惕(“嗨!”);
}
函数show(){
var btn=document.createElement(“按钮”);
btn.setAttribute(“id”、“btn1”);
btn.innerHTML=“打我!”;
文件.getElementById(“btn2”);
document.body.insertBefore(btn,btn2);
}
(新突变观察者(突变=>{
突变
.reduce((上一个,当前)=>上一个concat(数组从(当前添加节点)),[])
.filter(node=>node.id==“btn1”)
.forEach(button=>button.addEventListener('click',displayMessage));
})).observe(document.body,{childList:true,subtree:true})

Show
您还应该能够使用事件委派

如果新的DOM元素都放在id为“dynamic”的div中,则可以使用以下命令:

document.getElementById("dynamic").addEventListener("click",function(event){
    var target = event.target;
    console.log(target); 
});

这将捕获dynamicdiv中发生的所有单击事件,您可以测试事件目标以确定单击了哪个元素。使用这种方法,您只需要一个事件处理程序。

在您的情况下,
displayMessage()
btn1
处理程序将尝试在
btn1
向DOM注册之前先注册,当用户单击
btn2
时,
btn1
元素将向DOM注册。所以不会有任何处理程序触发。因此,请在注册
btn1
之后注册处理程序,如下所示

<button id="btn2" onclick="show()">Show</button>
<script type="text/javascript">
function show(){
    var btn = document.createElement("BUTTON");
        btn.setAttribute("id", "btn1");
        btn.innerHTML = "Hit me !";
    document.getElementById("btn2");
    document.body.insertBefore(btn, btn2);
    btn.addEventListener("click", displayMessage);
}
</script>
<script type="text/javascript" src="all.js"></script>
Show
函数show(){
var btn=document.createElement(“按钮”);
btn.setAttribute(“id”、“btn1”);
btn.innerHTML=“打我!”;
文件.getElementById(“btn2”);
document.body.insertBefore(btn,btn2);
btn.addEventListener(“单击”,显示消息);
}

将onclick属性添加到元素btn

函数displayMessage(){
警惕(“嗨!”);
}
函数show(){
var btn=document.createElement(“按钮”);
btn.setAttribute(“id”、“btn1”);
btn.innerHTML=“打我!”;
btn.onclick=显示消息;
文件.getElementById(“btn2”);
document.body.insertBefore(btn,btn2);
}

Show
在加载
all.js
时,它正在查找元素
btn1
,并尝试附加事件(如果它出现)。由于元素是动态创建/加载的,因此在加载
all.js
时,它不会附加到事件,因此元素在创建后没有附加到事件

根据我与您的讨论,我从您那里了解到以下几点:

  • 您不能更改
    all.js
    index.html
    ,因为它们都是维护的 由你的客户和保护
  • index.html
    正在调用类似于
    initHeader()的方法
    这反过来又通过ajax请求调用webservice
  • 然后,
    index.html
    正在解析ajax调用返回的
    json
    它实际上是您返回的,可以包含html和js
  • 然后将解析后的json(html)附加到页面中,如下所示:,
    document.getElementByID('nav').innerHtml=ajaxResponse
基于上述理解,您唯一可以更改/做一些事情的地方是您从Web服务返回的内容

因此,我可以建议您使用下面的脚本,您可以在最后的webservice响应中添加该脚本,该脚本将从
index.html
中删除现有的
all.js
文件,并在ajax响应后再次加载该文件

<script type="text/javascript">
    function reattachEvents() {
      // Remove 'all.js'
      var scripts = document.getElementsByTagName('script')
      for (var i = scripts.length - 1; i >= 0; i--){ // Loop backwards
         if (scripts[i]) {
            var srcUrl = scripts[i].getAttribute('src');
            if(srcUrl && srcUrl.indexOf('all.js') > -1) {
               scripts[i].parentNode.removeChild(scripts[i]);
            }
         }
      }

      // Load 'all.js'
      var head= document.getElementsByTagName('head')[0];
      var script= document.createElement('script');
      script.type= 'text/javascript';
      script.src= 'all.js';
      head.appendChild(script);
   }

   reattachEvents();
</script>

函数resattachevents(){
//删除'all.js'
var scripts=document.getElementsByTagName('script')
对于(var i=scripts.length-1;i>=0;i--){//向后循环
如果(脚本[i]){
var srcUrl=scripts[i].getAttribute('src');
if(srcUrl&&srcUrl.indexOf('all.js')>-1){
脚本[i].parentNode.removeChild(脚本[i]);
}
}
}
//加载'all.js'
var head=document.getElementsByTagName('head')[0];
var script=document.createElement('script');
script.type='text/javascript';
script.src='all.js';
head.appendChild(脚本);
}
复位();

注意:我已在中创建了一个新的拉取请求,通过这些更改

您可以在每次按下按钮时使用jQuery加载脚本

<button id="btn2" onclick="show()">Show</button>
<script
  src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script type="text/javascript">
    function show(){
        var btn = document.createElement("BUTTON");
            btn.setAttribute("id", "btn1");
            btn.innerHTML = "Hit me !";
        document.getElementById("btn2");
        document.body.insertBefore(btn, btn2);
        jQuery.getScript("all.js");
    }
</script>
Show
函数show(){
var btn=document.createElement(“按钮”);
btn.setAttribute(“id”、“btn1”);
btn.innerHTML=“打我!”;
文件.getElementById(“btn2”);
document.body.insertBefore(btn,btn2);
getScript(“all.js”);
}

创建一个方法,将事件列表器附加到all.js文件中的按钮中

   function attachClickEvent(elementId, event){
      var element = document.getElementById(elementId);
      if (element ){
        element.addEventListener("click", event);
      }    
    }

    function displayMessage(){
        alert("Hi!");
    }
index.html

<button id="btn2" onclick="show()">Show</button>
<script type="text/javascript">
    function show(){
        var btn = document.createElement("BUTTON");
            btn.setAttribute("id", "btn1");
            btn.innerHTML = "Hit me !";
        document.getElementById("btn2");
        document.body.insertBefore(btn, btn2);

        //now call attachClickEvent function to add event listner to btn1
        //(both displayMessage() and attachClickEvent() functions are loaded now)
        attachClickEvent('btn1', displayMessage);
    }
</script>
<script type="text/javascript" src="all.js"></script>
Show
函数show(){
var btn=document.createElement(“按钮”);
btn.setAttribute(“id”、“btn1”);
btn.innerHTML=“打我!”;
文件.getElementById(“btn2”);
document.body.insertBefore(btn,btn2);
//现在调用attachClickEvent函数将事件列表添加到btn1
//(displayMessage()和attachClickEvent()函数现在都已加载)
attachClickEvent('btn1',displayMessage);
<button id="btn2" onclick="show()">Show</button>
<script type="text/javascript">
    function show(){
        var btn = document.createElement("BUTTON");
            btn.setAttribute("id", "btn1");
            btn.innerHTML = "Hit me !";
        document.getElementById("btn2");
        document.body.insertBefore(btn, btn2);

        //now call attachClickEvent function to add event listner to btn1
        //(both displayMessage() and attachClickEvent() functions are loaded now)
        attachClickEvent('btn1', displayMessage);
    }
</script>
<script type="text/javascript" src="all.js"></script>
<button id="btn2" onclick="show()">Show</button>
<script type="text/javascript">
  function initHiddenButton(id, text) {
    var btn = document.createElement("BUTTON");
    btn.setAttribute("id", id);
    btn.innerHTML = text;
    btn.style.display = 'none';
    document.body.appendChild(btn);
  }
  initHiddenButton("btn1", "Hit me !");
    function show(){
      var btn1 = document.getElementById("btn1");
      var btn2 = document.getElementById("btn2");
        btn1.style.display = 'inline-block';
        document.body.insertBefore(btn1, btn2);

        //others code...
    }
</script>
<script src="all.js"></script>
<button id="btn2" onclick="show()">Show</button>

<!-- hidden buttons -->
<button id="btn1" onclick="show()" style="display: none;">Hit me !</button>

<script type="text/javascript">
    function show(){
      var btn1 = document.getElementById("btn1");
      var btn2 = document.getElementById("btn2");
        btn1.style.display = 'inline-block';
        document.body.insertBefore(btn1, btn2);

        //others code...
    }
</script>
<script src="all.js"></script>
function show() {
  var btn = document.createElement("BUTTON");
  btn.setAttribute("id", "btn1");
  btn.innerHTML = "Hit me !";
 //  btn.onclick = displayMessage;  // you can use this also.
  document.getElementById("btn2");
  document.body.insertBefore(btn, btn2);
//document.getElementById("btn1").addEventListener("click", displayMessage); //like this
}
<html>
<body>
<button id="btn2" onclick="show()">Show</button>
<script type="text/javascript" src="../jquery.js"></script>
<script type="text/javascript">
    function show(){
        var btn = document.createElement("BUTTON");
            btn.setAttribute("id", "btn1");
            btn.innerHTML = "Hit me !";
        document.getElementById("btn2");
        document.body.insertBefore(btn, btn2);

        //HERE YOU HAVE TO RELOAD YOUR all.js
        reload_js('all.js');    
    }
</script>
<script type="text/javascript">
    function reload_js(src) {
            $('script[src="' + src + '"]').remove();
            $('<script>').attr('src', src).appendTo('head');
        }
</script>
<script type="text/javascript" src="all.js"></script>
</body>
</html>
   <html>
<body>
<button id="btn2" onclick="show()">Show</button>
<script type="text/javascript">
    function show(){
        var btn = document.createElement("BUTTON");
            btn.setAttribute("id", "btn1");
            btn.innerHTML = "Hit me !";
        document.getElementById("btn2");
        document.body.insertBefore(btn, btn2);
        //Pass the name you want to reload 
        loadJs('all.js');
    }
</script>
<script type="text/javascript" src="all.js"></script>


<script type="text/javascript">


     function loadJs(js)
       {    
            //selecting js file
            var jsSection = document.querySelector('script[src="'+js+'"]');

            //selecting parent node to remove js and add new js 
            var parent = jsSection.parentElement;
            //deleting js file
            parent.removeChild(jsSection);

            //creating new js file 
            var script= document.createElement('script');
            script.type= 'text/javascript';
            script.src= js;

            //adding new file in selected tag.
            parent.appendChild(script);
       }
</script>
</body>
</html>
document.querySelector('body').addEventListener('click', function (event) {
    if (event.target.id !== 'btn1') {
        return; //other element than #btn1 has been clicked
    }

    //Do some stuff after clicking #btn1
});
$('body').on('click', '#btn1', function(event) {
    // do something when #btn has been clicked
});
// removed, see Edit
function reloadAllJs(){
    var path = "all.js"
        , oldScript = document.querySelector("script[src^='" + path + "']")
        , newScript = document.createElement("script")
        ;       
    // adding random get parameter to prevent caching
    newScript.src = path + "?timestamp=" + Date.now();
    oldScript.parentNode.replaceChild(newScript, oldScript);
}
function reloadAllJs(){
    var path = "all.js"
        , scripts = document.getElementsByTagName("script")
        , oldScript
        , newScript = document.createElement("script")
        ;

    for(var i = 0, s; s = scripts[i]; i++) {
        if (s.src.indexOf(path) !== -1) {
            oldScript = s;
            break;
        }
    }

    // adding random get parameter to prevent caching
    newScript.src = path + "?timestamp=" + (new Date()).getTime();
    oldScript.parentNode.replaceChild(newScript, oldScript);
}