I have two divs in my app and I want them to have custom functions with the same signature, but with different actions, so that I could store the "current" div in a variable, and just call something like:
我在我的应用程序中有两个div,我希望它们具有相同签名的自定义函数,但具有不同的操作,以便我可以将“当前”div存储在变量中,并且只需调用类似于:
myCurrentDiv.theFunction(someEventData);
and have the corresponding methods fired up.
How can I do that using jQuery?
我怎么能用jQuery做到这一点?
I tried doing something like:
我尝试过这样的事情:
$("#myFirstDiv").theFunction = function() {
alert("theFunction on firstDiv");
}
$("#mySecondDiv").theFunction = function() {
alert("theFunction on secondDiv");
}
6 个解决方案
#1
38
jQuery's philosophy is opposite to what you want: jQuery doesn't extends any existent types/objects with new attributes or methods; it implements all inside itself.
jQuery的理念与你想要的相反:jQuery不会使用新的属性或方法扩展任何现有的类型/对象;它实现了所有内部。
But if you want to do it with jQuery, you have few different ways:
但是如果你想用jQuery做,你有几种不同的方式:
-
JavaScript way:
$("#mySecondDiv")[0].theFunction = function(a, b) { /* ... */ }
-
jQuery.data:
$("#mySecondDiv").data({ theFunction: function(a, b) { /* ... */ } }); $("#mySecondDiv").data("theFunction")(1, 2)
-
Custom event:
$("#mySecondDiv").bind('my-event', function(event, a ,b) { /* ... */ }); $("#mySecondDiv").trigger('my-event', [1, 2]);
JavaScript方式:$(“#mySecondDiv”)[0] .theFunction = function(a,b){/ * ... * /}
jQuery.data:$(“#mySecondDiv”)。data({theFunction:function(a,b){/ * ... * /}}); $(“#mySecondDiv”)。data(“theFunction”)(1,2)
自定义事件:$(“#mySecondDiv”)。bind('my-event',function(event,a,b){/ * ... * /}); $(“#mySecondDiv”)。trigger('my-event',[1,2]);
#2
3
You can use jQuery.data to store data associated with a specific element.
您可以使用jQuery.data存储与特定元素关联的数据。
For example:
var div = $("#myFirstDiv")[0];
jQuery.data(div, "theFunction", function() {
alert("theFunction on firstDiv");
});
#3
2
Looks like what you want is a custom event in jquery...
看起来你想要的是jquery中的自定义事件......
$('#myFirstDiv').bind('theFunction', function(e) {
alert('theFunction on firstDiv');
});
$('#mySecondDiv').bind('theFunction', function(e) {
alert('theFunction on firstDiv');
});
$('#myFirstDiv').trigger('theFunction');
Here's a working fiddle to show you the example: http://jsfiddle.net/XkutP/
这是一个工作小提示,向您展示示例:http://jsfiddle.net/XkutP/
#4
#5
0
Build a Super-jQuery object
You can use also use $.fn.extend()
to bind multiple methods (functions) at once . . . and if you really wanna get into it, you can use $.fn.extend()
to recreate the jQuery elements as powerfully customized objects which can then be used to automate and manage DOM elements that are (logically/virtually) part of the same object or tool. (PS: I made up that "Super-jQuery" phrase--that's not real jargon . . . well, maybe it is now.)
您也可以使用$ .fn.extend()一次绑定多个方法(函数)。 。 。如果你真的想进入它,你可以使用$ .fn.extend()重新创建jQuery元素作为强大的自定义对象,然后可以用来自动化和管理(逻辑上/虚拟地)部分相同的DOM元素对象或工具。 (PS:我编写了“Super-jQuery”这句话 - 这不是真正的行话......好吧,也许现在就是这样。)
The one I'm working on now is an Excel file uploader. I'll recreate/copy some of it here to give you an idea:
我现在正在处理的是Excel文件上传器。我将在这里重新创建/复制其中一些以给你一个想法:
HTML
<div id="uploader" class="uploader">
<div class="uploader-item-title uploader-item title">
<span class="title-item-value title-item value">
Excel File Uploader
</span>
</div>
<div class="uploader-item-subtitle uploader-item subtitle">
<span class="subtitle-item-value subtitle-item value">
Uploads Excel files
</span>
</div>
<div id="formatError" style="width:100%;">
<div class="error-message">
<!-- General-purpose error-message container (registered on server-side) -->
</div>
</div>
<div id="messagebox" class="uploader-item-messagebox uploader-item messagebox hidden" style="width:100%;">
<span class="messagebox-item-value messagebox-item value">
<!-- Enter any messages/alerts here that you would like to display to the user -->
</span>
</div>
<div id="dropzone" dropzone="copy f:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" class="uploader-item-dropzone uploader-item dropzone">
<span class="dropzone-item-notes dropzone-item notes">
Drag and drop your Excel file(s) here to begin the upload process.
</span>
<div id="fileSummaryTable" class="dropzone-item-filesummary dropzone-item filesummary hidden">
<table class="filesummary-item-table filesummary-item table">
<!-- Display excel file information here. -->
</table>
</div>
<div id="pbar" class="dropzone-item-pbar dropzone-item pbar hidden">
<div class="pbar-item-filler pbar-item filler">
</div>
</div>
</div>
<div id="fallbackUploader" class="uploader-item-fallbackuploader uploader-item fallbackuploader invisible">
<!-- some asp code you don't need to see :) -->
</div>
</div>
Javascript
var oUploader = (function () {
function oUploader(opts) { // primary object constructor
var primaryOpts = opts || {}; // Optional arguments
var superObj_primary = $('#uploader'); // primary super object
var that = this;
var superObj_secondary = (function () {
function superObj_secondary(secondaryOpts) { // secondary object constructor
// =================================================================================
// step 10 = get the default options' values
// =================================================================================
var self = this,
o = secondaryOpts || {},
title_val = o.title || 'Excel File Uploader',
subtitle_val = o.subtitle || 'Uploads Excel files',
notes_val = o.notes || 'Drag and drop your Excel file(s) here to begin the upload process.';
// =================================================================================
// step 20 = create your public properties and children here.
// =================================================================================
self.dropzone = $('.uploader-item-dropzone');
self.dropzone.pbar = $('.dropzone-item-pbar');
self.dropzone.fileSummaryTable = $('#fileSummaryTable');
self.fallbackUploader = $('#fallbackUploader');
self.messagebox = $('.uploader-item-messagebox');
// =================================================================================
// step 30 = create your private properties and children here.
// =================================================================================
var progress_ele = self.dropzone.pbar.children('.pbar-item-filler'), // inner-progressbar element
fileSummaryTable_table_ele = self.dropzone.fileSummaryTable.children('table.filesummary-item-table'), // inner table for the file summary table
title_ele = $('.uploader-item-title'), // title container for the main uploader object
title_value_ele = title_ele.children('.title-item-value'), // inner value object for the title
subtitle_ele = $('.uploader-item-subtitle'), // subtitle container for the main uploader object
subtitle_value_ele = subtitle_ele.children('subtitle-item-value'), // inner value object for the subtitle
notes_value_ele = self.dropzone.children('.dropzone-item-notes'), // element containing the notes text
messagebox_ele = $('.uploader-item-messagebox'), // element containing the message/alert container
messagebox_value_ele = messagebox_ele.children('.messagebox-item-value'); // element containing the message/alert text
// =================================================================================
// step 30 = create your public get/set functions for private properties
// =================================================================================
// ------------------------------------------------------------
// get/set function for private properties of uploader
// ------------------------------------------------------------
Object.defineProperties(superObj_primary,
{
// gets or sets the title of the uploader
'title': {
'get': function () { return title_value_ele.text(); },
'set': function (val) { title_value_ele.text(val); }
},
// gets or sets the sub-title of the uploader
'subtitle': {
'get': function () { return subtitle_value_ele.text(); },
'set': function (val) { subtitle_value_ele.text(val); }
},
// either (1) gets the msg value, (2) sets the msg and grows
// in the container, or (3) clears the msg value and
// shrinks out the container.
'msg': {
'get': function () { return messagebox_value_ele.text(); },
'set': function (val) {
if (val.length) {
messagebox_value_ele.text(val);
messagebox_ele.xGrowIn(null,null,function () { // fadeObj = custom jQuery plugin created elsewhere
messagebox_value_ele.fadeObj('show',100); // fadeObj = custom jQuery plugin created elsewhere
});
} else {
messagebox_value_ele.fadeObj('invisible',100, function () {
messagebox_ele.xShrinkOut(null,function () {
messagebox_value_ele.text('.');
});
});
}
}
}
});
// ------------------------------------------------------------
// get/set function for progressbar object
// ------------------------------------------------------------
Object.defineProperties(self.dropzone.pbar,
{
// gets or sets the width and data-progress attribute of the inner progress bar.
'progress': {
'get': function () { return (parseInt(Math.round(progress_ele.attr('aria-valuenow'))) || 0); },
'set': function (val) { progress_ele.progressbar({ value: Math.round(val) }); }
}
});
// =================================================================================
// step 40 = create your public methods here.
// =================================================================================
// ------------------------------------------------------------
// hide all of the primary uploader elements and show the fallback elements.
// ------------------------------------------------------------
self.switchToFallback = function () {
// hide the primary uploader elements
self.dropzone.addClass('hidden');
self.dropzone.fileSummaryTable.addClass('hidden');
self.dropzone.pbar.addClass('hidden');
// show the fallback uploader elements
self.fallbackUploader.removeClass('invisible');
};
// ------------------------------------------------------------
// show the primary dropzone and add the necessary event listeners
// ------------------------------------------------------------
self.enableDropzone = function () {
self.dropzone.removeClass('hidden');
// init event handlers
self.dropzone.addEventListener("dragenter", dragEnter, false);
self.dropzone.addEventListener("dragexit", dragExit, false);
self.dropzone.addEventListener("dragleave", dragExit, false);
self.dropzone.addEventListener("dragover", dragOver, false);
self.dropzone.addEventListener("drop", drop, false);
// define drag and drop events
function dragEnter(evt) {
evt.stopPropagation();
evt.preventDefault();
}
function dragExit(evt) {
evt.stopPropagation();
evt.preventDefault();
self.dropzone.removeClass("active-dropzone");
}
function dragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
self.dropzone.addClass("active-dropzone");
};
function drop(evt) {
evt.stopPropagation();
evt.preventDefault();
self.dropzone.removeClass("active-dropzone");
superObj_primary.msg = ''; // hide any messages.
var files = evt.dataTransfer.files;
var count = files.length;
// Only call the handler if 1 file was dropped.
if (count == 1) {
handleFiles(files);
}
else if (count > 1) {
// still working on this part :-/
}
}
};
// ------------------------------------------------------------
// Method to fill the pbar to the max value (i.e., 100%)
// ------------------------------------------------------------
self.dropzone.pbar.complete = function () {
progress_ele.progressbar({ value: 100 });
};
// ------------------------------------------------------------
// Check if FileAPI and XmlHttpRequest.upload are supported.
// ------------------------------------------------------------
self.hasDndSupport = function () {
return (window.File && window.FileReader && window.FileList && window.Blob && new XMLHttpRequest().upload);
};
};
return superObj_secondary;
})();
return $.fn.extend(superObj_primary, new superObj_secondary());
};
return oUploader;
})();
var uploader = new oUploader(); // now we just init the new object and there we go. You can go to your console and try out the commands.
// **Note: If you are doing this in JsFiddle, you'll have to change the scope of the browser console from "<top frame>" to "result( fiddle.jshell.net/)".
Additional Automation
This object works as long as I build the corresponding HTML objects, but usually when I'm done building these, I'll add an additional section to them wherein I create all the HTML components via javascript during the object's construction. The purpose for that, of course, is to make the tool more easily deploy-able.
只要我构建了相应的HTML对象,这个对象就可以工作,但通常当我构建这些对象时,我会向它们添加一个额外的部分,其中我在对象构造期间通过javascript创建所有HTML组件。当然,其目的是使工具更易于部署。
#6
0
You can also try this , it's a bit ugly but it works :)
你也可以尝试这个,它有点难看,但它的工作:)
The custom object :
自定义对象:
$.fn.epicModule = function (pMessage) {
var object = $(this)[0];
object.__construct = function (pMessage) {
//TODO
this.message = pMessage;
}
object.callMeDirectly = function () {
alert(this.message);
}
object.__construct(pMessage);
}
Init Module :
初始模块:
$(".myHtmlEl").epicModule("Hallo World");
Calling the function :
调用功能:
$(".myHtmlEl")[0].callMeDirectly();
#1
38
jQuery's philosophy is opposite to what you want: jQuery doesn't extends any existent types/objects with new attributes or methods; it implements all inside itself.
jQuery的理念与你想要的相反:jQuery不会使用新的属性或方法扩展任何现有的类型/对象;它实现了所有内部。
But if you want to do it with jQuery, you have few different ways:
但是如果你想用jQuery做,你有几种不同的方式:
-
JavaScript way:
$("#mySecondDiv")[0].theFunction = function(a, b) { /* ... */ }
-
jQuery.data:
$("#mySecondDiv").data({ theFunction: function(a, b) { /* ... */ } }); $("#mySecondDiv").data("theFunction")(1, 2)
-
Custom event:
$("#mySecondDiv").bind('my-event', function(event, a ,b) { /* ... */ }); $("#mySecondDiv").trigger('my-event', [1, 2]);
JavaScript方式:$(“#mySecondDiv”)[0] .theFunction = function(a,b){/ * ... * /}
jQuery.data:$(“#mySecondDiv”)。data({theFunction:function(a,b){/ * ... * /}}); $(“#mySecondDiv”)。data(“theFunction”)(1,2)
自定义事件:$(“#mySecondDiv”)。bind('my-event',function(event,a,b){/ * ... * /}); $(“#mySecondDiv”)。trigger('my-event',[1,2]);
#2
3
You can use jQuery.data to store data associated with a specific element.
您可以使用jQuery.data存储与特定元素关联的数据。
For example:
var div = $("#myFirstDiv")[0];
jQuery.data(div, "theFunction", function() {
alert("theFunction on firstDiv");
});
#3
2
Looks like what you want is a custom event in jquery...
看起来你想要的是jquery中的自定义事件......
$('#myFirstDiv').bind('theFunction', function(e) {
alert('theFunction on firstDiv');
});
$('#mySecondDiv').bind('theFunction', function(e) {
alert('theFunction on firstDiv');
});
$('#myFirstDiv').trigger('theFunction');
Here's a working fiddle to show you the example: http://jsfiddle.net/XkutP/
这是一个工作小提示,向您展示示例:http://jsfiddle.net/XkutP/
#4
0
Use .bind and a custom function then .trigger to invoke the function.
使用.bind和自定义函数然后.trigger来调用该函数。
#5
0
Build a Super-jQuery object
You can use also use $.fn.extend()
to bind multiple methods (functions) at once . . . and if you really wanna get into it, you can use $.fn.extend()
to recreate the jQuery elements as powerfully customized objects which can then be used to automate and manage DOM elements that are (logically/virtually) part of the same object or tool. (PS: I made up that "Super-jQuery" phrase--that's not real jargon . . . well, maybe it is now.)
您也可以使用$ .fn.extend()一次绑定多个方法(函数)。 。 。如果你真的想进入它,你可以使用$ .fn.extend()重新创建jQuery元素作为强大的自定义对象,然后可以用来自动化和管理(逻辑上/虚拟地)部分相同的DOM元素对象或工具。 (PS:我编写了“Super-jQuery”这句话 - 这不是真正的行话......好吧,也许现在就是这样。)
The one I'm working on now is an Excel file uploader. I'll recreate/copy some of it here to give you an idea:
我现在正在处理的是Excel文件上传器。我将在这里重新创建/复制其中一些以给你一个想法:
HTML
<div id="uploader" class="uploader">
<div class="uploader-item-title uploader-item title">
<span class="title-item-value title-item value">
Excel File Uploader
</span>
</div>
<div class="uploader-item-subtitle uploader-item subtitle">
<span class="subtitle-item-value subtitle-item value">
Uploads Excel files
</span>
</div>
<div id="formatError" style="width:100%;">
<div class="error-message">
<!-- General-purpose error-message container (registered on server-side) -->
</div>
</div>
<div id="messagebox" class="uploader-item-messagebox uploader-item messagebox hidden" style="width:100%;">
<span class="messagebox-item-value messagebox-item value">
<!-- Enter any messages/alerts here that you would like to display to the user -->
</span>
</div>
<div id="dropzone" dropzone="copy f:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" class="uploader-item-dropzone uploader-item dropzone">
<span class="dropzone-item-notes dropzone-item notes">
Drag and drop your Excel file(s) here to begin the upload process.
</span>
<div id="fileSummaryTable" class="dropzone-item-filesummary dropzone-item filesummary hidden">
<table class="filesummary-item-table filesummary-item table">
<!-- Display excel file information here. -->
</table>
</div>
<div id="pbar" class="dropzone-item-pbar dropzone-item pbar hidden">
<div class="pbar-item-filler pbar-item filler">
</div>
</div>
</div>
<div id="fallbackUploader" class="uploader-item-fallbackuploader uploader-item fallbackuploader invisible">
<!-- some asp code you don't need to see :) -->
</div>
</div>
Javascript
var oUploader = (function () {
function oUploader(opts) { // primary object constructor
var primaryOpts = opts || {}; // Optional arguments
var superObj_primary = $('#uploader'); // primary super object
var that = this;
var superObj_secondary = (function () {
function superObj_secondary(secondaryOpts) { // secondary object constructor
// =================================================================================
// step 10 = get the default options' values
// =================================================================================
var self = this,
o = secondaryOpts || {},
title_val = o.title || 'Excel File Uploader',
subtitle_val = o.subtitle || 'Uploads Excel files',
notes_val = o.notes || 'Drag and drop your Excel file(s) here to begin the upload process.';
// =================================================================================
// step 20 = create your public properties and children here.
// =================================================================================
self.dropzone = $('.uploader-item-dropzone');
self.dropzone.pbar = $('.dropzone-item-pbar');
self.dropzone.fileSummaryTable = $('#fileSummaryTable');
self.fallbackUploader = $('#fallbackUploader');
self.messagebox = $('.uploader-item-messagebox');
// =================================================================================
// step 30 = create your private properties and children here.
// =================================================================================
var progress_ele = self.dropzone.pbar.children('.pbar-item-filler'), // inner-progressbar element
fileSummaryTable_table_ele = self.dropzone.fileSummaryTable.children('table.filesummary-item-table'), // inner table for the file summary table
title_ele = $('.uploader-item-title'), // title container for the main uploader object
title_value_ele = title_ele.children('.title-item-value'), // inner value object for the title
subtitle_ele = $('.uploader-item-subtitle'), // subtitle container for the main uploader object
subtitle_value_ele = subtitle_ele.children('subtitle-item-value'), // inner value object for the subtitle
notes_value_ele = self.dropzone.children('.dropzone-item-notes'), // element containing the notes text
messagebox_ele = $('.uploader-item-messagebox'), // element containing the message/alert container
messagebox_value_ele = messagebox_ele.children('.messagebox-item-value'); // element containing the message/alert text
// =================================================================================
// step 30 = create your public get/set functions for private properties
// =================================================================================
// ------------------------------------------------------------
// get/set function for private properties of uploader
// ------------------------------------------------------------
Object.defineProperties(superObj_primary,
{
// gets or sets the title of the uploader
'title': {
'get': function () { return title_value_ele.text(); },
'set': function (val) { title_value_ele.text(val); }
},
// gets or sets the sub-title of the uploader
'subtitle': {
'get': function () { return subtitle_value_ele.text(); },
'set': function (val) { subtitle_value_ele.text(val); }
},
// either (1) gets the msg value, (2) sets the msg and grows
// in the container, or (3) clears the msg value and
// shrinks out the container.
'msg': {
'get': function () { return messagebox_value_ele.text(); },
'set': function (val) {
if (val.length) {
messagebox_value_ele.text(val);
messagebox_ele.xGrowIn(null,null,function () { // fadeObj = custom jQuery plugin created elsewhere
messagebox_value_ele.fadeObj('show',100); // fadeObj = custom jQuery plugin created elsewhere
});
} else {
messagebox_value_ele.fadeObj('invisible',100, function () {
messagebox_ele.xShrinkOut(null,function () {
messagebox_value_ele.text('.');
});
});
}
}
}
});
// ------------------------------------------------------------
// get/set function for progressbar object
// ------------------------------------------------------------
Object.defineProperties(self.dropzone.pbar,
{
// gets or sets the width and data-progress attribute of the inner progress bar.
'progress': {
'get': function () { return (parseInt(Math.round(progress_ele.attr('aria-valuenow'))) || 0); },
'set': function (val) { progress_ele.progressbar({ value: Math.round(val) }); }
}
});
// =================================================================================
// step 40 = create your public methods here.
// =================================================================================
// ------------------------------------------------------------
// hide all of the primary uploader elements and show the fallback elements.
// ------------------------------------------------------------
self.switchToFallback = function () {
// hide the primary uploader elements
self.dropzone.addClass('hidden');
self.dropzone.fileSummaryTable.addClass('hidden');
self.dropzone.pbar.addClass('hidden');
// show the fallback uploader elements
self.fallbackUploader.removeClass('invisible');
};
// ------------------------------------------------------------
// show the primary dropzone and add the necessary event listeners
// ------------------------------------------------------------
self.enableDropzone = function () {
self.dropzone.removeClass('hidden');
// init event handlers
self.dropzone.addEventListener("dragenter", dragEnter, false);
self.dropzone.addEventListener("dragexit", dragExit, false);
self.dropzone.addEventListener("dragleave", dragExit, false);
self.dropzone.addEventListener("dragover", dragOver, false);
self.dropzone.addEventListener("drop", drop, false);
// define drag and drop events
function dragEnter(evt) {
evt.stopPropagation();
evt.preventDefault();
}
function dragExit(evt) {
evt.stopPropagation();
evt.preventDefault();
self.dropzone.removeClass("active-dropzone");
}
function dragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
self.dropzone.addClass("active-dropzone");
};
function drop(evt) {
evt.stopPropagation();
evt.preventDefault();
self.dropzone.removeClass("active-dropzone");
superObj_primary.msg = ''; // hide any messages.
var files = evt.dataTransfer.files;
var count = files.length;
// Only call the handler if 1 file was dropped.
if (count == 1) {
handleFiles(files);
}
else if (count > 1) {
// still working on this part :-/
}
}
};
// ------------------------------------------------------------
// Method to fill the pbar to the max value (i.e., 100%)
// ------------------------------------------------------------
self.dropzone.pbar.complete = function () {
progress_ele.progressbar({ value: 100 });
};
// ------------------------------------------------------------
// Check if FileAPI and XmlHttpRequest.upload are supported.
// ------------------------------------------------------------
self.hasDndSupport = function () {
return (window.File && window.FileReader && window.FileList && window.Blob && new XMLHttpRequest().upload);
};
};
return superObj_secondary;
})();
return $.fn.extend(superObj_primary, new superObj_secondary());
};
return oUploader;
})();
var uploader = new oUploader(); // now we just init the new object and there we go. You can go to your console and try out the commands.
// **Note: If you are doing this in JsFiddle, you'll have to change the scope of the browser console from "<top frame>" to "result( fiddle.jshell.net/)".
Additional Automation
This object works as long as I build the corresponding HTML objects, but usually when I'm done building these, I'll add an additional section to them wherein I create all the HTML components via javascript during the object's construction. The purpose for that, of course, is to make the tool more easily deploy-able.
只要我构建了相应的HTML对象,这个对象就可以工作,但通常当我构建这些对象时,我会向它们添加一个额外的部分,其中我在对象构造期间通过javascript创建所有HTML组件。当然,其目的是使工具更易于部署。
#6
0
You can also try this , it's a bit ugly but it works :)
你也可以尝试这个,它有点难看,但它的工作:)
The custom object :
自定义对象:
$.fn.epicModule = function (pMessage) {
var object = $(this)[0];
object.__construct = function (pMessage) {
//TODO
this.message = pMessage;
}
object.callMeDirectly = function () {
alert(this.message);
}
object.__construct(pMessage);
}
Init Module :
初始模块:
$(".myHtmlEl").epicModule("Hallo World");
Calling the function :
调用功能:
$(".myHtmlEl")[0].callMeDirectly();