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.
Related
I have some legacy jQuery executing in the page that can't be moved i.e.
jQuery(document).bind('click', function(){
console.log('click');
});
Now that loading of jQuery is at the bottom of the page 'AFTER' the above inline code, the page errors 'jQuery is undefined'
I would like to use a pattern similar to this:
var deferInlineScripts = [];
window.$ = function(inlineFunction) {
deferInlineScripts.push(inlineFunction);
};
Seen working here: https://jsfiddle.net/xpvt214o/165864/
that takes the inline scripts and executes them (Once jQuery is loaded') using
for (i = 0; i < deferInlineScripts.length; i++) {
deferInlineScripts[i]();
}
But unlike the Fiddle my legacy code doesn't have the $(function(){}); and can't be moved, changed or have anything wrapped around it i.e
jQuery(document).bind('click', function(){
console.log('click');
});
jQuery(document).ready(function(){
console.log('ready');
});
Here is the Fiddle https://jsfiddle.net/xpvt214o/165972/ that I would like to fix so the the Bind & Ready functions execute after jQuery is loaded.
Initially define window.jQuery as a function that returns a Proxy. This proxy will allow subsequent arbitrary psuedo-propery lookups (such as .bind in jQuery(document).bind) to be performed. The properties accessed and the arguments the resulting function is eventually called with can be stored in an array and then executed once jQuery is properly loaded.
<script>
const deferCallHandler = {
get: function(jqFirstArg, jqProp) {
return function(...secondArgs) {
deferredInlineScripts.push({
jqFirstArg,
jqProp,
secondArgs,
});
}
}
};
const deferredInlineScripts = [];
window.jQuery = function(jqFirstArg) {
return new Proxy(jqFirstArg, deferCallHandler);
}
document.addEventListener('DOMContentLoaded', function(){
// window.jQuery has now been properly assigned to the true jQuery object
deferredInlineScripts.forEach(({ jqFirstArg, jqProp, secondArgs }) => {
jQuery(jqFirstArg)[jqProp](...secondArgs);
});
});
/* Can't change this code */
jQuery(document).bind('click', function(){
console.log('click');
});
jQuery(document).ready(function(){
console.log('ready');
});
</script>
<div>some element</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function() {
this._innerHTML = this.innerHTML;
}
document.registerElement('template-mini', {
prototype: proto
})
</script>
<template-mini id='example1'>
<script type='text/beforeUpdate'>
console.log('hi')
this.name = 'Bob'
</script>
<p>hello {{name}}</p>
</template-mini>
<template-mini id='example2'>
<p>hello</p>
<script type='text/beforeUpdate'>
console.log('hi')
</script>
</template-mini>
<script>
console.log(example1._innerHTML)
console.log(example2._innerHTML)
</script>
I'm developing a custom-element called template-mini https://github.com/zhoukekestar/webcomponents/tree/master/components/template-mini
When i use this template-mini, i need a preprocessor to modify data or add some function that can be used in template. So i have a script typed beforeUpdate, Unfortunately, i had the below issue:
https://bugs.chromium.org/p/chromium/issues/detail?id=502872
What should i do ? I want to get full innerHTML ( the script will be executed by my custom element ).
There are several solutions.
1. If you can, wait for the document to be loaded before registering the <template-mini> custom element. Therefore you'll be sure that the content of the element is fully parsed when createdCallback() is called:
document.addEventListener( 'DOMContentLoaded', function () {
document.registerElement( 'template-mini', { prototype: proto } )
} )
2. Use another tag than <script>, for example <script-mini>. Anyway because of its specific type attribute it won't be interpreted as a normal script element.
3. You can defer the time you'll get the content by using a function like setTimeout() or requestAnimationFrame():
proto.createdCallback= function () {
setTimeout( function ( e ) {
e._innerHTML = e.innerHTML
console.log( e._innerHTML )
}, 0, this )
}
I'd recommend solution 2.
I am using jquery 1.9.1. I have logout code where I need to post to multiple pages then do a redirect:
<script type="text/javascript">
window.onload=function(){
$( document ).ajaxStop(function() {
logoutRedirect();
});
logoutOfApps();
}
</script>
These methods are in a different javascript file (but I think that is irrelavent).
function logoutOfApps(){
$.post("/app1/logout");
$.post("/app2/logout");
}
function logoutRedirect(){
var redirectOnLogoutURL = null;
redirectOnLogoutURL = "/mylogoutdisplaypage";
top.location = redirectOnLogoutURL;
}
SECOND TRY: This also doesn't work consistently:
<script type="text/javascript">
window.onload=function(){
logoutOfApps();
logoutRedirect();
}
</script>
Make sure both requests have finished before you redirect
function logoutOfApps(){
return $.when(
$.post("/app1/logout"),
$.post("/app2/logout")
)
}
logoutOfApps().done(logoutRedirect);
Just for completeness thought I would document exactly how I changed it, which took a little while to get just right. Thank you adeneo for your answer that I accepted.
<script type="text/javascript">
window.onload=function(){
onLoadOfPage();
}
</script>
This is in the second file (I preferred all jquery code in one file):
function onLoadOfPage(){
$( document ).ajaxStop(function() {
logoutRedirect();
});
logoutOfApps().done(logoutRedirect);
}
function logoutOfApps(){
return $.when(
$.post("/app1/logout"),
$.post("/app2/logout")
)
}
function logoutRedirect(){
var redirectOnLogoutURL = null;
redirectOnLogoutURL = "/mylogoutdisplaypage";
top.location = redirectOnLogoutURL;
}
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 );
}
} );
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(); } );
});