JQuery: function for binding objects in for-loop with locking commit

I'm stuck here, any hint would be nice.
I have an array of Objects [] objects and an array of divnames []. My object has features like play () and stop (). The object and its functions have been tested in several situations; they work. Now im trying to iterate over divnames [] and assign the actions of the corresponding objects [] to hover the mouse, mouse, and click.
Closing issue, I fixed a solution that I found on another thread here in StackOverflow. It works. But the problem remains that mouseover actions, etc. Not assigned to partitions that load later. They work with objects that are on the page from the very beginning.
Here is what I have:

$(function(){ for (var i=0, len=divnames.length; i<len; i++) { if(divnames[i]){ (function( ) { // anonymous function to fix closures var index = i; // also needed to fix closures $('#'+divnames[index]).on("click", function() { objects[index].play(); loadContent(divnames[index]+".php"); }); })( ); // direct function execution to fix closures } } }); 

As stated above, the closing problem is fixed by two commented lines, leaving them further away, only ever applying the last execution of the for loop. Like now, it works.
But what does not work is that the click function should also be applied to the divs corresponding to the selector, but not yet loaded.
But this works if code with the same functionality does not repeat inside the for loop without fixing the closure, because this is the expected .on () behavior, if I understand correctly.

So how can I make both desired functions work?

Thanks for your time in advance.

---- ---- edit

Additional information on request:

 var divnames = []; divnames[0] = "home"; divnames[1] = "about"; divnames[2] = "projects"; function SpriteAnim (options) { var timerId = 0; var i = 0; this.status = 0; this.init = function () { var element = document.getElementById(options.elementId); element.style.width = options.width + "px"; element.style.height = options.height + "px"; element.style.backgroundRepeat = "no-repeat"; element.style.backgroundImage = "url(" + options.sprite + ")"; }; this.showFrame = function (which) { if (which < options.frames) { i = which; element = document.getElementById(options.elementId); element.style.backgroundPosition = "0px -" + which * options.height + "px"; } }; this.play = function () { this.status = 2; timerId = setInterval(function () { if (i < (options.frames - 1)) { i++; element = document.getElementById(options.elementId); element.style.backgroundPosition = "0px -" + i * options.height + "px"; } else { clearInterval(timerId); this.status = 1; } }, 100); }; } 

As you probably already guessed, the objects [] array contains 3 SpriteAnim objects in objects [0], objects [1], objects [2].

 objects[0] = new SpriteAnim({ width: 7, height: 7, frames: 8, sprite: "myanim1.png", elementId: "anim0" }); objects[1] = new SpriteAnim({ width: 7, height: 7, frames: 8, sprite: "myanim1.png", elementId: "anim1" }); objects[2] = new SpriteAnim({ width: 7, height: 7, frames: 8, sprite: "myanim2.png", elementId: "anim2" }); 
+2
source share
2 answers

This is because the index is declared outside of your binding statement. When a click goes into this call, it does not know what objects [index] are.

If you want to keep the same structure, redesign your function as follows:

 $(function(){ for (var i=0, len=divnames.length; i<len; i++) { if(divnames[i]){ (function( ) { // anonymous function to fix closures var index = i; // also needed to fix closures $('#'+divnames[index]).on("click", function(e) { switch ($(e.id).attr('name')){ case 'home': objects[0].play(); loadContent('home.php'); break; case 'about': // do same case 'projects': // do same default: break; } }); })( ); // direct function execution to fix closures } } }); 

Really, you should do this:

 $(document).on('click','div[name=home],div[name=projects],div[name=about]', function(){ var name = $(this).attr('name'); switch (name){ case 'home': objects[0].play(); break; // and so on } loadContent(name + '.php'); }); 

EDIT:

When you click on a div, this is all he will know about:

 objects[index].play(); loadContent(divnames[index]+".php"); 
+1
source

You need to use event delegation and listen for these events on the parent element, and not on the elements themselves. That way, if you add new items later, you won’t need to rewrite them.

 $("#buttons").on("click", ".button", function(){ console.log("You clicked on a .button element."); }); 

In this case, we attach to the click event on #buttons , but only when the caller matches the .button selector. Your markup would be something like this:

 <div id="buttons"> <a class="button">Foo</a> <a class="button">Bar</a> </div> 

When a click occurs on any of the .button elements and bubbles up to the parent #buttons , it will be intercepted and the handler will be launched.

+4
source

Source: https://habr.com/ru/post/1442512/


All Articles