3

My Rails app loads links to a page dynamically. I want to append an onClick action to those links.

The links are appended to the page properly, but the JS for the page is not being applied to those newly added elements.

I've tried rendering new JS tags to the dynamically-added content. I've also tried including this block of code, which should target any link with .select-link added to the #links div.

        $("#links").on("click", ".select-link", function() {
          my code here...
        })

That code works when the links are not dynamically loaded. However, I cannot seem to apply ANY onClick handler to them when dynamically loaded, even in the console.

What could possibly cause this issue?

For more context, the problem I'm trying to solve is here: AJAX-loaded JS not rendering

Community
  • 1
  • 1
bevanb
  • 8,201
  • 10
  • 53
  • 90
  • Please include the HTML as it is once the Rails content is loaded. – Makyen Sep 10 '16 at 06:14
  • Please do not intentionally ask duplicate questions. The question you link [AJAX-loaded JS not rendering](http://stackoverflow.com/questions/39422028/ajax-loaded-js-not-rendering), which you asked 3 hours ago, is effectively a duplicate of this question. – Makyen Sep 10 '16 at 06:23
  • The reason you have not gotten effective help for your problem is that you have not provided a **complete** [mcve] in the question which is sufficient to duplicate the problem. The reason that a [mvce] is required for debugging questions, like yours, is that without a [mcve], we have to *guess* at what the problem is. Please [edit] your question(s) to include a [mcve] that can be used to duplicate the problem. Do this even if you have to show the AJAX code and provide the text of what the AJAX response would be. – Makyen Sep 10 '16 at 06:26
  • @Makyen Good feedback. In this question, I'm wondering about what could, in general, cause newly added DOM elements to be not targetable by Jquery selectors. Any ideas? – bevanb Sep 10 '16 at 06:49
  • There are at least a few possible reasons. However, because you have not provided a [mcve], anything we state is just a guess based on too little information. The requirements for on-topic questions are specifically in place to prevent you wasting large amounts of other people's time by having them speculate without enough information. What you have is a specific debugging issue. You have code, it is not working. Such questions **require** a **[mcve]** to be on-topic. By not providing one, you are intentionally expending other people's time to **guess** at what your issue might be. – Makyen Sep 10 '16 at 08:06
  • The simplest solution to this is that you are using a selector that does not match any of the dynamically loaded content. In other words, the simplest solution is that it is a bug in your code, not an issue with jQuery, or other means of adding event listeners. – Makyen Sep 10 '16 at 08:10

3 Answers3

1

You should bind your event to document like this

$(document).on("click", "#links .select-link", function() {
          my code here...
});
R.K.Saini
  • 2,678
  • 1
  • 18
  • 25
  • Unfortunately, this does not work. (It works when rendered statically, but not dynamically). – bevanb Sep 10 '16 at 07:15
0

Try following code:

$(document).on("click", "#links .select-link", function() {
          /*my code here...*/
})

or

$("#links .select-link").live("click", function() {
         /*my code here...*/
})
0

The thing is, the code which you have in the question does work for dynamically inserted content.

The following snippet has one <div class="select-link"> which is part of the HTML and inserts two <div class="select-link"> elements via JavaScript.

jQuery is used to add two separate click handlers. The first handler is added prior to any of the dynamic content being added to the DOM. The second handler is added after the second <div class="select-link"> is added, but before the third one is inserted. Both handlers are called for all three <div class="select-link">. This demonstrates that the code you have provided in the question does work for dynamically inserted content. That means something else is going on.

$("#links").on("click", ".select-link"
    ,logEvent.bind(null,'#links on .select-link','jQuery'));

function logEvent(text,type,e){
  var curTarget = (e.currentTarget.id)?e.currentTarget.id:e.currentTarget.nodeName;
  var target = (e.target.id)?e.target.id:e.target.nodeName;
  console.log(text + ' ::' + type + ' ::curTarget=' + curTarget 
              + ' ::target=' + target);
}

function appendLink(id,text) {
    document.querySelector('#links').insertAdjacentHTML('beforeend'
        ,'<div class="select-link"  id="' + id + '" style="color:blue;">' 
         + text + '</div>');
}

appendLink('sel-pre-ready','Selected Link 2 (added prior to document ready)');

$(document).ready(function(){
    $("#links").on("click", ".select-link"
        ,logEvent.bind(null,'#links on .select-link','jQuery at doc ready'));
    appendLink('sel-post-ready','Selected Link 3 (added after document ready)');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Not Link</div>
<div id="links">Links
  <div id="not-sel">Not Selected Link</div>
  <div class="select-link"  id="sel-html" style="color:blue;">Selected Link 1 (HTML)</div>
</div><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>

Without more information, spending a lot of time speculating on what might be causing the problem is just wasting time.

One possibility of what is happening is that another event handler is being fired for these events and stopping propagation. One way to (mostly) check for that is to add an event handler to the window on the capture phase (i.e. not using jQuery). You could do so with the following:

//The following will catch the event prior to almost all possible
//  interference by other event handlers.
window.addEventListener('click',function(e){
    if(!$(e.target).is("#links .select-link")){
        return; //Not one of the elements we are interested in
    }//else
    //e.stopPropagation();
    logEvent('on window','Capture',e);
},true);
Makyen
  • 31,849
  • 12
  • 86
  • 121