Attach handler from another file

My folder structure looks like this.
-script1.js -script2.js -script3.js

Scripts 1 and 2 include script3 because the functionality they share is analogous. Meanwhile I need to attach a certain handler in script1 on page load and when page state is updated (IN ONLY SCRIPT1), so I have something like this in script3

// perform some async operation
// In the callback we have
if (location.href.indexOf('script1') > -1) {
       $('.nobody').each(function(item) {
        
       $(this).click(Closure(item).bind($(this)));
     })
   }

Closure lives in script 1 for initialization purposes but no matter how hard I try, I can’t successfully introduce him in script3. I’ve tried using AJAX to fetch it but it never makes it to the present scope.
All the scripts are wrapped in document.readyies but I’m using a closure to expose it from script1. Something like this:

var Closure = null;

$(document).ready(function () {
		Closure = function(context) {
			 return function (e) {
			e.preventDefault();

// uses a bunch of variables from the same script and leaves side effects

			return context;
		}
	}

       $('.nobody').each(function(item) {
			$(this).click(Closure(item).bind($(this)));
		})

Now, binding the closure this way works in script1 but not in script3 and throws no errors neither. Is there a better way of attaching it or do I move the functions individually? I was looking at something like autoloading but for JS.

If Closure is required by other scripts as well, why wait for document ready in the first place? I’d suggest to define it in a dedicated file where it exposes itself to the global object, like

(function() {
  window.Closure = function (context) {/* ... */}
})()

Then concatenate all your JS files in the desired order and serve them as a single main.js (or something). so that you can be sure about the order of execution (which also means fewer requests to the server).

Sorry for the late response. Would you advice that I sacrifice abstraction for just one tiny callback? Besides, if I had the luxury of channeling all my scripts into one file, will there still be any point exiling that function alone to its separate file, then including that file? Won’t it make sense to empty them all in the same jumbo file?

Anyway,

Because these other scripts do not require it only when they first load. When state change, they may need to update certain components, besides some other tasks script3 is meant to handle.

The binding was actually working all along. The problem was that I wasn’t rewrapping the fresh elements in class nobody. I forgot I had something like this at the top of script3
$("tr:not(first-child) td:nth-child(7) a:contains('nobody')").addClass('nobody');

So fresh elements weren’t getting wrapped before I called the bind statement.

Additionally, if anyone has this same problem, another way to workaround this is to use jQuery.proxy() like so

var export = null, Closure = {};

$(document).ready(function () {


		Closure =  {
		handler : function (e) {
			e.preventDefault();
// do a bunch of stuff with items on this page
}
	} // close obj
		
		
		export = $.proxy(Closure.handler, $('.nobody'))
		$('.nobody').on('click', export)
});

Then in script3, you can have

if (location.href.indexOf('staff') > -1) {
        t = $.proxy(Closure.handler, $('.nobody'))
        $('.nobody').on('click', export)
}

This will work as well.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.