0

Similar to this : Event binding on dynamically created elements?

but I'm not adding an element dynamically only a class to an element using .addClass.

Basic html:

<div  id="WebPartWPQ6_ChromeTitle">
<a accesskey="W" href="/siteurl" >
<span>Access </span></a></div>

Function:

(function($){
$.fn.sharePop = function(){
if(typeof OpenPopUpPage == 'function'){
  return this.each(function(i){
    if($(this).attr('href') != null){
     $(this).click(function(e){
       e.preventDefault();
        OpenPopUpPage($(this).attr('href'));
      });
    }
  });
}
else{
  return false;
}
};
})(jQuery);
$(document).ready(function(){
$('.dialog-pop').sharePop();
 });

To add class:

$( document ).ready(function() {
    $( "#WebPartWPQ6_ChromeTitle a" ).addClass( "dialog-pop" );
});

The class gets added fine. But my assumption is it isn't there when the event gets attached to the element - and this line needs to change:

$(this).click(function(e){

I tried this:

$(this).on('click', '.dialog-pop', function(e){

But no luck.

matt
  • 2,690
  • 2
  • 16
  • 17

2 Answers2

1

$(document).on('click', '.dialog-pop', function(){ return function{ code goes here }; });

  • Thank you both. Tried bypassing the addclass and running the function directly on the element and replacing the function as shown and neither work. There's no class on the anchor itself I can use so I used #WebPartWPQ6_ChromeTitle a. NG. – matt Dec 11 '17 at 16:56
  • Odd because if I replicate the exact html elsewhere on the page, and call the fn directly it works -$('#WebPartWPQ6_ChromeTitle h2 a').sharePop(). Just not on this particular web part. – matt Dec 11 '17 at 17:46
  • I narrowed the issue down to an attribute Msft injects into Sharepoint web part titles - "onepagenavigationaction" which prevented the function running. Adding a .removeAttr to get rid of that, fixed it so now directly calling the function works. – matt Dec 11 '17 at 20:23
1

Basically, when you instantiate the element

$('.dialog-pop').sharePop()

It searches element with .dialog-pop in document and bind the event you as you've wrote. So, if there is a new dynamically added element, whether if the element has selector that firstly you instantiate with, the sharePop function does not have any idea what to do. So, rather than adding a class, directly instantiate your element.

$('#WebPartWPQ6_ChromeTitle a').sharePop()

If you in a need to use selector chosen, event delegation is way to go. In case you forcibly cannot determine selector you're going to use and currently using jQuery 1.7 or below, .selector property might help.

And oh, a thing to note is, I think destroy previously the same event -- to prevent it executing twice, and so forth -- (although you use preventDefault) is good.

$.fn.sharePop = function() {
  if (typeof OpenPopUpPage == 'function'){
    var selector = this.selector

    $(document).off('click').on('click', selector, function (e) {
      e.preventDefault()
      var href = $(this.attr('href'))

      if (href) {
        OpenPopUpPage($(this).attr('href'))
      }
    })

    return this
  }

  return false
};

Or apply the selector as argument if your version jQuery is greater than 1.7. Also notice I use a namespaced event to prevent destroying other click events that already attached.

$.fn.sharePop = function(selector) {
  if (typeof OpenPopUpPage == 'function'){
    if (typeof selector === 'string') {
      $(document).off('click.openpopup').on('click.openpopup', selector, function (e) {
        e.preventDefault()
        var href = $(this.attr('href'))

        if (href) {
          OpenPopUpPage($(this).attr('href'))
        }
      })
    } else {
      // attach the event like you already did?
    }

    return this
  }

  return false
};

Actually , I'd never create plugin thingy like this $.fn.sharePop if I won't share method/API like $('.dialog-pop').sharePop('refresh') or $('.dialog-pop').sharePop('destroy') or whatsoever rather than just bind the event on document ready directly.

Chay22
  • 2,834
  • 2
  • 17
  • 25