Marko
Marko

Reputation: 41

jQuery click function won't work on my div

i am having snow effect javascript. Wanted to make each flake clickable but i don't know what i am doing wrong here...

$('#flake').click(function(e) {  
  alert("Test");
});

Here is the code http://codepen.io/anon/pen/eBVJjB Thanks!

Upvotes: 3

Views: 210

Answers (3)

Ajay Narain Mathur
Ajay Narain Mathur

Reputation: 5466

There are couple of issues with your approach/ code.

  1. HTML document should have unique ID, therefore replace your id with class.

  2. The elements are dynamically added to the DOM and they don't exist at the time the script is executed therefore attach the event to document and delegate them to your flake class.

Working Snippet:

/**
 * jquery.snow - jQuery Snow Effect Plugin
 *
 * Available under MIT licence
 *
 * @version 1 (21. Jan 2012)
 * @author Ivan Lazarevic
 * @requires jQuery
 * @see http://workshop.rs
 *
 * @params minSize - min size of snowflake, 10 by default
 * @params maxSize - max size of snowflake, 20 by default
 * @params newOn - frequency in ms of appearing of new snowflake, 500 by default
 * @params flakeColor - color of snowflake, #FFFFFF by default
 * @example $.fn.snow({ maxSize: 200, newOn: 1000 });
 */
(function($) {

  $.fn.snow = function(options) {

    var $flake = $('<div class="flake" />').css({
        'position': 'absolute',
        'top': '-50px'
      }).html('&#10052;'),
      documentHeight = $(document).height(),
      documentWidth = $(document).width(),
      defaults = {
        minSize: 10,
        maxSize: 20,
        newOn: 500,
        flakeColor: "#FFFFFF"
      },
      options = $.extend({}, defaults, options);


    var interval = setInterval(function() {
      var startPositionLeft = Math.random() * documentWidth - 100,
        startOpacity = 0.5 + Math.random(),
        sizeFlake = options.minSize + Math.random() * options.maxSize,
        endPositionTop = documentHeight - 40,
        endPositionLeft = startPositionLeft - 100 + Math.random() * 200,
        durationFall = documentHeight * 10 + Math.random() * 5000;
      $flake
        .clone()
        .appendTo('body')
        .css({
          left: startPositionLeft,
          opacity: startOpacity,
          'font-size': sizeFlake,
          color: options.flakeColor
        })
        .animate({
            top: endPositionTop,
            left: endPositionLeft,
            opacity: 0.2
          },
          durationFall,
          'linear',
          function() {
            $(this).remove()
          }
        );
    }, options.newOn);

  };

})(jQuery);
body {
  background: black;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
  $(document).ready(function() {
    $.fn.snow();
  });
</script>
<script>
  $(document).on("click", '.flake', function(e) {
    alert("Test");
  });
</script>

Upvotes: 1

Dekel
Dekel

Reputation: 62536

  1. id attribute should be unique across elements in the document.
  2. The $('#flake').click(... code runs before the <div id="flake"> elements were added to the page, so the click event was not attached to them. You can fix this by using $(document).on('click', '#flake', function() {... });

Here is the fix to your code:

/**
 * jquery.snow - jQuery Snow Effect Plugin
 *
 * Available under MIT licence
 *
 * @version 1 (21. Jan 2012)
 * @author Ivan Lazarevic
 * @requires jQuery
 * @see http://workshop.rs
 *
 * @params minSize - min size of snowflake, 10 by default
 * @params maxSize - max size of snowflake, 20 by default
 * @params newOn - frequency in ms of appearing of new snowflake, 500 by default
 * @params flakeColor - color of snowflake, #FFFFFF by default
 * @example $.fn.snow({ maxSize: 200, newOn: 1000 });
 */
(function($){
  $.fn.snow = function(options){

    var $flake 			= $('<div class="flake" />').css({'position': 'absolute', 'top': '-50px'}).html('&#10052;'),
        documentHeight 	= $(document).height(),
        documentWidth	= $(document).width(),
        defaults		= {
          minSize		: 10,
          maxSize		: 20,
          newOn		: 500,
          flakeColor	: "#FFFFFF"
        },
        options			= $.extend({}, defaults, options);


    var interval		= setInterval( function(){
      var startPositionLeft 	= Math.random() * documentWidth - 100,
          startOpacity		= 0.5 + Math.random(),
          sizeFlake			= options.minSize + Math.random() * options.maxSize,
          endPositionTop		= documentHeight - 40,
          endPositionLeft		= startPositionLeft - 100 + Math.random() * 200,
          durationFall		= documentHeight * 10 + Math.random() * 5000;
      $flake
      .clone()
      .appendTo('body')
      .css(
        {
          left: startPositionLeft,
          opacity: startOpacity,
          'font-size': sizeFlake,
          color: options.flakeColor
        }
      )
      .animate(
        {
          top: endPositionTop,
          left: endPositionLeft,
          opacity: 0.2
        },
        durationFall,
        'linear',
        function() {
          $(this).remove()
        }
      );
    }, options.newOn);

  };

})(jQuery);

$(function(){
  $.fn.snow();
  $(document).on("click", '.flake',function() {  
    alert("Test");
  });
});
body {
  background: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 0

Travis J
Travis J

Reputation: 82267

There are several issues.

  • unique ids
  • event delegation

The flakes should have their own unique selector, which in this situation would probably be a class. <div class="flake">. ids should be unique, and in your codepen they are not.

The click event that you have is tied to only the one div with id flake that is present in the DOM at the time of assignment, which due to delay, may be none. Instead the event should be delegated to all flakes, preferably with the class selector described above

$("body").on("click",".flake",function(e){
    alert('clicked');
});

Upvotes: 5

Related Questions