litel
litel

Reputation: 3980

Link in jQuery replaced HTML not working

I'm trying to make a simple plugin that collects the # of Facebook likes and tweets for a given URL (and let users tweet or like a given link). There is a total share count that expands to include LIs for likes and shares upon hover. Currently, on mouseover or select of the like/share LIs, the HTML of the Twitter/Facebook is replaced with a link and text with a subtle CTA. This link is supposed to open a new window with a share dialog for the given social site. However, this link doesn't seem to work at all.

HTML

   <html>
  <head>
    <link rel="stylesheet" href="css/style.css" type="text/css">
  </head>
  <body>
    <div id="social">
      <ul>
        <li class="share">
     <p>shares<p>
        </li>
      <li class="twitter"><p>tweets</p></li>
        <li class="facebook"><p>likes</p></li>
      </ul>
    </div>
   <!-- <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="js/app.js"></scrpt>-->
  </body>
</html>

jQuery

var fbCount,twCount,totalCount,
   urlDebug = 'http://www.google.com',
   urlCurrent = window.location.href,
   twitterCountUrl = 'http://urls.api.twitter.com/1/urls/count.json?url=' + urlDebug + '&callback=?',
    facebookCountUrl = 'https://graph.facebook.com/fql?q=SELECT%20share_count,%20like_count,%20comment_count,%20total_count,commentsbox_count,%20comments_fbid,%20click_count%20FROM%20link_stat%20WHERE%20url=%27' + urlDebug + '%27',
    fbShareUrl = "https://www.facebook.com/sharer/sharer.php?u=" + urlDebug +  "&t=" + document.title + 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=300,width=600',
    twShareUrl = "https://twitter.com/intent/tweet?text=" + document.title + "url=" + urlDebug;

$('.sharelink').on('click', function() {
window.open( $(this).attr('href') );
return false;
});


function getnumString(num) {
  var numString;

  if (num < 1000) {
    numString = num;
  } else if (num < 10000) {
    // removed my rube goldberg contraption and lifted
    // CMS version of this segment
    numString = num.charAt(0) + ',' + num.substring(1);
  } else if (num < 1000000) {
    numString = (Math.round((num / 1000) * 10) / 10) + "k"
  } else {
    numString = (Math.round((num / 1000000) * 10) / 10) + "M"
  }

  return numString.toString();
}
$.when(
$.getJSON(twitterCountUrl, function twitterCount(data) {
  twCount = data.count;
  $('.twitter').append('<p class="num">' + getnumString(twCount) + '</p>');
}),

$.getJSON(facebookCountUrl,
    function facebookCount(data) {
      fbCount = data.data[0].like_count;
      $('.facebook').append('<p class="num">' + getnumString(fbCount) + '</p>');
    })).done(function(response) {
      totalCount = fbCount + twCount;
      $('.share').append('<p class="num">' + getnumString(totalCount) + '</p>');
});

      $('#social ul').on('mouseover touchstart focusin', function() {
        $('.facebook, .twitter').slideDown("slow");

      }).on('mouseleave touchend focusout', function() {
        $('.facebook, .twitter').hide();
      });

      $('#social .twitter').on('mouseenter focusin', function() {

       $(this).html('<a href="'+ twShareUrl +'">TWEET<br>LINK</a>');
        $(this).children('a').addClass('sharelink');
      }).on('mouseleave focusout', function() {
        $(this).children('a').removeClass('sharelink');
        $(this).html('<p> tweets</p>').append('<p class="num">' + getnumString(twCount) + '</p>');
      });


      $('#social .facebook').on('mouseenter focusin', function() {
        $(this).html('<a href="' + fbShareUrl + '">SHARE<BR>ON FB</a>');
        $(this).children('a').addClass('sharelink');
      }).on('mouseleave focusout', function() {
        $(this).children('a').removeClass('sharelink');
        $(this).html('<p>likes</p>').append('<p class="num">' + getnumString(fbCount) + '</p>');
      });

Upvotes: 0

Views: 52

Answers (1)

Joy Biswas
Joy Biswas

Reputation: 6527

When you add dynamic elements to DOM jQuery actually never cached that. You need to use delegated events so that when you add dynamic elements they are in scope and jQuery is listening

Case 1 (direct):

$("div#social .twitter").on("mouseenter focusin", function() {...});

== Hey! I want every span.twitter inside div#social to listen up: when you get mouseenter on, do X.

Case 2 (delegated):

$("div#social").on("mouseenter focusin", "span.twitter", function() {...});

== Hey, div#target! When any of your child elements which are "span.twitter" get mouseentered, do X with them.

Summary

In case 1, each of those spans has been individually given instructions. If new spans get created, they won't have heard the instruction and won't respond to clicks. Each span is directly responsible for its own events.

In case 2, only the container has been given the instruction; it is responsible for noticing clicks on behalf of its child elements. The work of catching events has been delegated.

Upvotes: 1

Related Questions