Calling external JS function from internal JS code block - javascript

I have 2 JS blocks that I am working with. One is internal to my HTML. It handles touch functionality. The other is an external file which is a content slider. Basically I want to use the touchevents to control the slider and move to the previous/next slide depending on which direction the user swipes on mobile devices but have more traditional controls on desktops. Is it possible to call a function in the external file from my internal code block.
HTML File
<html>
<head>
<script type="text/javascript" src="js/externalfile.js"></script>
<script>
... lots of code for touchevents ....
function processingRoutine() {
if ( swipeDirection == 'left' ) {
// Function below is in external file
previous();
} else if ( swipeDirection == 'right' ) {
// Function below is in external file
next();
}
</script>
</head>
<body>
Some HTML code
</body>
External JS File
(function($) {
... Functionality to work slider ...
// load the next slide
// These are the functions I am trying to call from above.
function next() {
goToAndPause(counter+1);
};
// load the previous slide
function previous() {
goToAndPause(counter-1);
};
})(jQuery);
Is there an easy way to do this or is there a rotator that has this functionality built in already?

The slider must have been instantiated somehow and you may have a reference to it, i.e. to make the slider work in the first place you might have called something like $('.mySlider').slider();
if you changed that to
window.mySlider = $('.mySlider').slider();
you could then potentially then call mySlider.next() or similar in your "internal" code.

why not just extract your code into an external js file? I don't see any reason you would actually need to have it embedded in the script tag , and in general i think that may be a poor architectural decision.
2nd idea, you could also get to it by declaring a global variable and accessing it, though thats not great practice.

If you don't mind editing the plugin, you could use jQuery's event API.
// external file
(function($) {
....
$(window).on('slider:next', next);
$(window).on('slider:previous', previous);
})(jQuery);
// inline js (this should really live in its own file, too)
function processingRoutine () {
if ( swipeDirection === 'left' ) {
$(window).trigger('slider:next');
} else if ( swipeDirection === 'right' ) {
$(window).trigger('slider:previous');
}
}

Related

Moving inline Javascript to external .js file

I have some inline Javascript in my <body> that I'm trying to export to a .js file. I know that normally you would just copy/paste it over, sometimes including it in a document ready function, but something about this one is different. I'm not super fluent in JS and the code wasn't written by me (but was provided free online).
This is how the code is in my file. If you need any more info just ask!
<body>
<script>
(function (window, document) {
var menu = document.getElementById('menu')
, WINDOW_CHANGE_EVENT = ('onorientationchange' in window) ? 'orientationchange' : 'resize';
function toggleHorizontal() {
[].forEach.call(document.getElementById('menu').querySelectorAll('.custom-can-transform'), function (el) {
el.classList.toggle('pure-menu-horizontal');
});
};
function toggleMenu() {
// set timeout so that the panel has a chance to roll up
// before the menu switches states
if (menu.classList.contains('open')) {
setTimeout(toggleHorizontal, 500);
}
else {
toggleHorizontal();
}
menu.classList.toggle('open');
document.getElementById('toggle').classList.toggle('x');
};
function closeMenu() {
if (menu.classList.contains('open')) {
toggleMenu();
}
}
document.getElementById('toggle').addEventListener('click', function (e) {
toggleMenu();
e.preventDefault();
});
window.addEventListener(WINDOW_CHANGE_EVENT, closeMenu);
})(this, this.document);
</script>
</body>
UPDATE:
I was able to wrap the script in a scope (foo = function() {}) and get it to work externally by adding window.onload = function to the HTML page. This was suggested by #marmeladze and worked.
As suggested by #marmeladze, I was able to wrap the script in a scope (foo = function() {}) and get it to work externally by adding window.onload = function to the HTML page.
So what is the real problem to export it in an external js file?
As always i would copy and past code in a new js. Link it to HTML page and write functions that i need as attribute of HTML's tag (ex. "onload=functioname();" in body's tag).
As marmeladze said you can wrap all in an unique scope so you can call it in body.
Maybe you are doing it so if you maybe can explain better your problem would be great.

jQuery JavaScript not working on Wordpress, confused about no-conflict mode syntax

I am trying to get this codepen http://codepen.io/eternalminerals/pen/qdGvMo working on my wordpress page at http://eternalminerals.com/test/
I know that since Wordpress is in no-conflict mode, I have to change the $ to jQuery, but I did that and made sure the script was in the header as well (using this JS adder plugin css-javascript-toolbox) but it still isn't working like the codepen. I tested the codepen without the javascript and it behaves like the wordpress page, so I know the issue must be in the javascript.
<script type='text/javascript'>
StarWars = (function() {
/*
* Constructor
*/
function StarWars(args) {
// Context wrapper
this.el = jQuery(args.el);
// Audio to play the opening crawl
this.audio = this.el.find('audio').get(0);
// Start the animation
this.start = this.el.find('.start');
// The animation wrapper
this.animation = this.el.find('.animation');
// Remove animation and shows the start screen
this.reset();
// Start the animation on click
this.start.bind('click', jQuery.proxy(function() {
this.start.hide();
this.audio.play();
this.el.append(this.animation);
}, this));
// Reset the animation and shows the start screen
jQuery(this.audio).bind('ended', jQuery.proxy(function() {
this.audio.currentTime = 0;
this.reset();
}, this));
}
/*
* Resets the animation and shows the start screen.
*/
StarWars.prototype.reset = function() {
this.start.show();
this.cloned = this.animation.clone(true);
this.animation.remove();
this.animation = this.cloned;
};
return StarWars;
})();
new StarWars({
el : '.starwars'
});
</script>
There are no javascript console errors on my website page but it behaves as if there is no javascript controlling the html like in the codepen. Any help would be greatly appreciated. Thank you!
If you want to quickly update your jQuery call and pass in jQuery to it's own function then you can do so as shown below:
jQuery(document).ready(function( $ ) {
// $ Works! You can test it with next line if you like
// console.log($);
});
Additionally, and I've executed this methodology myself below, you can pass jQuery in as the dollar sign. NOTE: All jQuery code that uses "$.apis()" instead of "jQuery.apis()" must be within this code snippet which you may also load from an external script if necessary.
(function($) {
// $ Works! You can test it with next line if you like
// console.log($);
})( jQuery );
You can find the link to examples with more detail here: (https://digwp.com/2011/09/using-instead-of-jquery-in-wordpress/)
This solution is designed for wordpress, but I was using in a CMS-serving engine that rendered all the JS files on the backend and only sent out a view. In that scenario I could never use the dollar sign declaration in a typical document.ready function as you are trying so our issue is identical, just with a different engine behind it. This should help, cheers and happy coding!
Ok, thanks to Wordpress embedded javascript on page doesn't work it seems like all I had to do was surround the script with a jQuery ready function:
jQuery(function() {
/* your code here */
)};
http://eternalminerals.com/test/ works now woohoo!

Define more than one onLoad in the same js file

How can i define more than one onload function (but different!)
in the same js file,
for ex,
file.js:
//---on load forpage1
$( document ).ready( handler ){
do something one
}
//---on load for page2
$( document ).ready( handler ){
do something else
}
and import it in both of the 2 pages:
for ex:
page1:
<!DOCTYPE>
<html>
<head>
<script type="text/javascript" src="file.js"></script>
</head>
page2:
<!DOCTYPE>
<html>
<head>
<script type="text/javascript" src="file.js"></script>
</head>
I'm assuming you ask this because you want to execute different code on the other page.
You could for example check location.href to see which page is currently being called.
More usual though is to use server side scripting to determine the current page and refer to the javascript accordingly.
Edit for an example:
$(function () {
var page = window.location.pathname;
if (page == "/index.html") {
// code here
}
else if (page == "/contact.html") {
// other code here
}
});
It depends what you're trying to achieve. If you want several functions to run when your page loads, the code in your post is almost correct:
$(document).ready(function() {
console.log("Function 1 running");
});
$(document).ready(function() {
console.log("Function 2 running");
}
You can also pre-define these functions if you want, and pass them to your $(document).ready() call:
function handler_1() {
console.log("Handler_1 is running");
}
function handler_2() {
console.log("Handler_2 is running");
}
$(document).ready(handler_1);
$(document).ready(handler_2);
And you can even use the jQuery shortcut $():
$(handler_1);
$(handler_2);
But if you want only one function to run when the page loads - depending on which page loaded - you'll need to take another approach. You could define all your code in script.js, and load init_page1.js from page 1, init_page2.js from page 2, etc. Those init files would call whichever setup function is appropriate for the page.
Alternatively, you could add a data attribute on your body tag indicating what page it's on, and have your $(document).ready() call the correct handler. Something like this:
$(document).ready(function() {
var page_type = $('body').data('page-type');
if (page_type == 'home') {
handler_1();
} else if (page_type == 'profile') {
handler_2();
}
});
And then, in your HTML file:
<body data-page-type="profile">
Possibly the neatest solution, though, is to have the callback functions determine whether they're relevant to the page. That way you can re-use them wherever you like. So your script would look something more like this:
function handler_1() { // Only for home page
if ($('body').data('page-type') != 'home') {
return;
}
console.log("I'm the handler_1 function");
}
function handler_2() { // Only for profile page
if ($('body').data('page-type') != 'profile') {
return;
}
}
$(handler_1);
$(handler_2);
Really, though, if you can avoid coding this into your JavaScript, you should. It's better to only include scripts that you know are required for that particular page to function.
In addition to $( document ).ready, which is called after the DOM is fully loaded for the current HTML file, including all images, the $(window).load is another method to detect DOM readiness that is not fired until all sub-elements, like iframes have been loaded and are available for use.
As to your original question, you can define as many $( document ).ready functions as you like; they are executed in the order they are found.
You can have multiple blocks of $(document).ready – but it won't solve your problem as they'll all be called once the DOM is loaded.
I'd recommend you to take a look at Paul Irish's DOM-based Routing.
Your question was very vague but I'm assuming you want multiple items to be called upon the page being loaded, in which the first example is.
document.ready(function(handler){
/*Do thing one*/
/*Do thing two*/
});
But if you mean for them to be called with different scenarios then you would use the handler passed in to check the status of the document and call a different item.
document.ready(function(handler){
if(handler==bar)
//Do thing one
else if(handler==foo)
//Do thing two
else
//Do thing three
});

Uncaught ReferenceError: $ is not defined? Jsfiddle

I'm a beginner at javascript and i have used jsfiddle to create a navigation bar which appears when the user has scrolled down.
When i copy the code to dreamweaver it no longer works?
I have researched and it said something about adding the jquery framework or something?
Or is there a way to do this without the framework?
Link to jsfiddle for full code: http://jsfiddle.net/fNn7K/270/
javascript :
$(window).on('scroll', function () {
console.log($(this).scrollTop());
if ($(this).scrollTop() > 50) {
$('.nav').addClass('visible');
}else if ($(this).scrollTop() <= 50 && $('.nav').hasClass('visible')) {
$('.nav').removeClass('visible');
}
});
Without jQuery you can do :
window.onscroll = function() {
var display = document.body.scrollTop > 150 ? 'inline' : 'none',
elems = document.getElementsByTagName('nav');
for (var i=0; i<elems.length; i++) {
elems[i].style.display = display;
}
}
FIDDLE
When i copy the code to dreamweaver it no longer works?
JS Fiddle assembles a page based on several pieces of user entered data. One of those pieces of data is the selection of a library.
You have to copy the code to the right places in the document and include the same libraries.
Even then, the preview modes of Dreamweaver might not show it up, because they are (or at least were) entirely awful. Do you testing in a real browser.
I have researched and it said something about adding the jquery framework or something?
You need the jQuery library to use jQuery methods, yes.
Or is there a way to do this without the framework?
jQuery is just some JavaScript written by other people. You can reproduce anything it does. A line by line rewrite of your code to not use jQuery would be out of scope for a stackoverflow answer though.
you need to add jquery.js file in your code (dreamweaver)..
add this in between <head> tag
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
in the fiddle you provided, the jquery is already loaded..so you didn't get that error.
and don't forget to wrap your code inside document.ready function (which is again, already added in fiddle)..
$(function(){
$(window).on('scroll', function () {
.....
});
});

Click button on load event

I have the following javascript -
function onLoad() {
if (!(document.applets && document.VLVChart && document.VLVChart.isActive())) {
setTimeout('onLoad()', 200);
return;
}
objChart = document.VLVChart;
PollEvent();
}
function fan() {
objChart.reorganize();
}
And then when the HTML page is loaded -
<body onLoad="onLoad()">
and have a button within the HTML that execute the fan() function -
<input type='button' value='Fan' onClick='fan();'>
Is it possible for me to activate the fan() function within the onload event so that a user does ont have to click the button?
EDIT
After trying the provided answers, on debugging the code breaks on the line -
objChart.reorganize();
Within the fan() function with the error -
SCRIPT5007: Unable to get value of the property 'reorganize': object is null or undefined
This is odd as when I manually click the button on the page, the function works fine.
Solution
After much head scratching I have realised that I was trying to load the fan() function before the page (and more specifically the objChart) had fully loaded. Hence why adding the function in the onLoad event was not working. I added a setTimeout -
function Fan()
{
setTimeout(function(){objChart.reorganize();},3000);
}
<body onload='onLoad(); fan();'>...
However inline JS is best avoided and you would do well to begin looking into centralised event management. There are various advantages to this.
An answer I wrote yesterday to another question outlines why this is. Something like jQuery makes this trivial if it's new for you.
$(function() {
$('body').on('load', function() {
onLoad();
fan();
});
});
Reading your question I assume you didn't even have tried. Just call that function from within your onLoad()-function:
function onLoad()
{
fan();
/* … */
}
Yes.
You can use <body onload='onLoad(); fan();'> as Utkanos suggests.
If you use jQuery, you can also stick a script in the head containing:
$(function(){
...
});
The jQuery function actually fires earlier, as is explained here.

Categories