Manipulating dynamically created elements?

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 1417 Views - Last Post: 12 May 2015 - 09:01 AM

#1 Soulyy   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 30
  • Joined: 12-February 15

Manipulating dynamically created elements?

Posted 11 May 2015 - 11:54 PM

Hello. I'm working on a project that will create a slideshow from a json file. So I build an unordered list dynamically and then call two jquery plugins from there. The problem is that I can't seem to access the dynamically created elements (such as the images).

So if I dynamically create all the children in the UL (note that the UL element is NOT dynamically created):
<ul id="gallerizeRoot" class="gallerizeCss">
     <li><img src="cat.png" caption="A small cat" alt="Image" /></a></li>
     <li><img src="lamb.jpg" caption="Boo boo bee boo" alt="Image" /></a></li>
     <li><img src="h1.jpg" caption="H1z1" alt="Image" /></li>
     <li><img src="cashmoney.jpg" caption="Money" alt="Image" /></li>
     <li><img src="cards.jpg" caption="Aces high" alt="Image" /></li>
     <li><img src="walkingbread.jpg" caption="The Walking Bread" alt="Image" /></li>
</ul>

How can I access the images to apply effects like hide, fade in, fade out, ect?

I'm trying to call this function on all of the images in the list
$this.wrap('<div class="' + settings.Class + '"></div>').parent().css({
                'height': imageHeight,
                'width': imageWidth
            });

            $this.after('<span>' + caption + '</span>');

            $this.css({
                'display': 'block'
            }).next().css({
                'position': 'absolute',
                'margin-top': '-' + captionHeight + 'px',
                'width': imageWidth + 'px',
                'height': captionHeight + 'px',
                'background': 'rgba(' + settings.captRed + ',' +
                    settings.captGreen + ',' +
                    settings.captBlue + ',' +
                    settings.opacity + ')',
                'text-align': settings.textAlign,
                'font-size': settings.textSize
            }).attr('class', 'captionizer').hide();

            if (settings.hover) {
                $this.parent().hover(
                    function () {
                        $this.next().fadeTo(100, settings.opacity);
                    },
                    function () {
                        $this.next().fadeTo(100, 0);
                    });
            }
            else {
                $this.next().fadeTo(1, settings.opacity);
            };


with this (where $this is the UL element):
$this.children('img').Captionize();


Is This A Good Question/Topic? 0
  • +

Replies To: Manipulating dynamically created elements?

#2 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4303
  • View blog
  • Posts: 13,677
  • Joined: 08-June 10

Re: Manipulating dynamically created elements?

Posted 11 May 2015 - 11:59 PM

assuming that $this maps to the <ul>, your call to children() returns an empty set since the images are not children, but "grandchildren" of <ul>. better use the find() method.
Was This Post Helpful? 0
  • +
  • -

#3 Soulyy   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 30
  • Joined: 12-February 15

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 12:09 AM

View PostDormilich, on 11 May 2015 - 11:59 PM, said:

assuming that $this maps to the <ul>, your call to children() returns an empty set since the images are not children, but "grandchildren" of <ul>. better use the find() method.

Thank for you hasty reply however this does not solve my issue. I did some investigating and when I used $this.find('img').Captionize() for the Captionize function below, there are two alerts. One fires and one does not. Any ideas?

$.fn.Captionize = function (options) {
        var defaults = {
            captRed: 255,
            captGreen: 255,
            captBlue: 255,
            hover: true,
            cssClass: 'captContainer',
            opacity: 0.75,
            textSize: '18pt',
            textAlign: 'center'
        };

        var settings = $.extend(defaults, options);
	
        alert('You will see me');

        return this.each(function () {
            var $this = $(this);
            var caption = $this.attr('caption');
            var imageWidth = $this.width();
            var imageHeight = $this.height();
            var captionHeight = (imageHeight / 4);
			
            alert('You will not see me');

            $this.wrap('<div class="' + settings.Class + '"></div>').parent().css({
                'height': imageHeight,
                'width': imageWidth
            });

            $this.after('<span>' + caption + '</span>');

            $this.css({
                'display': 'block'
            }).next().css({
                'position': 'absolute',
                'margin-top': '-' + captionHeight + 'px',
                'width': imageWidth + 'px',
                'height': captionHeight + 'px',
                'background': 'rgba(' + settings.captRed + ',' +
                    settings.captGreen + ',' +
                    settings.captBlue + ',' +
                    settings.opacity + ')',
                'text-align': settings.textAlign,
                'font-size': settings.textSize
            }).attr('class', 'captionizer').hide();

            if (settings.hover) {
                $this.parent().hover(
                    function () {
                        $this.next().fadeTo(100, settings.opacity);
                    },
                    function () {
                        $this.next().fadeTo(100, 0);
                    });
            }
            else {
                $this.next().fadeTo(1, settings.opacity);
            };
        });
    };


Sorry for the double post but I think I should post the plugin as a whole.

(function ($) {
	$.fn.Captionize = function (options) {
        var defaults = {
            captRed: 255,
            captGreen: 255,
            captBlue: 255,
            hover: true,
            cssClass: 'captContainer',
            opacity: 0.75,
            textSize: '18pt',
            textAlign: 'center'
        };

        var settings = $.extend(defaults, options);
		
        return this.each(function () {
            var $this = $(this);
            var caption = $this.attr('caption');
            var imageWidth = $this.width();
            var imageHeight = $this.height();
            var captionHeight = (imageHeight / 4);
			
            $this.wrap('<div class="' + settings.Class + '"></div>').parent().css({
                'height': imageHeight,
                'width': imageWidth
            });

            $this.after('<span>' + caption + '</span>');

            $this.css({
                'display': 'block'
            }).next().css({
                'position': 'absolute',
                'margin-top': '-' + captionHeight + 'px',
                'width': imageWidth + 'px',
                'height': captionHeight + 'px',
                'background': 'rgba(' + settings.captRed + ',' +
                    settings.captGreen + ',' +
                    settings.captBlue + ',' +
                    settings.opacity + ')',
                'text-align': settings.textAlign,
                'font-size': settings.textSize
            }).attr('class', 'captionizer').hide();

            if (settings.hover) {
                $this.parent().hover(
                    function () {
                        $this.next().fadeTo(100, settings.opacity);
                    },
                    function () {
                        $this.next().fadeTo(100, 0);
                    });
            }
            else {
                $this.next().fadeTo(1, settings.opacity);
            };
        });
    };
	
    $.fn.Gallerize = function (options) {
        var defaults = {
			swapInterval: 5000
        };

        var settings = $.extend(defaults, options);
		
        return this.each(function () {
			var $this = $(this);
			var i = 0;
			var length;
			var current;
			
			console.log("Start Gallery");
			$this.children('li:gt(0)').hide();
			
			ImageSwap = function(){
				$($this.children('li').get(i)).fadeOut();
				
				i++;
				// manage overflow
				if (i > length - 1) { i = 0; }
				
				$($this.children('li').get(i)).fadeIn();
			}
			
			length = $this.children('li').length;
			setInterval(ImageSwap, settings.swapInterval);
        });
    };
	
	$.fn.BuildSlide = function (jsonURL) {

        return this.each(function () {
            var $this = $(this);
			
			//$this.append('<ul id="gallerizeRoot" class="gallerizeCss"></ul>')
			
			$.getJSON(jsonURL, function(data) {
				$.each(data, function(key, val) {
					$this.append('<li><img src="' + val.File + '" caption="' + val.Caption + '" alt="Image"></li>');
				})
			});

			$this.find('img').Captionize();
			$this.Gallerize();
        });
    };
}(jQuery));

Was This Post Helpful? 0
  • +
  • -

#4 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4303
  • View blog
  • Posts: 13,677
  • Joined: 08-June 10

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 12:20 AM

Quote

One fires and one does not. Any ideas?

check the Error Console and set breakpoints to see where the code flows.
Was This Post Helpful? 0
  • +
  • -

#5 Soulyy   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 30
  • Joined: 12-February 15

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 12:36 AM

I'm not getting any errors and all lines are fired except for return each of captionize, most likely because it's not finding the image elements and just returning instantly. Also only the first image in the slideshow is doing any fading in/out.
Was This Post Helpful? 0
  • +
  • -

#6 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4303
  • View blog
  • Posts: 13,677
  • Joined: 08-June 10

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 12:45 AM

Quote

most likely because it's not finding the image elements and just returning instantly

then you should log some this and $this to see what elements you’re operating on.
Was This Post Helpful? 0
  • +
  • -

#7 Soulyy   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 30
  • Joined: 12-February 15

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 01:18 AM

this and $this are both the UL element with ID gallery.
Was This Post Helpful? 0
  • +
  • -

#8 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4303
  • View blog
  • Posts: 13,677
  • Joined: 08-June 10

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 01:22 AM

no wonder it doesn’t work. you cannot apply the image settings on the <ul>.
Was This Post Helpful? 0
  • +
  • -

#9 Soulyy   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 30
  • Joined: 12-February 15

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 01:28 AM

You lost me. this and $this are never given any value in the Captionize function. this and $this are the ul element in the BuildSlide function.

I'm not sure what you mean.
Was This Post Helpful? 0
  • +
  • -

#10 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4303
  • View blog
  • Posts: 13,677
  • Joined: 08-June 10

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 01:35 AM

you said alert('You will not see me'); is never called. that call is placed in this.each(). so it seems that is the crucial part why it fails. therefore you need to know what that this refers to to know why the callback is not fired.
Was This Post Helpful? 0
  • +
  • -

#11 Soulyy   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 30
  • Joined: 12-February 15

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 07:28 AM

I see. "this" is empty because $this.find('img') is not finding any of the image elements that I append. When I log this in Captionize I get this:

prevobject: m.fn.init[1]
context: ul
selector: img
length: 0
Was This Post Helpful? 0
  • +
  • -

#12 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4303
  • View blog
  • Posts: 13,677
  • Joined: 08-June 10

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 07:31 AM

that’s because—at that time—you have not created any images. they will be added when the AJAX completes … later.
Was This Post Helpful? 0
  • +
  • -

#13 Soulyy   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 30
  • Joined: 12-February 15

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 07:39 AM

Yes, which brings me right back to my original question. How can I access these elements from my plugin? Or can't I?
Was This Post Helpful? 0
  • +
  • -

#14 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4303
  • View blog
  • Posts: 13,677
  • Joined: 08-June 10

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 07:44 AM

you wait until you have created them.

it’s the asynchonousness of AJAX that puts you off here.

temporarly modify your code to see what it executed when:
	$.fn.BuildSlide = function (jsonURL) {

        return this.each(function () {
            var $this = $(this);
			
			// before AJAX
			console.log('before');
			
			$.getJSON(jsonURL, function(data) {
				$.each(data, function(key, val) {
					$this.append('<li><img src="' + val.File + '" caption="' + val.Caption + '" alt="Image"></li>');

					// on completion of AJAX
					console.log('complete');

				})
			});

			// after AJAX
			console.log('after');

			$this.find('img').Captionize();
			$this.Gallerize();
        });
    };


Was This Post Helpful? 1
  • +
  • -

#15 Soulyy   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 30
  • Joined: 12-February 15

Re: Manipulating dynamically created elements?

Posted 12 May 2015 - 08:19 AM

Oh wow.

I added this before the getjson. Thanks.
$.ajaxSetup({
	async: false
});

This post has been edited by Soulyy: 12 May 2015 - 08:20 AM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2