I have a page using prototype (don't have much control over that).
What I'd like to do is have a document ready function that only uses "jQuery" once, and then inside that function I can just use $ and it won't conflict with prototype.
This is what I have so far
jQuery(function() {
var superProperties = $.cookie('mp_' + token + '_mixpanel');
console.log($.cookie());
});
If you want it to run on document load
jQuery(function($) {
var superProperties = $.cookie('mp_' + token + '_mixpanel');
console.log($.cookie());
});
If you want it to run immediately
(function($) {
var superProperties = $.cookie('mp_' + token + '_mixpanel');
console.log($.cookie());
})(jQuery);
Related
I am working on a function that changes the source of an image tag to a background-image. This function should be really helpful for the way images will look in IE. I have tried debugging, but I get stuck on an object expected error. This happens on the second line:
if ( ! Modernizr.objectfit ) {
$('.wrapper__figure').each(function () {
var $container = $(this),
imgUrl = $container.find('img').attr('src');
if (imgUrl) {
$container
.css('backgroundImage', 'url(' + imgUrl + ')');
}
});
}
The only way I can get that code to cause that error in IE is if jQuery's noConflict has been used, so $ isn't jQuery anymore (example: http://output.jsbin.com/bixijotala). If so, you probably want to use an IIFE to use a local $, passing in jQuery:
(function($) {
if ( ! Modernizr.objectfit ) {
$('.wrapper__figure').each(function () {
var $container = $(this),
imgUrl = $container.find('img').attr('src');
if (imgUrl) {
$container
.css('backgroundImage', 'url(' + imgUrl + ')');
}
});
}
})(jQuery);
Or of course, you'd get this if you don't have jQuery loaded at all, in which case the answer is: Load jQuery, prior to running that code.
I have written some codes by Jquery but because of a reason, it can not find Jquery. I have changed $ to Jquery and still get the same error. What if I change that to the pure JS, any comments on that?
var listener = throttle(300, function () {
slotsAtlantic.forEach(function (item) {
var $item = jQuery('#' + item.id);
if ($item.length) {
var $parent = $item.parent();
var index = slotsAtlantic.indexOf(item);
if ($parent.is(':visible') && ((window.scrollY || window.pageYOffset) >= ($parent.offset().top - jQuery(window).height() - 300))) {
googletag.cmd.push(function () {
googletag.pubads().refresh([item.slot]);
});
slotsAtlantic.splice(index, 1);
}
}
});
});
If you are getting an error JQuery not found, it probably means that either you are not including the JQuery script or for some reason, JQuery variable is getting undefined. Can you post your whole html code? Alternately, can you ensure the inclusion of JQuery scripts? E.g. to include JQuery v1.12.0 from Google CDN, you need to have a script tag like following
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
Sorry, probably bit of a noob JS question regarding binding handlers to instances.
I am creating a controller instance with some data that will subsequently be used to process incoming events (the actual use case is composing complex d3 handlers with varying ajax urls and into which I compose the function(s) doing the actual tree update).
RequireJS and jquery are involved, but I suspect my issue has more to do with my specific binding code. I guess I could forego the use of 'this' since I have only one controller per page which can be a global. But this feels like it should be doable, if only I knew how to.
This is how I bind the controller to its target, from within the constructor (doing it outside the constructor seems to work):
function BtnMgr(msg, tgt_id) {
this.msg = msg;
this.tgt_id = tgt_id;
var selector = "#" + tgt_id;
$(selector).on("click", this.handleClick);
}
What is going wrong?
When I click on the button, 'this', in the handleClick refers to the html button, not to the controller instance.
If I call the controller instance method directly, 'this' is correct.
I've tried call or creating a wrapper function, as suggested in
How can I bind an event handler to an instance in JQuery?
$(selector).click(function(e) { BtnMgr.prototype.handleClick.call(this, e); });
My button click keeps seeing 'this' as the button, not the controller:
output
global var controller:BtnMgr.I am a button
this:[object HTMLButtonElement],type:
e:[object Object],type:Object
BtnMgr.handleClick:this.msg:undefined
Simplified version:
HTML
page4.html
<!DOCTYPE html>
<html>
<head>
<title>Page 4</title>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.15/require.min.js"></script>
<script type="text/javascript">
requirejs.config({
baseUrl: '.',
paths: {
"jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min"
}
});
var controller;
require(["main4"], function(BtnMgr) {
controller = new BtnMgr("I am a button", "btn_click");
//this simulated call works - 'this' refers to the BtnMgr instance
controller.handleClick("dummy_btn");
});
</script>
</head>
<body>
<button id="btn_click">click me!</button>
</body>
</html>
RequireJS
main4.js
define(["jquery"], function($) {
function BtnMgr(msg, tgt_id) {
this.msg = msg;
this.tgt_id = tgt_id;
var selector = "#" + tgt_id;
$(selector).on("click", this.handleClick);
}
BtnMgr.prototype.toString = function(){
return "BtnMgr." + this.msg;
};
BtnMgr.prototype.handleClick = function(e) {
//I want 'this' to refer to the BtnMgr instance
//and e to the html element that got clicked...
console.log("global var controller:" + controller);
console.log("this:" + this + ",type:" + this.constructor.name);
console.log("e:" + e + ",type:" + e.constructor.name);
console.log("BtnMgr.handleClick:this.msg:" + this.msg);
};
//define is returning the constructor method for the object
return BtnMgr;
});
You could achieve (nearly) what you want with :
$(selector).on("click", this.handleClick.bind(this));
this will be the instance of BtnMgr and e.target will, as always, be the button.
However, that would fly in the face of convention and confuse anyone trying to understand your code, including yourself in 6 months time. In a click handler, this should always refer to the clicked element, as is natural.
If you really must have a reference from the handler back to the instance of BtnMgr that attached the click, then I might opt for "e-augmentation" like this :
function BtnMgr(msg, tgt_id) {
var that = this;
this.msg = msg;
this.tgt_id = tgt_id;
var selector = "#" + tgt_id;
$(selector).on("click", function(e) {
e.clickAttacher = that;
that.handleClick(e);
});
}
BtnMgr.prototype.toString = function(){
return "BtnMgr." + this.msg;
};
BtnMgr.prototype.handleClick = function(e) {
console.log("click attacher was instance of : " + e.clickAttacher.constructor.name); // BtnMgr
console.log("button id: " + e.target.id); // xxx
console.log("msg: " + e.clickAttacher.msg); // Hello World!
};
var b = new BtnMgr('Hello World!', 'xxx');
DEMO
Having done that, you have to ask whether it's really worthwhile defining handleClick in that way. Sure, if it's a monster function then yes, define it with BtnMgr.prototype...., but if it's only small, then define it in the constructor itself and take direct advantage of that being in the scope chain (as does the augmenter function above).
Try this when you bind your onClick:
function BtnMgr(msg, tgt_id) {
this.msg = msg;
this.tgt_id = tgt_id;
var selector = "#" + tgt_id;
$(selector).on("click", $.proxy(this.handleClick, this));
}
That would make sure that the 'this' variable in your callback is your class and not the clickevent.
You can read more about jQuery Proxy here: http://api.jquery.com/jquery.proxy/
I have some JS code but Drupal 7 does not recognize it. I'm getting the following error:
TypeError: $ is not a function
Can anyone help me to make this script work? I'm using jQuery v1.4.4.
<script type="text/javascript">
this.screenshotPreview = function(){
/* CONFIG */
xOffset = 10;
yOffset = 30;
// these 2 variable determine popup's distance from the cursor
// you might want to adjust to get the right result
/* END CONFIG */
$("a.screenshot").hover(function(e){
this.t = this.title;
// this.title = "";
var c = (this.t != "") ? "<br/>" + this.t : "";
$("body").append("<p id='screenshot'><img src='"+ this.rel +"' alt='url preview' />"+ c +"</p>");
$("#screenshot")
.css("top",(e.pageY - xOffset) + "px")
.css("left",(e.pageX + yOffset) + "px")
.fadeIn("fast");
},
function(){
this.title = this.t;
$("#screenshot").remove();
});
$("a.screenshot").mousemove(function(e){
$("#screenshot")
.css("top",(e.pageY - xOffset) + "px")
.css("left",(e.pageX + yOffset) + "px");
});
};
// starting the script on page load
$(document).ready(function(){
screenshotPreview('some text');
});
</script>
Try changing all your instances of the "$" shortcut to "jQuery" and it should work. Calling the screenshotPreview function would for example then look like this:
// starting the script on page load
jQuery(document).ready(function(){
screenshotPreview('some text');
});
Alternatively enclose all your jQuery code in a function with jQuery as a parameter and the $ shortcut should then work.
// We define a function that takes one parameter named $.
(function ($) {
// Use jQuery with the shortcut:
console.log($.browser);
// Here we immediately call the function with jQuery as the parameter.
}(jQuery));
(Source: https://drupal.org/node/171213)
Drupal 7 provides jQuery in the no-conflict mode, which means that $ is not the jQuery object/namespace. This should not be an issue with properly written jQuery plugins that follow jQuery's plugins authoring documentation.
JavaScript code that expect $ to be the jQuery namespace will not work within a Drupal page. This can be easily solved by wrapping the code in an immediately invoked anonymous function that will alias the jQuery namespace to $:
(function($) {
// Here $ is the jQuery namespace.
})(jQuery);
Try this: (or let me know if that's not right - but it seems to work for me)
/*******************************************************************
* :: Define Your Functions ::
*******************************************************************/
(function ($) {
removeAjaxLoader = function() {
console.log('removeAjaxLoader');
$('body').find('.ajax-loader').remove();
$('body').find('.ajax-loader-icon').remove();
return false;
} //removeAjaxLoader
addAjaxLoader = function() {
console.log('addAjaxLoader');
removeAjaxLoader();
$('body').append('<div class="ajax-loader"></div><div class="ajax-loader-icon"></div>');
return false;
} //addAjaxLoader
}) (jQuery);
/*******************************************************************
* :: Ready Set Go ::
*******************************************************************/
(function ($) {
$(document).ready(function() {
console.log('ready complete');
removeAjaxLoader();
}); // document.ready
}) (jQuery);
I have the bellow code, I wish to create an IF statement so the loadScript function is only called for a specific HREF. But when I try and alert the value of the href it returns "Undefined"...
Many Thanks,
J
$(document).ready(function()
{
$('.jNav').click(function()
{
$('#sandbox').load($(this).attr('href'),function()
{
alert("From here " + $(this).attr('href') + " to here.");
loadScript();
});
return false;
});
});
Your issue is just scoping. In your load() callback, this refers to the element you're calling load() on, which happens to be $('#sandbox'), and thus: no href. Usually what I do is something like this:
$('.jNav').click(function()
{
var self = this;
$('#sandbox').load($(this).attr('href'),function()
{
// Notice the use of self here, as we declared above
alert("From here " + $(self).attr('href') + " to here.");
loadScript();
});
return false;
});
Doing this ensures that you can still get to the thing that you clicked from inside the load() callback.
The problem is one of context: The call to $(this) in the alert refers to $('#sandbox') not $('.jNav'). Simply define a variable for you first reference.
When you are inside the callback for $('#sandbox').load, this refers to $('#sandbox'), and not to $('.jNav'). If you want to alert the href, save that (or a reference to this) in a variable.
$('.jNav').click(function(){
var that = this;
$('#sandbox').load($(this).attr('href'),function(){
alert($(that).attr('href'));
//...
});
}
OR
$('.jNav').click(function(){
var href = $(this).attr('href');
$('#sandbox').load($(this).attr('href'),function(){
alert(href);
//...
});
}
$(this) was the .jNav, but in your callback it's now the #sandbox. Pre-cache the variable at the point where it's presented to you, then use it wherever you like.
Improving slightly on Groovetrain's answer, I'd write:
$('.jNav').click(function(event) {
var $self = $(this);
var href = $self.attr('href');
$('#sandbox').load(href, function() {
alert("From here " + href + " to here.");
loadScript();
});
event.preventDefault(); // better than `return false`
});
Inside your innnermost function the context (this) is set to the #sandbox element. You'll want to get the href attribute from the .jNav element beforehand and store it in a variable.
Example code
Take care of what "this" is in what part of your function. In the innermost function, you are calling it from $('#sandbox'),which I suspect doesn't have a href attribute. the best solution would probably be to pass the value of the href into the function or store it in a variable.
$(document).ready(function()
{
$('.jNav').click(function()
{
$('#sandbox').load($(this).attr('href'),function()
{
alert("From here " + $(this).parent().attr('href') + " to here.");
loadScript();
});
return false;
});
});