I'am trying to pass a variable/ value from the fancybox iframe to the parent window without success.
Fancybox is launched from a link with
class="fancybox fancybox.iframe"
My code in the fancybox.iframe is:
$(document).ready(function(){
$('.insert_single').click(function(){
var test = $('.members_body').find('{row.U_USERNAME}');
setTimeout(function(){ parent.$.fancybox.close();},300);return true;
});
});
Where '{row.U_USERNAME}' is the username to find in the iframe.
Then, in the parent there's the following code:
$(document).ready(function(){
$('.fancybox').fancybox(
{
openEffect:'fade',
openSpeed:500,
afterClose: function(){
alert($(".fancybox-iframe").contents().find(test));
$('#form input[name=username]').val()(test);return false;
}
}
);
});
But when the fancybox is closed, there's no alert showing up with the variable "test", nor the variable is showing up as a value or as a text in the input field of the form.
I've read and tried various solutions found here on stackoverflow without success.
Thanks in advance for helping
EDIT
Here's an Example
When the fancybox is closed the iframe is removed from the document. So you must use beforeClose event instead of afterClose
$(document).ready(function() {
$('a.fancybox').fancybox({
openEffect:'fade',
openSpeed:500,
beforeClose: function() {
// working
var $iframe = $('.fancybox-iframe');
alert($('input', $iframe.contents()).val());
},
afterClose: function() {
// not working
var $iframe = $('.fancybox-iframe');
alert($('input', $iframe.contents()).val());
}
});
});
JSFiddle: http://jsfiddle.net/NXY7Y/1/
EDIT:
I edited your jsfiddle (http://jsfiddle.net/NXY7Y/9/). Update is in this link
http://jsfiddle.net/NXY7Y/13/
Main page javscript:
$(document).ready(function() {
$('a.fancybox').fancybox({
openEffect:'fade',
openSpeed:500//,
//beforeClose: function() {
// // working
// var $iframe = $('.fancybox-iframe');
// alert($('input', $iframe.contents()).val());
//},
//afterClose: function() {
// // not working
// var $iframe = $('.fancybox-iframe');
// alert($('input', $iframe.contents()).val());
//}
});
});
function setSelectedUser(userText) {
$('#username').val(userText);
}
No need to use afterClose or beforeClose events. Just access the parent function setSelectedUser from the iframe on link click event like this:
$(document).ready(function() {
$('a.insert_single').click(function() {
parent.setSelectedUser($(this).text());
parent.$.fancybox.close();
});
});
Some clarifications :
You should use .find() to find elements by selector (you are trying to find a variable .find(test), which is not a valid format).
You should use .val() to get the contents of an input field or .val(new_value) to set the contents of an input field
You should use .html() or .text() to get the contents of any element other than input,
example: having this html code
<p class="test">hola</p>
... and this jQuery code
var temp = $(".test").html();
... temp will return hola.
On the other hand, if you have control over the iframed page and it's under the same domain than the parent page, then you may not need to set any jQuery in the child page.
so, having this html in the child (iframed) page for instance
<div class="members_body">
<p>GOOGLE</p>
<p>JSFIDDLE</p>
<p>STACKOVERFLOW</p>
</div>
You could set this jQuery in your parent page to get the contents of any clicked element in your child page :
var _tmpvar; // the var to use through the callbacks
jQuery(document).ready(function ($) {
$(".fancybox").fancybox({
type: "iframe",
afterShow: function () {
var $iframe = $('.fancybox-iframe');
$iframe.contents().find(".members_body p").each(function (i) {
$(this).on("click", function () {
_tmpvar = $('.members_body p:eq(' + i + ')', $iframe.contents()).html();
$.fancybox.close();
}); // on click
}); // each
},
afterClose: function () {
$('#form input[name=username]').val(_tmpvar);
}
});
}); // ready
Notice that we declared the var _tmpvar globally so we can use it within different callbacks.
See JSFIDDLE
I'm trying to do a simple image swap, but when I add in my code for the swap, it doesn't work! I have a function toggling different classes which are animated using CSS which work fine without the image swap code, but once I add it in all of it breaks!
Could someone troubleshoot my code really quickly? I feel like my JQuery logic is a bit off.
jQuery(document).ready(function () {
var toggle = 0;
var toggleClass = function () {
toggle = !toggle;
$(".two").toggleClass("two-menu", toggle);
$(".four").toggleClass("four-menu", toggle);
$(".images").toggleClass("images-menu", toggle);
$(".home").toggleClass("home-menu", toggle);
$("#bottom-left").toggleClass("bottom-left", !toggle);
$("#bottom-right").toggleClass("bottom-right", !toggle);
$("#margin-zero").toggleClass("margin-zero", !toggle);
$(".left-container").toggleClass("left-container-show", toggle);
$(".right-container").toggleClass("right-container-show", toggle);
}
var imageSwap = function () {
this.src = '/wp-content/uploads/2013/11/Twitter.jpg';
}, function () {
this.src = '/wp-content/uploads/2013/11/Facebook.jpg';
}
jQuery(".home").click(function () {
toggleClass();
});
jQuery(".two").click(function () {
toggleClass();
imageSwap();
});
jQuery(".four").click(function () {
toggleClass();
});
});
I've created two JSFiddles.
1) The first does not work, and includes the imageSwap function. http://jsfiddle.net/MuQ2w/
2) The second does not have the imageSwap, and works perfectly. http://jsfiddle.net/E2Rzv/
The problem you are experiencing is because of the syntax of you jQuery imageSwap function, as you can't write two function seperated with a "comma".
I think a possible solution might be to remove the second function.
Also imageSwap function doesnot know about 'this' as it is out of it's scope. You'll need to pass 'this' as an argument to it.
So the final imageSwap function will look like:
var imageSwap = function ($this) {
$this.src = '/wp-content/uploads/2013/11/Facebook.jpg';
}
And your call to this function would be like:
jQuery(".two").click(function () {
imageSwap(this);
toggleClass();
});
I hope it will help.
P.S. Just to follow the tradition, here is a working fiddle:
jsfiddle.net/gKxLz
did you look in your console for the errors? `
var imageSwap = function () {
this.src = '/wp-content/uploads/2013/11/Twitter.jpg';
}, function () {
this.src = '/wp-content/uploads/2013/11/Facebook.jpg';
}
is not correct syntax: the second function has no variable name
It is hard to figure out what is happening without debugging the code.
I am guessing that perhaps the problem is due to the scope of "this" inside imageSwap function.
Try to pass this (for the handler) to imageSwap function as a parameter, like:
var imageSwap = function ($this) {
$this.src = '/wp-content/uploads/2013/11/Twitter.jpg';
}, function ($this) {
$this.src = '/wp-content/uploads/2013/11/Facebook.jpg';
}
jQuery(".two").click(function () {
toggleClass();
imageSwap(this, this);
});
Hope it will work
I want to run a function after a link has been clicked.
The link I would like to point to the function is the one with the cancelLink class. The first link is here to show you as an example how I'm getting the AppointmentId the first link works by passing a parameter to another page.
I would like to be able to click the Cancel link and run a function on the current page.
Here are my links:
Invoice |
<a href="#" class="cancelLink" data-attr=${AppointmentId}>Cancel</a>
Below is my click function which is under the document ready:
$('a.cancelLink').click(function () {
var appointmentId = $(this).attr("data-attr");
//var appointmentId = $(this).attr("appointmentId");
MemberWebService.AppointmentStatusUpdate(appointmentId, 3, function () {
window.location = 'AppointmentViewAll.aspx';
});
});
Currently code does not enter this click function, how could I achieve this?
Your code seems fine to me. Here is a working plunk. Have you tried put a 'console.log("sample test");' inside your click handler to see if it's firing? Could you please also post how did you wrap your code inside $(document).ready() ?
Did you do it this way?
$(document).ready(function() {
$('a.cancelLink').click(function () {
var appointmentId = $(this).attr("data-attr");
//var appointmentId = $(this).attr("appointmentId");
MemberWebService.AppointmentStatusUpdate(appointmentId, 3, function () {
window.location = 'AppointmentViewAll.aspx';
});
});
});
try this:
$('a.cancelLink').click(function (e) {
e.preventDefault();
var appointmentId = $(this).attr("data-attr");
//var appointmentId = $(this).attr("appointmentId");
MemberWebService.AppointmentStatusUpdate(appointmentId, 3, function () {
window.location = 'AppointmentViewAll.aspx';
});
});
i hope it helps.
I found a few possible causes, see my comments;
HTML
Invoice
Cancel // Use quotes
Javascript
$(document).ready(function() { // Only access elements once the DOM is loaded
$(document).on('click', 'a.cancelLink', function(event) { // Try using on() instead of click() as you seem to be using some templating for creating the link ("${AppointmentId}").
event.preventDefault(); // Don´t follow the link to #
var appointmentId = $(this).data('attr'); // Use data() instead of attr()
console.log(event.type, appointmentId); // View your console
MemberWebService.AppointmentStatusUpdate(appointmentId, 3, function() {
window.location = 'AppointmentViewAll.aspx';
});
});
});
See on() and data().
Use the onclick method to call a function and add parameters.
Cancel
function bindCancel(appointmentId) {
MemberWebService.AppointmentStatusUpdate(appointmentId, 3, function () {
});
}
I've written this code for a friend. The idea is he can add a "default" class to his textboxes, so that the default value will be grayed out, and then when he clicks it, it'll disappear, the text will return to its normal color, and then clicking a second time won't clear it:
$(document).ready(function() {
var textbox_click_handler = function clear_textbox() {
$(this).removeClass('default');
$(this).attr('value', '');
$(this).unbind(textbox_click_handler);
};
$(".default").mouseup(textbox_click_handler);
});
The clicking-to-clear works, but I get the following error:
Uncaught TypeError: Object function clear_textbox() { ... } has no method 'split'
what is causing this? How can I fix it? I would just add an anonymous function in the mouseup event, but I'm not sure how I would then unbind it -- I could just unbind everything, but I don't know if he'll want to add more functionality to it (probably not, but hey, he might want a little popup message to appear when certain textboxes are clicked, or something).
How can I fix it? What is the 'split' method for? I'm guessing it has to do with the unbind function, since the clearing works, but clicking a second time still clears it.
You can do it like this:
var textbox_click_handler = function(e) {
$(this).removeClass('default')
.attr('value', '')
.unbind(e.type, arguments.callee);
};
$(function() {
$(".default").mouseup(textbox_click_handler);
});
Or use the .one function instead that automatically unbinds the event:
$(function() {
$(".default").one('mouseup', function() {
$(this).removeClass('default').attr('value', '');
});
});
The unbind needs an event handler while you are specifying a function to its argument thereby giving you the error.
I am not sure if this is really different but try assigning the function to a variable:
var c = function clear_textbox() {
$(this).removeClass('default');
$(this).attr('value', '');
$(this).unbind('mouseup');
}
and then:
$(".default").mouseup(function(){
c();
});
if you don't want to completely unbind mouseup, check for the current state using hasClass(). No need to unbind anything.
$(document).ready(function() {
$('.default').bind('mouseup', function(e) {
var tb = $(this);
if(tb.hasClass('default')) {
tb.removeClass('default').val('');
}
});
});
Make sure you are unbinding mouseup:
function clear_textbox() {
$(this).removeClass('default');
$(this).attr('value', '');
$(this).unbind('mouseup');
}
$(function() {
$('.default').mouseup(clear_textbox);
});
Also I would write this as a plugin form:
(function($) {
$.fn.watermark = function(settings) {
this.each(function() {
$(this).css('color', 'gray');
$(this).mouseup(function() {
var $this = $(this);
$this.attr('value', '');
$this.unbind('mouseup');
});
});
return this;
};
})(jQuery);
so that your friend can simply:
$(function() {
$('.someClassYourFriendUses').watermark();
});
I'm using jQuery in my site and I would like to trigger certain actions when a certain div is made visible.
Is it possible to attach some sort of "isvisible" event handler to arbitrary divs and have certain code run when they the div is made visible?
I would like something like the following pseudocode:
$(function() {
$('#contentDiv').isvisible(function() {
alert("do something");
});
});
The alert("do something") code should not fire until the contentDiv is actually made visible.
Thanks.
You could always add to the original .show() method so you don't have to trigger events every time you show something or if you need it to work with legacy code:
Jquery extension:
jQuery(function($) {
var _oldShow = $.fn.show;
$.fn.show = function(speed, oldCallback) {
return $(this).each(function() {
var obj = $(this),
newCallback = function() {
if ($.isFunction(oldCallback)) {
oldCallback.apply(obj);
}
obj.trigger('afterShow');
};
// you can trigger a before show if you want
obj.trigger('beforeShow');
// now use the old function to show the element passing the new callback
_oldShow.apply(obj, [speed, newCallback]);
});
}
});
Usage example:
jQuery(function($) {
$('#test')
.bind('beforeShow', function() {
alert('beforeShow');
})
.bind('afterShow', function() {
alert('afterShow');
})
.show(1000, function() {
alert('in show callback');
})
.show();
});
This effectively lets you do something beforeShow and afterShow while still executing the normal behavior of the original .show() method.
You could also create another method so you don't have to override the original .show() method.
The problem is being addressed by DOM mutation observers. They allow you to bind an observer (a function) to events of changing content, text or attributes of dom elements.
With the release of IE11, all major browsers support this feature, check http://caniuse.com/mutationobserver
The example code is a follows:
$(function() {
$('#show').click(function() {
$('#testdiv').show();
});
var observer = new MutationObserver(function(mutations) {
alert('Attributes changed!');
});
var target = document.querySelector('#testdiv');
observer.observe(target, {
attributes: true
});
});
<div id="testdiv" style="display:none;">hidden</div>
<button id="show">Show hidden div</button>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
There is no native event you can hook into for this however you can trigger an event from your script after you have made the div visible using the .trigger function
e.g
//declare event to run when div is visible
function isVisible(){
//do something
}
//hookup the event
$('#someDivId').bind('isVisible', isVisible);
//show div and trigger custom event in callback when div is visible
$('#someDivId').show('slow', function(){
$(this).trigger('isVisible');
});
You can use jQuery's Live Query plugin.
And write code as follows:
$('#contentDiv:visible').livequery(function() {
alert("do something");
});
Then everytime the contentDiv is visible, "do something" will be alerted!
redsquare's solution is the right answer.
But as an IN-THEORY solution you can write a function which is selecting the elements classed by .visibilityCheck (not all visible elements) and check their visibility property value; if true then do something.
Afterward, the function should be performed periodically using the setInterval() function. You can stop the timer using the clearInterval() upon successful call-out.
Here's an example:
function foo() {
$('.visibilityCheck').each(function() {
if ($(this).is(':visible')){
// do something
}
});
}
window.setInterval(foo, 100);
You can also perform some performance improvements on it, however, the solution is basically absurd to be used in action. So...
The following code (pulled from http://maximeparmentier.com/2012/11/06/bind-show-hide-events-with-jquery/) will enable you to use $('#someDiv').on('show', someFunc);.
(function ($) {
$.each(['show', 'hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
return el.apply(this, arguments);
};
});
})(jQuery);
If you want to trigger the event on all elements (and child elements) that are actually made visible, by $.show, toggle, toggleClass, addClass, or removeClass:
$.each(["show", "toggle", "toggleClass", "addClass", "removeClass"], function(){
var _oldFn = $.fn[this];
$.fn[this] = function(){
var hidden = this.find(":hidden").add(this.filter(":hidden"));
var result = _oldFn.apply(this, arguments);
hidden.filter(":visible").each(function(){
$(this).triggerHandler("show"); //No bubbling
});
return result;
}
});
And now your element:
$("#myLazyUl").bind("show", function(){
alert(this);
});
You could add overrides to additional jQuery functions by adding them to the array at the top (like "attr")
a hide/show event trigger based on Glenns ideea:
removed toggle because it fires show/hide and we don't want 2fires for one event
$(function(){
$.each(["show","hide", "toggleClass", "addClass", "removeClass"], function(){
var _oldFn = $.fn[this];
$.fn[this] = function(){
var hidden = this.find(":hidden").add(this.filter(":hidden"));
var visible = this.find(":visible").add(this.filter(":visible"));
var result = _oldFn.apply(this, arguments);
hidden.filter(":visible").each(function(){
$(this).triggerHandler("show");
});
visible.filter(":hidden").each(function(){
$(this).triggerHandler("hide");
});
return result;
}
});
});
I had this same problem and created a jQuery plugin to solve it for our site.
https://github.com/shaunbowe/jquery.visibilityChanged
Here is how you would use it based on your example:
$('#contentDiv').visibilityChanged(function(element, visible) {
alert("do something");
});
What helped me here is recent ResizeObserver spec polyfill:
const divEl = $('#section60');
const ro = new ResizeObserver(() => {
if (divEl.is(':visible')) {
console.log("it's visible now!");
}
});
ro.observe(divEl[0]);
Note that it's crossbrowser and performant (no polling).
Just bind a trigger with the selector and put the code into the trigger event:
jQuery(function() {
jQuery("#contentDiv:hidden").show().trigger('show');
jQuery('#contentDiv').on('show', function() {
console.log('#contentDiv is now visible');
// your code here
});
});
Use jQuery Waypoints :
$('#contentDiv').waypoint(function() {
alert('do something');
});
Other examples on the site of jQuery Waypoints.
I did a simple setinterval function to achieve this. If element with class div1 is visible, it sets div2 to be visible. I know not a good method, but a simple fix.
setInterval(function(){
if($('.div1').is(':visible')){
$('.div2').show();
}
else {
$('.div2').hide();
}
}, 100);
You can also try jQuery appear plugin as mentioned in parallel thread https://stackoverflow.com/a/3535028/741782
This support easing and trigger event after animation done! [tested on jQuery 2.2.4]
(function ($) {
$.each(['show', 'hide', 'fadeOut', 'fadeIn'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
var result = el.apply(this, arguments);
var _self=this;
result.promise().done(function () {
_self.triggerHandler(ev, [result]);
//console.log(_self);
});
return result;
};
});
})(jQuery);
Inspired By http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/
There is a jQuery plugin available for watching change in DOM attributes,
https://github.com/darcyclarke/jQuery-Watch-Plugin
The plugin wraps All you need do is bind MutationObserver
You can then use it to watch the div using:
$("#selector").watch('css', function() {
console.log("Visibility: " + this.style.display == 'none'?'hidden':'shown'));
//or any random events
});
Hope this will do the job in simplest manner:
$("#myID").on('show').trigger('displayShow');
$('#myID').off('displayShow').on('displayShow', function(e) {
console.log('This event will be triggered when myID will be visible');
});
I changed the hide/show event trigger from Catalint based on Glenns idea.
My problem was that I have a modular application. I change between modules showing and hiding divs parents. Then when I hide a module and show another one, with his method I have a visible delay when I change between modules. I only need sometimes to liten this event, and in some special childs. So I decided to notify only the childs with the class "displayObserver"
$.each(["show", "hide", "toggleClass", "addClass", "removeClass"], function () {
var _oldFn = $.fn[this];
$.fn[this] = function () {
var hidden = this.find(".displayObserver:hidden").add(this.filter(":hidden"));
var visible = this.find(".displayObserver:visible").add(this.filter(":visible"));
var result = _oldFn.apply(this, arguments);
hidden.filter(":visible").each(function () {
$(this).triggerHandler("show");
});
visible.filter(":hidden").each(function () {
$(this).triggerHandler("hide");
});
return result;
}
});
Then when a child wants to listen for "show" or "hide" event I have to add him the class "displayObserver", and when It does not want to continue listen it, I remove him the class
bindDisplayEvent: function () {
$("#child1").addClass("displayObserver");
$("#child1").off("show", this.onParentShow);
$("#child1").on("show", this.onParentShow);
},
bindDisplayEvent: function () {
$("#child1").removeClass("displayObserver");
$("#child1").off("show", this.onParentShow);
},
I wish help
One way to do this.
Works only on visibility changes that are made by css class change, but can be extended to watch for attribute changes too.
var observer = new MutationObserver(function(mutations) {
var clone = $(mutations[0].target).clone();
clone.removeClass();
for(var i = 0; i < mutations.length; i++){
clone.addClass(mutations[i].oldValue);
}
$(document.body).append(clone);
var cloneVisibility = $(clone).is(":visible");
$(clone).remove();
if (cloneVisibility != $(mutations[0].target).is(":visible")){
var visibilityChangedEvent = document.createEvent('Event');
visibilityChangedEvent.initEvent('visibilityChanged', true, true);
mutations[0].target.dispatchEvent(visibilityChangedEvent);
}
});
var targets = $('.ui-collapsible-content');
$.each(targets, function(i,target){
target.addEventListener('visibilityChanged',VisbilityChanedEventHandler});
target.addEventListener('DOMNodeRemovedFromDocument',VisbilityChanedEventHandler });
observer.observe(target, { attributes: true, attributeFilter : ['class'], childList: false, attributeOldValue: true });
});
function VisbilityChanedEventHandler(e){console.log('Kaboom babe'); console.log(e.target); }
my solution:
; (function ($) {
$.each([ "toggle", "show", "hide" ], function( i, name ) {
var cssFn = $.fn[ name ];
$.fn[ name ] = function( speed, easing, callback ) {
if(speed == null || typeof speed === "boolean"){
var ret=cssFn.apply( this, arguments )
$.fn.triggerVisibleEvent.apply(this,arguments)
return ret
}else{
var that=this
var new_callback=function(){
callback.call(this)
$.fn.triggerVisibleEvent.apply(that,arguments)
}
var ret=this.animate( genFx( name, true ), speed, easing, new_callback )
return ret
}
};
});
$.fn.triggerVisibleEvent=function(){
this.each(function(){
if($(this).is(':visible')){
$(this).trigger('visible')
$(this).find('[data-trigger-visible-event]').triggerVisibleEvent()
}
})
}
})(jQuery);
example usage:
if(!$info_center.is(':visible')){
$info_center.attr('data-trigger-visible-event','true').one('visible',processMoreLessButton)
}else{
processMoreLessButton()
}
function processMoreLessButton(){
//some logic
}
$( window ).scroll(function(e,i) {
win_top = $( window ).scrollTop();
win_bottom = $( window ).height() + win_top;
//console.log( win_top,win_bottom );
$('.onvisible').each(function()
{
t = $(this).offset().top;
b = t + $(this).height();
if( t > win_top && b < win_bottom )
alert("do something");
});
});
$(function() {
$(document).click(function (){
if ($('#contentDiv').is(':visible')) {
alert("Visible");
} else {
alert("Hidden");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="contentDiv">Test I'm here</div>
<button onclick="$('#contentDiv').toggle();">Toggle the div</button>
<div id="welcometo">Özhan</div>
<input type="button" name="ooo"
onclick="JavaScript:
if(document.all.welcometo.style.display=='none') {
document.all.welcometo.style.display='';
} else {
document.all.welcometo.style.display='none';
}">
This code auto control not required query visible or unvisible control