How to overwrite this.href in the beforeShow block? (jquery / fancybox) - javascript

I'm trying to overwrite this.href in the beforeShow block but it doesn't work.
The old value of this.href is being used even if it's overwritten.
Code is:
beforeShow: function (opts, fb_obj) {
// this conditional is some other code checking $(window).width() and $(window).height() and
// if the bigger image will fit; it is simplified here!
if (1) {
var source = this.href;
this.href = source.replace('_large','_super_large');
console.log('retina detacted! ' + source + " " + this.href);
// console output is OK, but this.href is not beeing replaced in the output!
}

If you want to override the value of this.href, use beforeLoad instead.
NOTE: this is for fancybox v2.0.6+

Since you tagged this in jquery ..ill say
The full code
if (1) {
var oldhref = $(this).attr('href');
$(this).attr('href','_super_large');
console.log('retina detacted! ' +oldhref + " " + this.attr('href');
}

Related

jquery class selector yields unusable id

I am getting an id that is not addressable by jquery ("#"+id).something .
At document start I have a :
var g_justClicked = '';
$.ajaxSetup({
beforeSend:function(event){
if(g_justClicked) {
console.log('g_justClicked='+g_justClicked+' tagName='+$('#'+g_justClicked).tagName);
};
var wOffset = $('#'+g_justClicked).offset();
$('#loading').show();
},
complete:function(){
$('#loading').hide();
}
});
At document end I have another script (all elements with class spinner should set the global variable 'g_justClicked'):
$(document).ready(function () {
$('.spinner').click(function() {
g_justClicked = $(this).attr('id');
console.log('.spinner.click: g_justClicked='+g_justClicked);
});
This works fine, the variable is set and displayed correctly in ajaxSetup.
BUT: referencing it in tagName= or in wOffset = with
$('#'+g_justClicked).
results in
"TypeError: wOffset/tagName is undefined"
Note: all ids start with several characters, t.e. "boxshow12345" is a typical id.
What am I doing wrong?
I think was able to reproduce your scenario here: https://jsfiddle.net/mrlew/qvvnjjxn/3/
The undefined in your console.log is because you're accessing an inexistent jQuery property: .tagName. This property is only available to native HTML Element.
To retrieve the tag name from a jQuery Object, you should use: .prop("tagName"), or access the property accessing the native element with $('#'+g_justClicked)[0].tagName
So, if you change
console.log('g_justClicked='+g_justClicked+' tagName='+$('#'+g_justClicked).tagName);
to:
console.log('g_justClicked='+g_justClicked+' tagName='+$('#'+g_justClicked).prop("tagName"));
Will successfully log: g_justClicked=boxshow12345 tagName=BUTTON, as expected.
Note: In order to your logic work, you have to click .spinner first.
Your problem is that your ajax setup runs regardless of whatever you do in the click handler, and it runs before you even setup that handler. The initial value for g_justClicked is empty string, and this is what it tries to access in $('#'+g_justClicked), hence the error.
If you want to click the spinner and then pass the id to the beforeSend, do it like this:
$(document).ready(function() {
$('.spinner').click(function() {
var g_justClicked = this.id; //simplify this a bit
console.log('.spinner.click: g_justClicked=' + g_justClicked);
// call ajax
_setupAjax( g_justClicked );
});
});
function _setupAjax(g_justClicked) {
$.ajaxSetup({
beforeSend: function(event) {
if (g_justClicked) {
console.log('g_justClicked=' + g_justClicked + ' tagName=' + $('#' + g_justClicked).tagName);
};
var wOffset = $('#' + g_justClicked).offset();
$('#loading').show();
},
complete: function() {
$('#loading').hide();
}
});
}
UPDATE
If you don't want a separate function, just move your ajax setup into the click handler:
$(document).ready(function() {
$('.spinner').click(function() {
var g_justClicked = this.id; //simplify this a bit
console.log('.spinner.click: g_justClicked=' + g_justClicked);
// call ajax setup
$.ajaxSetup({
beforeSend: function(event) {
if (g_justClicked) {
console.log('g_justClicked=' + g_justClicked + ' tagName=' + $('#' + g_justClicked).tagName);
};
var wOffset = $('#' + g_justClicked).offset();
$('#loading').show();
},
complete: function() {
$('#loading').hide();
}
});
});
});
OK #mrlew.
Answer: I tried your .prop appoach, but still got "undefined". Now back to the roots:
The goal is to get the id of any element that was clicked to modify the busy indicators position, while ajax is running. Newly I am back to my original approach, without global variable and parameter passing:
$(document).ready(function () {
$('.spinner').click(function() {
_setupAjax();
});
});
which works, and:
function _setupAjax() {
$.ajaxSetup({
beforeSend: function() {
$('#loading').show();
wJustClicked = $(this).attr('id'); /// <- that doesnt work!
console.log("_setupAjax wJustClicked="+wJustClicked);
console.log('_setupAjax tagName=' + $('#' + wJustClicked).prop("tagName"));
....defining css based on id (no problem)..
which yields "undefined" twice. I tried so many ways to get that f.... id.
#mrlew
thanks a lot for your help. Meanwhile I found the solution. All trouble came from a timing problem. Here is what works (for all DIV, SPAN and IMG of class=spinner and having an id:
$(document).ready(function () {
_setupAjax();
$('.spinner').click(function() {
wJustClicked = $(this).attr('id');
if(wJustClicked == null) alert('Id missing on item clicked');
console.log('.spinner.click! id='+wJustClicked);
var wOffset = $('#' + wJustClicked).offset();
var xPos = Math.round(wOffset.left) + 8;
var yPos = Math.round(wOffset.top) + 4;
console.log(wJustClicked+' offset left='+wOffset.left+' top='+wOffset.top+' xPos='+xPos+' yPos='+yPos);
wDiv = 'loading';
$('#'+wDiv).css('left',xPos);
$('#'+wDiv).css('top',yPos);
});
and the js function:
function _setupAjax() {
$.ajaxSetup({
beforeSend: function() {
$('#loading').show();
},
complete: function() {
$('#loading').hide();
}
});
}
A strange thing remained (I have firebug installed), which I have solved with Math.round: the x and y position come overdetailed like 170.5134577 and 434.8768664 ?!?
I can live with that. But where does this pseudo precision come from?
Again thanks a lot to keep my hope upright.

Elements created by getJSON don't react to the rest of the javascript loaded on the page

I am using getJSON to access Vimeo's Simple API, and any objects created on the page by the call, do not react to the rest of the javascript that is on the page. It is probably something simple that I am missing. Here is my getJSON code:
$.getJSON("http://vimeo.com/api/v2/album/1822727/videos.json", function(data){
$.each(data, function (index, value) {
var videoID = value.id;
var videoThm = value.thumbnail_large;
$('#galThms').prepend('<li id="thm' + videoID + '" style="background-image:url(' + videoThm + ');"></li>');
console.log(videoThm);
});
});
Here you go: http://jsfiddle.net/8t3Xq/1/
This demonstrates loading your <li> thumbs just as your question does, then I show how to easily change one of them. How to "change" them is endless, this is just a simple example of changing the content and background. So you must not have your selectors right.
This is just a snippet, see fiddle for everything...
$.getJSON("http://vimeo.com/api/v2/album/1822727/videos.json", function(data){
$.each(data, function (index, value) {
var videoID = value.id;
var videoThm = value.thumbnail_large;
$('#galThms').prepend('<li id="thm' + videoID + '" style="background-image:url(' + videoThm + ');"></li>');
console.log(videoThm);
});
});
window.changeIt=function()
{
$('li').first().html("I'm changed!");
$('li').first().css("background-image","");
}
Just make sure the <li>s are present first before your code that changes them is present. Would need to see more of you code to understand when/how that happens.
$.getJSON("http://vimeo.com/api/v2/album/1822727/videos.json", function(data){
$.each(data, function (index, value) {
var videoID = value.id;
var videoThm = value.thumbnail_large;
$('#galThms').append('<li id="thm' + videoID + '" style="background-image:url(' + videoThm + ');"></li>');
console.log(videoThm);
$( "#galThms li" ).click(function() {
$(this).hide();
});
});
});
try this
there is no way that my answer is so far removed from the problem statement. my guess is that either I somehow errantly posted this answer or the problem was edited. apologies
you could also use:
$(document).on('click','li .playVideo',function(){
//do something
});
i would probably change your #playVideo to a class, if you will have multiple li's

Impossible to access a function out of an event

I'm quite new with javascript and I don't understand this problem:
$(function() {
var $tab_title_input = $( "#tab_title"),
$tab_content_input = $( "#tab_content" );
var tab_counter = 0;
var editors = {};
var tab_current = 0;
// tabs init with a custom tab template and an "add" callback filling in the content
var $tabs = $( "#tabs").tabs({
tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
add: function( event, ui ) {
var tab_content = $tab_content_input.val() || "Tab " + tab_counter + " content.";
$( ui.panel ).append("<div id=\"editor" + tab_counter + "\" class=\"editor\">" + tab_content + "</div>");
adjust_size();
tab_current = ui.index;
editors[tab_current] = ace.edit("editor" + tab_counter);
},
show: function( event, ui ) {
adjust_size();
tab_current = ui.index; // zero-based index
editors[tab_current].resize();
},
select: function( event, ui ) {
adjust_size();
tab_current = ui.index; // zero-based index
},
});
The problem is that this line of code:
editors[tab_current].resize();
breaks everything telling Uncaught TypeError: Cannot call method 'resize' of undefined.
But editors editors[tab_current].resize() is well defined in the add event and alert(tab_current) gives me the correct result.
I'd bet money that editors[tab_current] returns undefined.
Your alert(tab_current) may well return a correct value, but that doesn't mean that there's an element of editors that corresponds to it. Test it with alert(editors[tab_current]), and if it shows undefined then go check if the element is being set properly.
I can see two avenues of investigation straight away:
What does ace.edit("editor" + tab_counter) return? Does it always return an object with a resize method or does it sometimes return undefined?
Is add always called prior to show for any value of tab_current?

Best way to load and unload JS file via JQuery

I've been frustated trying to find the best way to load and unload some JS file via jQuery, this was last what I can do:
$("#button").live("click", function(){
var pl = $(this).attr('rel');
$.getScript('' + siteAddress + 'min/?js=fjs'+ pl +'', function() {
$('#container').load(""+ siteAddress +"load/"+ pl +"/");
});
});
What I want to do is to load some page via jQuery, and at same time it will include appropriate external JS file for current page that been loaded, it work fine for the first time, but when I click the button again, the last JS still loaded, so it will trigger the function inside JS file twice time for same page.
I've been try use .append, also by change <script> attribute and create dynamicaly <script> element but still, all i got is same result.
You can't "unload" JavaScript. Once it's loaded, it's loaded. There's no undo.
However, you can detach event handlers. See: http://api.jquery.com/unbind/
live() is a special case for unbind(), though. Live event handlers are attached to document rather than the element, so you have to remove the handler like so:
$(document).unbind('click');
However, that would probably remove more handlers than just the one in question, so you can do one of two things: 1) name your handler function or 2) create a namespace.
Naming handler function
function myClickHandler(){
var pl = $(this).attr('rel');
$.getScript('' + siteAddress + 'min/?js=fjs'+ pl +'', function() {
$('#container').load(""+ siteAddress +"load/"+ pl +"/");
});
}
$("#button").live("click", myClickHandler);
// And later ...
$(document).unbind('click', myClickHandler);
Namespacing
$("#button").live("click.myNamespace", function(){
var pl = $(this).attr('rel');
$.getScript('' + siteAddress + 'min/?js=fjs'+ pl +'', function() {
$('#container').load(""+ siteAddress +"load/"+ pl +"/");
});
});
// And later...
$(document).unbind('click.myNamespace');
UPDATE:
As #RTPMatt mentions below, die() is actually more appropriate. The method described above will work, but die() is easier to use. However, with die() you must match the selector exactly to the one used when you called live() or the results may be unpredictable:
$("#button").live("click", function(){
var pl = $(this).attr('rel');
$.getScript('' + siteAddress + 'min/?js=fjs'+ pl +'', function() {
$('#container').load(""+ siteAddress +"load/"+ pl +"/");
});
});
// And later ...
$('#button').die('click');
You could even have a "placeholder function" and check for its existence before loading the script again. But, first, i think it would be better to load the page and only after load the external script (and only if it's needed)
$("#button").live("click", function()
{
var pl = $(this).attr('rel');
//now we load the page, and then the "complete" callback function runs
$('#container').load(""+ siteAddress +"load/"+ pl +"/", function()
{
we check if the function is present into memory
if (typeof window["page_" + pl + "_init"] == 'undefined')
{
//function not found, we have to load the script
$.getScript('' + siteAddress + 'min/?js=fjs'+ pl +'');
}
});
});
Into the external script you will need to have the function
function page_abcde_init()
{
//this is just a place holder, or could be the function used
//to initialize the loaded script (sort of a document.ready)
}
Where "abcde" of "page_abcde_init()" is the value of the clicked element var pl = $(this).attr('rel');

jQuery, Uncaught TypeError

I have some javascript code on my webpage that is loading some divs onto the page. I also want to add onmouseenter, and onmouseleave event handlers to each div. I am using jquery to add these handlers, but i get the error:
"Property '$' of object [object DOMWindow] is not a function"
My code looks like this, it is in a for loop:
var newItem = document.createElement('div');
newItem.innerHTML = results[i];
newItem.setAttribute("id", "resultDiv_" + i.toString());
dropDown.appendChild(newItem);
//Error on next line...
$("resultDiv_" + i.toString()).bind("mouseenter", function() {
$("resultDiv_" + i.toString()).css({ 'background-color': 'blue' });
});
Does anyone have any ideas why i am getting this error, or even what the error means?
Try replacing all occurrences of $ with jQuery.
Also the selector $("resultDiv_" + i.toString()) won't likely return any elements. You probably meant: $("#resultDiv_" + i.toString())
And finally make sure this code is executed when the DOM is ready i.e. inside:
jQuery(function() {
// Put your code here
});
Are you sure that jQuery is properly loaded? Could it be a conflict with another javascript library?
(function ($) {
// All your code here
})(jQuery);
This fixed the problem for me.
What about trying this?
var newItem = document.createElement('div');
newItem.innerHTML = results[i];
newItem.setAttribute("id", "resultDiv_" + i.toString());
dropDown.appendChild(newItem);
//Error on next line...
$("resultDiv_" + i.toString()).mouseenter( function() {
$("resultDiv_" + i.toString()).css({ 'background-color': 'blue' });
});
Or make sure that $("resultDiv_" + i.toString()) is not null. Use Firebug to inspect the element.
You might as well try this:
var newItem = jQuery('<div id="' + "resultDiv_" + i.toString() + '">+ results[i] + '</div');
jQuery(dropDown).append(newItem);
//Error on next line...
newItem.mouseenter(function(){
jQuery(this).css( 'background-color', 'blue');
});
or perhaps jQuery.noConflict will solve this.

Categories

Resources