I have following js plugin to catch show hide events of elements. But i want to make it specific to One dom element only, i.e #div_loading_page
jQuery(function ($) {
$.each(['show','hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
el.apply(this, arguments);
};
});
});
can anyone please help. thanks
jQuery(function ($) {
$.each(['show','hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.each(function () {
if ( this.id == 'div_loading_page') {
$(this).trigger(ev);
return false; // break out of the loop
}
});
el.apply(this, arguments);
};
});
});
Related
I am developing a JQuery plugin. I need to use OOP inside my plugin. However, the class not working as I expected. When I initiate a new instance of the class, it is only the first line of its code that is executing. What is wrong with this code and how to execute a constructor of this class on initiation?
(function ($) {
var FunClass;
FunClass = function () {
console.log("FunGlobal");
function FunClass() {
console.log("FunConstructor");
}
FunClass.prototype.letsFun = function () {
console.log("FunMethod");
}
}();
$.fn.fun = function () {
var funClass;
return this.each(function () {
funClass = new FunClass();
funClass.letsFun();
});
};
}(jQuery));
Here is the console output: Console Output
Thanks for help.
Seems you've forgot to return FunClass:
(function($) {
var FunClass;
FunClass = (function() {
console.log("FunGlobal");
function FunClass() {
console.log("FunConstructor");
}
FunClass.prototype.letsFun = function() {
console.log("FunMethod");
}
return FunClass; // you missed this line
})();
$.fn.fun = function() {
var funClass;
return this.each(function() {
funClass = new FunClass();
funClass.letsFun();
});
};
}(jQuery));
// Usage
$(function() {
$('body').fun();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have implemented several jQuery plugins for my current project.
Since some plugins have functions with the same name, the one called in the last one defined.
Here is the definition of my first plugin:
$(function($)
{
$.fn.initPlugin1 = function(parameters)
{
var defaultParameters = {};
$(this).data('parameters', $.extend(defaultParameters, parameters));
return $(this);
};
$.fn.function1 = function(){ console.log('Function 1.'); };
$.fn.callFunction = function(){ $(this).function1(); };
});
And here is the definition of my second plugin:
$(function($)
{
$.fn.initPlugin2 = function(parameters)
{
var defaultParameters = {};
$(this).data('parameters', $.extend(defaultParameters, parameters));
return $(this);
};
$.fn.function2 = function(){ console.log('Function 2.'); };
$.fn.callFunction = function(){ $(this).function2(); };
});
I have also this scenario :
$("#div1").initPlugin1().callFunction();
$("#div2").initPlugin2().callFunction();
For this specific scenario the consoles shows: Function 2. Function 2.
In fact, since the callFunction() is also defined in the second plugin, this is the one used.
I would like some advise on what is the best way to solve this problem.
Is it possible to create a thing similiar to a namespace ?
Thank to #syms answer, I have created the following example.
Plugin1:
$(function($) {
$.fn.initPlugin1 = function() {
console.log('Initialized Plugin1');
return $(this);
};
$.fn.initPlugin1.testFunction = function() {
$(this).append('Function 1.');
};
});
Plugin2:
$(function($) {
$.fn.initPlugin2 = function() {
console.log('Initialized Plugin2');
return $(this);
};
$.fn.initPlugin2.testFunction = function() {
$(this).append('Function 2.');
};
});
Main:
(function($)
{
$(document).ready(
function()
{
$("#div1").initPlugin1(); //Run correctly
$("#div2").initPlugin2(); //Run correctly
$("#div1").initPlugin1.testFunction(); //Fail
$("#div2").initPlugin2.testFunction(); //Fail
});
})(jQuery);
When I run my code, I got the following error: Cannot read property 'createDocumentFragment' of null.
Apparently, the this object is corrupted.
you can try this,
$(function($) {
$.fn.initPlugin1 = function() {
console.log('Initialized Plugin1');
return $(this);
};
});
$(function($) {
$.fn.initPlugin2 = function() {
console.log('Initialized Plugin2');
return $(this);
};
$.fn.callFunction = function(param) {
$(this).append(param);
};
});
(function($) {
$(document).ready(
function() {
$("#div1").initPlugin1(); //Run correctly
$("#div2").initPlugin2(); //Run correctly
$("#div1").initPlugin1().callFunction('function1');
$("#div2").initPlugin2().callFunction('function2');
});
})(jQuery);
I wrote this plugin to catch show event only for div_loading_page element:
(function ($) {
$.each(['show'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.each(function () {
if (this.id == 'div_loading_page') {
$(this).trigger(ev);
return false; // break out of the loop
}
});
//alert(this.id);
el.apply(this, arguments);
};
});
})(jQuery);
It's working fine but because of it i get following error:
$cluetipTitle.show() is undefined , which is from cluetip jquery plugin. Any idea how can i resolve this conflict?
Change:
el.apply(this, arguments);
To
return el.apply(this, arguments);
This ensure that the original function's return value is reserved and will not cause unexpected behavior
change this
$.each(['show']
to
return $.each(['show']
this will allow for chaining, ie doing what you want to do with the .show
here's my basic code:
JS:
jQuery(function($)
{
function MyTest() {}
MyTest.prototype =
{
myMethod: function()
{
$(this).append("<div id='myId'></div>");
}
}
$(document).ready(function()
{
var myTest1 = new MyTest();
$("#anelement").click(function()
{
myTest1.myMethod();
});
});
});
HTML:
<div id='anelement'></div>
Clicking on "anelement", JS console returns:
TypeError: e is undefined ... jquery.min.js (line 5)
...and it doesn't append "myId" - why?
Thanks
You need to somehow pass the clicked element into your method. Here is one way to do it:
jQuery(function ($) {
function MyTest() {}
MyTest.prototype = {
myMethod: function (el) {
$(el).append("<div id='myId'></div>");
}
}
$(document).ready(function () {
var myTest1 = new MyTest();
$("#anelement").click(function () {
myTest1.myMethod(this);
});
});
});
You could also use .call to execute your method with the given context, however you then lose access to instance methods and variables.
jQuery(function ($) {
function MyTest() {}
MyTest.prototype = {
myMethod: function () {
$(this).append("<div id='myId'></div>");
}
}
$(document).ready(function () {
var myTest1 = new MyTest();
$("#anelement").click(function () {
myTest1.myMethod.call(this);
});
});
});
or simply
jQuery(function ($) {
function MyTest() {}
MyTest.prototype = {
myMethod: function () {
$(this).append("<div id='myId'></div>");
}
}
$(document).ready(function () {
var myTest1 = new MyTest();
$("#anelement").click(myTest1.myMethod);
});
});
I am looping through an array of data with each having there own delete button with class="delete_thereid". when the page loads the delete button works fine.. now
after the page loads again (start_timer()) and I try to delete a different record, the native js confirmation box pops up two times.. actually the popup increments each time the page gets refreshed. I really have been at trying to find a solution for this for a few days now with out a success. Here is my code.
var refreshSpeed = 8000;
var intValID = 0;
function get_post ()
{
$.ajax ({
url: "postComments.php",
type: "post",
cache: false,
dataType: "json",
data: {type: "getComments"},
success: function (d) {
var c = [];
var r = [];
v ar cp = [];
//Check for new post, update page.
$(d.results.com).each (function (k, v)
{
if ($("#showComments").find ("div#"+$(v).attr ("id")).length == 0) {
cp.push (v);
}
c.push ($(v).attr ("id"));
if ($.inArray ($(v).attr ("id"), c_hashid) == -1) {
c_hashid.push ($(v).attr ("id"));
}
});
$("#showComments").prepend (cp).fadeIn ("slow");
remove_deleted (c_hashid, c); //remove post
remove_deleted (r_hashid, r); //remove replies
deletePost ();
start_timer ();
//optionBttn ();
return false;
}
});
}
function remove_deleted (ids, r)
{
$.each (ids, function (k, v){
if ($.inArray (v, r) == -1)
{
$("#showComments").find ("div#"+v).slideUp ("slow");
}
});
}
function confirmDelete ()
{
if (confirm ("Are you sure you wish to delete this post?")) {
return true;
}
return false;
}
function deletePost ()
{
$("[class^=delete]").each (function () {
$(this).on("click", function (e)
{
e.preventDefault ();
//stop_timer ();
if (confirmDelete ())
{
$(this).die ("click"); //test
$(this).unbind ().click(); //test
//e.stopPropagation();
//start_timer ();
}
});
});
}
function start_timer () {
intValID = setTimeout (function () {
get_post ();
}, refreshSpeed);
}
function stop_timer () {
clearTimeout (intValID);
}
$(document).ready (function ()
{
$("#cbutton").attr("disabled", "disabled");
$(document).mouseup (function (e)
{
if ($("#layerOne").has (e.target).length === 0)
{
$("div[id^=replybox]").fadeOut ("fast");
}
});
get_post ();
textAreaAnim ();
play_video ();
});
the function that is making the call is deletePost from get_post, you can see what its doing here
EDIT
After all this time!!! and all I had to do was
$("[class^=delete]").on ("click", function (e)
{
if (confirmDelete ())
{
e.stopImmediatePropagation () //<----this!!! this is all I needed
//dorestofstuff ();
}
});
No more incremented confirmation box on each page load. stopImmediatePropagation () is magical!
You could try changing your deletePost method,
Instead of iterating through a set of matching elements you can directly bind an event to them:
function deletePost () {
$("[class^=delete]").on("click", function(e) {
e.preventDefault ();
//stop_timer ();
if (confirmDelete()) {
$(form).die ("click");
$(form).unbind ().click();
//e.stopPropagation();
//start_timer ();
}
});
}