I'd like to perform a function on only one page of my site where the body has an ID of #modulePage16460412. I have the script below that is not working.
<script type="text/javascript">
if($('#modulePage16460412').length > 0 ) {
$(function()
{
$(window).bind('load',
function(e)
{
window.setTimeout(function()
{
$.colorbox({opacity:0.3, href:"/storage/support/colorbox/offer.html"});
}, /*timeout->*/ 2000);
});
});
}
</script>
Would it also be possible to only execute the function the first time they visit the page and not execute again if they come back to that page?
Any help would be appreciated.
You can just put the function on the body load selecting it with the ID specified... if no element exists with this ID then the function will never fire.
$('#modulePage16460412').load(function() { // this will not be called unless an element with that ID has loaded into the DOM
// ... your code here.
});
and to touch on the 'single execution' part (this really should be a new question... but ohh well) you can use localStorage to persist the setting.
http://jsfiddle.net/rlemon/ET9Zg/
in your case something like
if( !getData('someKey') ) {
// ok so they have not been here.
setData('someKey', 1); // now set the data so this won't get hit again.
}
You need to put the condition inside $(function(){ so that the body tag is actually loaded before the JavaScript queries the (unloaded) DOM for the existence of the ID.
$(function(){
if($('#modulePage16460412').length) {
...
}
});
your defining a function, but not calling anywhere.
so put everything inside some function and call.
and also replace this if($('#modulePage16460412').length > 0 ) with if($('#modulePage16460412')), because when jquery couldnt find element with id : #modulePage16460412, it will return empty array. empty_array.length = 0, so it will always be true.
$('document').ready(function(){
if($('#modulePage16460412')) {
$(function()
{
$(window).bind('load',
function(e)
{
window.setTimeout(function()
{
$.colorbox({opacity:0.3, href:"/storage/support/colorbox/offer.html"});
}, /*timeout->*/ 2000);
});
});
}
});
Perhaps a simpler approach?
$( document ).ready( function() { // runs code only after DOM ready
if ( $( '#modulePage16460412' ).length > 0 ) { // runs code only if id found
window.setTimeout( function() {
$.colorbox( { opacity:0.3, href:"/storage/support/colorbox/offer.html" } );
}, 2000 );
}
} );
Related
I use a jQuery window libray https://github.com/humaan/Modaal
which triggers events this way $("class of element").modaal({arg1, arg2,...});
--- I updated my question here to make it more general and used an iframe / Html instead of an external svg ---
To trigger an element e.g. in an external Html which is loaded within an iframe, I applied the following code to the iframe:
<iframe src="External.html" id="mainContent" onload="access()"></iframe>
which calls this function:
function access() {
var html = document.getElementById("mainContent").contentDocument.getElementById("IDofDIVelement");
html.addEventListener('click', function() {clicker();});
}
function clicker()
{
// console.log('hooray!');
$("#mainContent").contents().find("IDofDIVelement").modaal({});
//return false;
}
Actually it will only work on every second click. Any idea what I did not consider properly?
Best
You do not need to wait windows loading but iframe only:
$(function() {
$("#mainContent").bind("load",function(){
var myIframeElement = $(this).contents().find(".modaal");
myIframeElement.modaal({
content_source: '#iframe-content',
type: 'inline',
});
});
});
The reason why it did not work was that the iframe was not completely loaded, while jQuery tried to attach the function. As $(document).ready(function(){} did not work, the workaround was to initialize it with
$( window ).on( "load",function() {
$("#mainContent").contents().find("IDofDIVelement").modaal({});
});
This worked properly to attach the functionallity to an element within the iframe.
Actually modaal will vanish the envent handler after the overlay was opened and closed again.
So maybe someone wants to trigger an iframe element for modaal, too, here is a setup which would solve this issue.
(It can be optimised by #SvenLiivaks answer):
$(window).on("load", function() {
reload();
});
function reload() {
var length = $("#iframeID").contents().find("#IDofDIVelement").length;
// The following check will return 1, as the iframe exists.
if (length == 0) {
setTimeout(function() { reload() }, 500);
} else {
$("#iframeID").contents().find("#IDofDIVelement").modaal({
content_source: '#modalwrapper',
overlay_close: true,
after_close: function reattach() {
reload();
}
});
}
}
Consider this function:
function hideElements( selector ) {
var number = $( selector ).length;
if ( number ) {
$( selector ).animate( { opacity: 0 }, 1000, function() {
*RETURN* number + " elements are now completely hidden.';
} );
} else return "No matching elements found";
}
var returnedMessage = hideElements( ".hideable-divs" );
The uppercase RETURN is the callback's return and so it won't work; I just put it there to convey the idea. How can I make it so the hideElement function returns something only after the animation is complete? Yes, whatever code that needs the returnedMessage variable will have to wait (synchronously(?)) until the animation is complete. Thank you!
** EDIT ** This isn't a duplicate question but rather a very specific scenario I'm dealing with:
A third-party script uses a confirm dialog to ask the user if they're sure they want to delete a div. If the user clicks OK, the element is removed instantly from the DOM.
My goal is to:
Bypass the confirmation dialog so the user doesn't have to confirm.
Animate the deletion so the user clearly sees it happening and, in case they clicked by accident, undo if necessary.
For this, I'm redeclaring window.confirm like in the code sample below. (To eliminate any confusion, please note that this update changes the idea behind my original question and the code block I posted above.)
var clickTarget;
$( document ).on( 'mousedown', function( event ) {
clickTarget = event.target;
} );
window.confirm = function( message ) {
if ( message.indexOf( 'OK to delete' ) !== -1 ) {
var $element = $( clickTarget ).parent();
$element.animate( { height: 0 }, 1000, 'swing', function() {} );
return true; // the 3rd party script receives this confirmation asynchronously and removes $element before it has a chance to be animated.
} else return confirm( message );
};
At the moment I'm achieving the effect by creating a clone and animating that instead of the actual element to be deleted. But this is rather "dirty" and I was wondering if there's a "cleaner" way to do it. Thanks!
As suggested in the link provided by Weedoze, normally you don't want to block a script on asynchronous code, but rather provide a callback.
The main difference with said link is that you want to wait till all animations are completed, not call it on each element's animation finish. In JQuery you can do that with .promise().done():
function hideElements( selector, callBack ) {
var sel = $( selector );
if ( sel.length) {
sel.animate( { opacity: 0 }, 1000).promise().done(function(){
callBack(sel.length + " elements are now completely hidden.");
});
} else
callBack("No matching elements found");
}
hideElements('div', console.log);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>a</div>
<div>b</div>
<div>c</div>
An alternative would be to make your hideElements function itself return a Promise (and return a resolved promise if no elements are found):
function hideElements( selector ) {
var sel = $( selector );
if ( sel.length) {
return sel.fadeOut(1000).promise().then(function(){
return sel.length + " elements are now completely hidden.";
});
} else
return Promise.resolve(("No matching elements found"));
}
hideElements('div').then(console.log);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>a</div>
<div>b</div>
<div>c</div>
edit
Based on the added info: letting the 3rd party code wait is a bit tricky. You can make your own code wait (e.g. with async await), but by definition the calling code should continue (not blocking the ui).
What you can do is cancel the delete on the first click (return false), but remember which element the code was called for. Then in the callback, invoke the click on the same element to restart the 3rd party code and this time return true to let the delete proceed:
let clickTarget, curDelete;
$( document ).on( 'mousedown', function( event ) {
clickTarget = event.target;
} );
let defConfirm = window.confirm; //needed to store the default functionality to avoid recursion in the call below
window.confirm = function(message) {
if ( message.indexOf( 'OK to delete' ) !== -1 ) {
if(clickTarget === curDelete)return true; //the confirm is called from the current delete, invoked by the click from the callback, return true
var $element = $( clickTarget ).parent(); //layout based on your example
$element.slideUp(2000, function(){ //used slide up, but the callback can be used for any animation
curDelete = clickTarget; //NB: perhaps an extra check is needed to see if another delete isn't started?
$(curDelete).click(); //invoke 3rd party script by emulating click (preferably, if a method is known it is called directly)
});
return false; //this result is returned before the animation finishes to stop the direct deletion
} else return defConfirm( message ); //show default confirm window
};
//3rd party spoof
$('div > div').click(function(){
if(confirm('dsaf asfda OK to delete aadf?'))
console.log('3rd Party delete executing');
});
div > div{
width:100px;
border: 1px solid gray;
margin: 2px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div id=a>click me</div>
<div id=a>or me</div>
<div id=a>or me</div>
</div>
I have a function that works on the body onload="" but I need it to load before other elements of the page and I'm trying to add the document ready function in the header but it just doesn't seem to work.
f1menu() {
$('.menuH').hover(
function() {
$('.menuC').stop().animate({width: '90px'},333)
},
function() {
$('.menuC').stop().animate({width: '-0'}, 333)
}
);
}
$(document).ready(function() {
f1menu();
});
So the onload function that works is just this one below:
onload="$('.menuH').hover(function() {$('.menuC').stop().animate({width: '90px'}, 333)}, function() {$('.menuC').stop().animate({width: '-0'}, 333)});"
Note that the following answer was provided before the OP changed the question.
You should write:
function f1menu(){}
not,
f1menu(){}
In addition, you can streamline your document.ready code by simply passing the function that you want called when the document is ready, directly to jQuery:
$(function() {
$('.menuH').hover(
function() {
$('.menuC').stop().animate({width: '90px'}, 333);
},
function() {
$('.menuC').stop().animate({width: '-0'}, 333);
}
);
});
UPDATE:
After OP revised the question, the solution (not a recommended approach by the way) would be to just insert the script into the body of the page, but AFTER any elements that the function references, such as:
<body>
<!-- elements that the code references must come before the code -->
<script>
// .menuH and .menuC elements must have already been loaded into DOM
$('.menuH').hover(
function() {
$('.menuC').stop().animate({width: '90px'},333)
},
function() {
$('.menuC').stop().animate({width: '-0'}, 333)
}
);
</script>
<!-- Rest of HTML -->
</body>
It doesnt know f1menu is a function since you didnt declare it as one. Try this:
function f1menu(){
//logic
}
I have a js function which looks like this
function showProducts(){
document.getElementById("shopList").innerHTML = "<ul><li>Test Text</li></ul>";
}
It's a function that has to show an array of my products. I've made an div with id="shopList" in my html page
<div id="shopList">
</div>
But how can I call the function to show me the text in the div? It works when I use this as my body tag but I'm not allowed to write any js code in my html or to use onload or onclick. I'm trying to do it with listeners for almost 4 hours and I still did not find a solution. Could someone help me?
<body onload="showProducts()">
Using pure javascript:
window.onload = function(){
};
(or
function doLoad() {
//Do stuff on load
}
window.onload = doLoad;
With Jquery
$(document).ready(function(){
});
It's not difficult with listeners. Here is a solution (not cross-browser):
document.addEventListener("DOMContentLoaded", showProducts);
Really, assigning to onload is just shorthand for doing it with listeners. This should work , though I haven't tested it.
window.addEventListener("load", showProducts);
With Jquery you could do something like this :
$(document).ready(function(){
showProducts();
});
It waits untill the page is loaded and then executes the function.
You just put it in an external .js file and include it in your page.
(For the people downvoting this answer because it's Jquery, he said he couldn't use onload() so I just mentioned this option. )
Just place the script at the bottom:
<body>
...
<script type="text/javascript">
myFunction();
</script>
</body>
John Resig's simplified version from "Pro JavaScript Techniques". It depends on addEvent.
var ready = ( function () {
function ready( f ) {
if( ready.done ) return f();
if( ready.timer ) {
ready.ready.push(f);
} else {
addEvent( window, "load", isDOMReady );
ready.ready = [ f ];
ready.timer = setInterval(isDOMReady, 13);
}
};
function isDOMReady() {
if( ready.done ) return false;
if( document && document.getElementsByTagName && document.getElementById && document.body ) {
clearInterval( ready.timer );
ready.timer = null;
for( var i = 0; i < ready.ready.length; i++ ) {
ready.ready[i]();
}
ready.ready = null;
ready.done = true;
}
}
return ready;
})();
window.onload would work, but it is a different beast. jQuery's $(document).ready() is much more complex and better in most scenarios.
Given your criteria of "no script in the HTML" and "no onload or onclick listener", you can put the function into a separate file and run it from a script element at the foot of the page:
<script type="text/javascript" src="showproducts.js"></script>
so now you have no script in the page and no listeners. The code will be executed when the element is added to the DOM, so as long as it is after the related DIV, you're fine.
Incidentally, you don't even need a function, you can just put the statements from the function body into the file.
I have this code that works on this site: http://jsfiddle.net/FPNBe/2/
However, the exact code doesn't work on my site. (With the exception I had to add
<script TYPE="text/javascript"> & < /script> around the javascript.)
Is there something I'm missing?
Wrap the script inside $(document).ready()
$(document).ready(function () {
$('#password, #confirmpassword').keyup(function() { checkPass(); } );
});
This line:
$('#password, #confirmpassword').keyup(function() { checkPass(); } );
Must only be executed after the elements in question have been added to the DOM (Document Object Model) by the browser, so that jQuery can find them. To wait until the DOM is ready, meaning that all the page's elements are accessible, you can put this line inside a function, which you can pass to jQuery:
$(document).ready(function() {
$('#password, #confirmpassword').keyup(function() { checkPass(); } );
});
Or a bit shorter:
$(function() {
$('#password, #confirmpassword').keyup(function() { checkPass(); } );
});