I have the following code in main.js:
(function($) {
// Code goes here
$.fn.switcher=function(opts)
{
var defaults={
btn:'.info_btn', //Класс кнопки
block:'.details_info', //Класс блока, который нужно скрыть
hideifout:false, //Если true то скроект блок когда мышь его покент
classActive:'open' //Класс который ставится активной кнопке
//classNotActive:'close'
};
var options=$.extend(defaults, opts);
this.each(
function(){
var $this=$(this);
var btn=$this.find(options.btn);
var block=$this.find(options.block);
var plaing=false;
var click=function(e){
if (e.type=='mouseleave')
{
e.stopPropagation();
}
if (plaing) return;
plaing=true;
if (block.is(':visible'))
{
block.hide('blind',function(){
btn.removeClass(options.classActive);
btn.css('z-index',0);
plaing=false;
});
} else {
btn.addClass(options.classActive);
btn.css('z-index',2);
block.show('blind',function(){
plaing=false;
});
}
}
btn.click(click);
if (options.hideifout){
block.mouseleave(click);
}
}
);
}
})(jQuery);
And js code in my aspx file:
<script type="text/javascript">
$(document).ready(function () {
$('#listInfoBlock').load('/cinema/filmlist'); // load films by default
$(".title").click(function (e) {
e.preventDefault();
loadFilmList($(this));
});
$("#buttonFindFilmByName").click(function (e) {
e.preventDefault();
loadFilmList($(this));
});
// load films by criteria
function loadFilmList(id) {
$('#listInfoBlock').load('/cinema/filmlist?id=' + $(id).attr("id"));
$(".tabs").find("a").removeClass("active");
$(id).parent().addClass("active");
};
});
</script>
The function loadFilmList fills listInfoBlock.
The problem in that function in main.js executes first and there are no div called .details_info (it will be there when loadFilmList is executed)
How can I solve this problem?
Thanks.
SOLUTION:
I rewrite like that:
function loadFilmList(id) {
$('#listInfoBlock').load('/cinema/filmlist?id=' + $(id).attr("id"), function () {
$('.infoBlock').switcher();
$('div.widgets').switcher(
{
btn: '.expand',
block: '.voice_block',
hideifout: true
// classActive:'expand'
});
});
if (id !== undefined) {
$(".tabs").find("a").removeClass("active");
$(id).parent().addClass("active");
}
};
now it's work.
Thanks Nate.
The problem is that you're declaring $.fn.switcher but aren't ever calling it anywhere. I think you need to call it in two places, in a callback function on both of your .load() AJAX calls.
$('#listInfoBlock').load('/cinema/filmlist', function() { $.fn.switcher({ }); });
and
$('#listInfoBlock').load('/cinema/filmlist?id=' + $(id).attr("id"), function() { $.fn.switcher({ }); });
Related
I am trying to disable the button until the code is successfully executed. Unfortunately, the button is activated too early, the function is still running. How can I prevent this?
$("#myButton").click(function() {
$(this).prop("disabled", true)
doSomethingFunction()
$(this).prop("disabled", false)
});
Edit:
Thank you all for your help. I have adjusted my code. Can you do it this way or are there better ways?
class TestClass
{
static doSomethingFunction() {
return new Promise(function (resolve, reject) {
setTimeout(function () { console.log("function is done"); resolve(self); }, 5000);
})
}
}
$("#myButton").click(function() {
$(this).prop("disabled", true)
TestClass.doSomethingFunction().then(r => $(this).prop("disabled", false))
});
The second solution does not work for me, because "completely done" is output before "function is done"
class TestClass
{
static doSomethingFunction(callback) {
setTimeout(function () { console.log("function is done");}, 2000);
if(callback !== undefined){
callback();
}
}
}
$("#myButton").click(function() {
$(this).prop("disabled", true)
TestClass.doSomethingFunction(function(){
console.log("completely done")
});
});
What am I doing wrong?
Consider the following.
var myData;
function doSomethingFunction(callback){
$.get("someplace.php", function(data){
myData = data;
if(callback !== undefined){
callback();
}
});
}
$("#myButton").click(function() {
var $self = $(this);
$self.prop("disabled", true);
doSomethingFunction(function(){
console.log(myData);
$self.prop("disabled", false);
});
});
This allows you to pass in code to run once the function is complete. In this example, maybe it's getting data from the server. This may take almost no time, or maybe the report takes 1.2 seconds to generate. Either way it will not be run until the AJAX is successful.
Update
Here is an example, based on the following: How do I use jQuery promise/deffered in a custom function?
$(function() {
function doSomething() {
var deferred = new $.Deferred();
setTimeout(function() {
deferred.resolve(10);
}, 10 * 1000);
return deferred;
}
$("button").click(function() {
var $self = $(this);
console.log("Disabled");
$self.prop("disabled", true);
doSomething().then(function() {
$self.prop("disabled", false);
console.log("Enabled");
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Start</button>
This will run for 10 seconds and then enable the button. Applying it to your example.
class TestClass {
static doSomethingFunction() {
var deferred = new $.Deferred();
setTimeout(function() {
deferred.resolve(10);
}, 5 * 1000);
return deferred;
}
}
$("#myButton").click(function() {
var $self = $(this);
$self.prop("disabled", true);
TestClass.doSomethingFunction().then(r => $self.prop("disabled", false));
});
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 am not sure how to ask this question. I made a jQuery function for a banner.
$(document).ready(function() {
ionanim();
setInterval(ionanim, 12000);
function ionanim() {
$(function () {
$('.ion1anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500);
});
});
$(function () {
$('.ion2anim').delay(6000).fadeIn(500, function () {
$(this).delay(5000).fadeOut(500);
});
});
};
});
Link for the full animation : http://jsfiddle.net/L8XHL/11/
But with each intervatl on the setInverval the animations go close to each other after some time they overlap each other.
Did i do anything wrong?
Intervals and animations aren't exact enough to handle the timing that you require. I'd suggest using a self-executing function instead so that it will never overlap.
Also, you are over-using the document ready handler. Please stop.
http://jsfiddle.net/L8XHL/13/
$(document).ready(function () {
ionanim();
function ionanim() {
$('.ion1anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500, function () {
$('.ion2anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500,ionanim);
});
});
});
}
});
I would further modify this to work more like a slider so that you can add an infinite number of items without having a huge pyramid of code.
http://jsfiddle.net/L8XHL/17/
$(document).ready(function () {
$(".ionbanner .bottom div").first().siblings().hide();
anim();
function anim() {
var curr = $(".ionbanner .bottom :visible");
var next = curr.next();
if (next.length == 0) {
next = curr.siblings().first();
}
curr.delay(5000).fadeOut(500,function(){
next.fadeIn(500,anim);
});
}
});
Or you could try something like this: http://jsfiddle.net/L8XHL/16/
$(document).ready(function() {
var anim1 = function() {
$('.ion1anim').fadeIn(1000, anim1Callback);
},
anim1Callback = function() {
$('.ion1anim').fadeOut(1000, anim2);
},
anim2 = function() {
$('.ion2anim').fadeIn(1000, anim2Callback);
},
anim2Callback = function() {
$('.ion2anim').fadeOut(1000, anim1);
};
anim1();
});
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);
});
});