I wonder if selector "$cacheA" will be cached on page load in the example below?
// MY JQUERY FUNCTION/PLUGIN
(function( $ ){
$.fn.myFunction = function() {
var $cacheA = this,
$cacheB = $cacheA.children(),
$cacheC = $cacheB.eq(0);
$cacheD = $cacheA.parent();
$cacheD.click(function(){
$cacheA.toggle();
$cacheB.fadeIn();
$cacheC.slideUp();
});
};
})( jQuery );
// END JQUERY FUNCTION/PLUGIN
$(window).load(function(){
$('#mySelector').myFunction();
});
Would it be any reason to do this:
$(window).load(function(){
var $mySelector = $('#mySelector');
$mySelector.myFunction();
});
If, inside your "load" handler, you were to do many jQuery operations with "$mySelector", then saving that in a variable would be a good idea. However, in your example, you only use the value once, so it really makes no difference at all.
Firstable, $cacheA and others inside click function will be undefined.
$cacheD.click(function(){
$cacheA.toggle();
$cacheB.fadeIn();
$cacheC.slideUp();
});
Second,
$.fn.myFunction = function() {
var $cacheA = this,
$cacheB = $cacheA.children(),
$cacheC = $cacheB.eq(0);
$cacheD = $cacheA.parent();
}
So, after $('selector').myFunction() how can I use $cacheB, $cacheC and $cacheD? Where they are will store?
Related
So I'm fairly novice with jquery and js, so I apologise if this is a stupid error but after researching I can't figure it out.
So I have a list of data loaded initially in a template, one part of which is a dropdown box that lets you filter the data. My issue is that the filtering only works once? As in, the .change function inside $(document).ready() only fires the once.
There are two ways to reload the data, either click the logo and reload it all, or use the search bar. Doing either of these at any time also means the .change function never fires again. Not until you refresh the page.
var list_template, article_template, modal_template;
var current_article = list.heroes[0];
function showTemplate(template, data)
{
var html = template(data);
$("#content").html(html);
}
$(document).ready(function()
{
var source = $("#list-template").html();
list_template = Handlebars.compile(source);
source = $("#article-template").html();
article_template = Handlebars.compile(source);
source = $("#modal-template").html();
modal_template = Handlebars.compile(source);
showTemplate(list_template,list);
$(".articleButton").click(function()
{
var index = $(this).data("id");
current_article = list.heroes[index];
showTemplate(article_template,current_article);
$('.poseThumb').click(displayModal);
});
$("#classFilter").change(function()
{
console.log("WOW!");
var classToFilter = this.value;
var filteredData =
{
heroes: list.heroes.filter(function(d)
{
if (d.heroClass.search(classToFilter) > -1)
{
return true;
}
return false;
})
};
console.log(filteredData);
showTemplate(list_template,filteredData);
$(".articleButton").click(function()
{
var index = $(this).data("id");
current_article = filteredData.heroes[index];
showTemplate(article_template,current_article);
$('.poseThumb').click(displayModal);
});
});
$("#searchbox").keypress(function (e)
{
if(e.which == 13)
{
var rawSearchText = $('#searchbox').val();
var search_text = rawSearchText.toLowerCase();
var filteredData =
{
heroes: list.heroes.filter(function(d)
{
if (d.name.search(search_text) > -1)
{
return true;
}
return false;
})
};
console.log(filteredData);
showTemplate(list_template,filteredData);
$(".articleButton").click(function()
{
var index = $(this).data("id");
current_article = filteredData.heroes[index];
showTemplate(article_template,current_article);
$('.poseThumb').click(displayModal);
});
}
});
$("#logo").click(function()
{
showTemplate(list_template,list);
$(".articleButton").click(function()
{
var index = $(this).data("id");
current_article = list.heroes[index];
showTemplate(article_template,current_article);
$('.poseThumb').click(displayModal);
});
});
//$("#logo").click();
});
function displayModal(event)
{
var imageNumber = $(this).data("id");
console.log(imageNumber);
var html = modal_template(current_article.article[0].vicPose[imageNumber]);
$('#modal-container').html(html);
$("#imageModal").modal('show');
}
I should note two things: first, that the search bar works perfectly, and the anonymous function inside both of them is nearly identical, and like I said, the filtering works perfectly if you try it after the initial load. The second is that the same problem occurs replacing .change(anonymous function) with .on("change",anonymous function)
Any help or advice would be greatly appreciated. Thanks.
I agree with Fernando Urban's answer, but it doesn't actually explain what's going on.
You've created a handler attached to an HTML element (id="classFilter") which causes part of the HTML to be rewritten. I suspect that the handler overwrites the HTML which contains the element with the handler on it. So after this the user is clicking on a new HTML element, which looks like the old one but doesn't have a handler.
There are two ways round this. You could add code inside the handler which adds the handler to the new element which has just been created. In this case, that would mean making the handler a named function which refers to itself. Or (the easier way) you could do what Fernando did. If you do this, the event handler is attached to the body, but it only responds to clicks on the #classFilter element inside the body. In other words, when the user clicks anywhere on the body, jQuery checks whether the click happened on a body #classFilter element. This way, it doesn't matter whether the #classFilter existed when the handler was set. See "Direct and delegated events" in jQuery docs for .on method.
Try to use some reference like 'body' in the event listeners inside your DOM like:
$('body').on('click','.articleButton', function() {
//Do your stuff...
})
$('body').on('click','#classFilter', function() {
//Do your stuff...
})
$('body').on('keypress','#searchbox', function() {
//Do your stuff...
})
$('body').on('click','#logo', function() {
//Do your stuff...
})
This will work that you can fire it more than once.
I am new to writing JQuery Plugins...and have a question regarding returning the selector used to bind the plugin to.
Lets say we attach a jQuery plugin to an element like this...
$(".someClass").viEdit();
And this is the Plugin ...
(function ($) {
$.fn.viEdit = function () {
var myTarget = "????"; // See Below
};
}(jQuery));
Now...How can I retrieve the target that was used to bind the jQuery?
I don't mean $(this), I'm looking for .someClass in this case.
As a second example, if it was set like this...
$("#myElement").viEdit();
I would be looking for...
#myElement
Any help would be greatly appreciated!
You can use this.selector:
http://jsfiddle.net/3NAwD/
(function ($) {
$.fn.viEdit = function () {
console.log(this.selector);
};
}(jQuery));
Note that something like $(document.getElementById('someId')).viEdit(); will give you a blank selector.
There were a .selector property, which is deprecated in newer versions.
The advised method now is to pass it as a option like
(function ($) {
$.fn.viEdit = function (options) {
var myTarget = options.target;
};
}(jQuery));
$("#myElement").viEdit({
target: '#myElement'
});
I've baked a plug-in to handle runtime searches on input fields I'm using all over a big site.The plug-in works perfect in every situation but this http://jsfiddle.net/tonino/v8d2A/
$(document).ready(function () {
var callback_methods = { /* methods here */ };
var input_html = '<div class="search"><input name="search-field" value="Search..."></div>';
$(document).on('click', 'div.add', function (event) {
if (!$('li div.add + div').hasClass('search')) {
var input = $(this).after(input_html).parent().find('input');
input.focus();
input.hunter({url:'<?php echo $this->request->base; ?>/searches', callback:callback_methods, var_name:'data[Search][term]'});
// other code after
}
});
});
If I comment the hunter plug-in everything works fine.
I'm sure is some concept on how it must be structured, here is the code: jquery.hunter.1.3.js
Why my plug-in make this error in this situation, where I'm wrong on writing it?
the problem is this part of your code:
var selector = this.selector;
var def_css = {backgroundPosition:'-16px center', paddingLeft:$(selector).css('padding-left')}
if (settings.loader) { setStyle(def_css); }
var selector = this.selector;
and later:
$(this.selector).blur(function () {
first of all your code wont work when the if-condition is fulfilled, because you are trying to redeclare the variable 'selector' inside the if block. just leave the var-statement out there:
if (settings.loader) { setStyle(def_css); }
selector = this.selector;
but YOUR MAIN-problem is that 'this.selector' contains '.parent() input' which i doubt is a valid jQuery selector.
why are you doing that? why dont you just use $(this) save it into a variable and use this???
eg:
// first line in your plugin
$this = $(this)
// later you could use the $this var
$this.blur(function () {
To get rid of the error change this line:
var input = $(this).after(input_html).parent().find('input');
To the following:
var input = $(input_html).insertAfter($(this));
The core problem though is that the jquery.hunter plugin is using the this.selector variable for some reason - you don't need this - the plugin should use $(this) instead of $(this.selector)
How come this doesn't work in loading header content...
(function ($) {
var mheaderwrapper = '<div id="header"></div><div class="header-menu"></div>';
var mheadercontent = '/shop/Pages/global_header.html';
var mmenucontent = '/shop/Pages/global_megamenu.html';
var mjqueryhover = 'js/jquery.hoverIntent.minified.js';
var mjquerymenu = 'js/jquery.custom-menu.js';
$('#wrapper').prepend(mheaderwrapper);
$('#header').load(mheadercontent);
$('.header-menu').load(mmenucontent, function(){
$.getScript(mjqueryhover);
$.getScript(mjquerymenu);
});
})(jQuery);
but this does...
$.mheader = function() {
var mheaderwrapper = '<div id="header"></div><div class="header-menu"></div>';
var mheadercontent = '/shop/Pages/global_header.html';
var mmenucontent = '/shop/Pages/global_megamenu.html';
var mjqueryhover = 'js/jquery.hoverIntent.minified.js';
var mjquerymenu = 'js/jquery.custom-menu.js';
$('#wrapper').prepend(mheaderwrapper);
$('#header').load(mheadercontent);
$('.header-menu').load(mmenucontent, function(){
$.getScript(mjqueryhover);
$.getScript(mjquerymenu);
});
}
$(function() {
$.mheader();
});
This :
(function ($) {....})(jQuery);
executes immediately, and only maps jQuery to $ to make sure the dollar sign really is "jQuery" within the self executing function. It's not a "DOM ready" function.
This:
$(function() {....});
will wait until the DOM is ready before any code is executed.
You can use the second one inside the first one :
(function ($) {
$(function() {
//code here
});
})(jQuery);
to do both!
When you have a function in the <head> section like that, it is executing immediately, and is doing so before your HTML elements have started loading. Your elements #wrapper, #header, and anything with the .header-menu class do not yet exist at the time your code is executing, which is why it fails.
In the second example, using the domready event delays the firing of your code until after the DOM is ready (and your HTML elements exist), so the code works.
By the way,
$(function() {
// executes when DOM is ready
});
is just a shortcut for:
$(document).ready(function() {
// executes when DOM is ready
});
The above examples are specifically functionality provided by jQuery. Don't confuse the former with the immediately-executing function structure, which is pure JavaScript:
(function() {
// executes NOW
})();
See adeneo's answer for how to properly combine the two.
$(document).ready actually runs after the DOM is created.
Self-invoking functions run instantly if inserted into <head> section, before the DOM is constructed.
I just started writing Plugins for jQuery. I found a good tutorial how to start with it, but one point I missed. I want register a independent plugin-object for each element and I need them events.
Here the code I got atm:
(function($){
var MyPlugin = function(pElement, pOptions)
{
var element = $(pElement);
var object = pElement;
var settings = $.extend({
param: 'defaultValue'
}, pOptions || {});
this.onfocus = function() {
element.val('Focus');
};
this.onblur = function() {
element.val('Blur');
}
// DO I NEED THIS?
object.onfocus = this.onfocus;
object.onblur = this.onblur;
};
$.fn.myplugin = function(options)
{
return this.each(function()
{
var element = $(this);
if (element.data('myplugin')) { return };
var myplugin = new MyPlugin(this, options);
element.data('myplugin', myplugin);
});
};
})(jQuery);
Do I need to copy my public methods "onfocus" and "onblur" from "this" to "object"? Is there a better way?
The best guide for writing jQuery plugins is probably jQuery's own.
jQuery's event system is the best way of handling events for your plugin. If you're using jQuery 1.7+ (which I recommend, if it's possible), .on() and .off() are your workhorses. Not only can you bind browser events like focus and blur, you can create completely custom events like 'iamasuperstar' and trigger them manually with this.trigger( 'iamasuperstar' ).
So you'd do something like this for your plugin:
element.on( 'focus', function() {} )
element.on( 'blur', function() {} )
...and whatever else you need.
Why not:
object.onfocus = function() {
element.val('Focus');
};
object.onblur = function() {
element.val('Blur');
}