<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="/jquery-2.1.0.min.js"></script>
<title>Title!</title>
<script type="text/javascript">
var x = false;
function foo() {
alert (x);
return true;
}
window.onload = function() {
$('#my_form').attr('onsubmit', foo);
$('a').click(function(e) {
x = true;
$('#my_form').submit();
return false;
});
}
</script>
</head>
<body>
<form id="my_form" action="">
<input type="submit">
</form>
Click here!
</body>
</html>
The 'a' click function sets the variable x to be true, why it is false when foo() is run?
Raw JS events do not work the same way as jQuery events. Don't mix the two.
attr allows you to supply a function as the second parameter. That is why your code fires immediately. It is simply assigning the return value to the attribute, e.g. onsubmit="true"
Your current fiddle fires the foo handler as soon as you run this line:
$('#my_form').attr('onsubmit', foo)
You probably meant something like this (or equivalent), but it does not work either:
$('#my_form').attr('onsubmit', "javascript:foo()");
Here is the jQuery equivalent:
var x = false;
function foo() {
alert (x);
return true;
}
$(function() {
$('#my_form').submit(foo);
$('a').click(function(e) {
x = true;
$('#my_form').submit();
return false;
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/Lf8hhwvq/
The shortcut DOM ready handler I use above, $(function(){...});, also acts as an IIFE, so you can move the related code inside it:
$(function () {
var x = false;
function foo() {
alert(x);
return true;
}
$('#my_form').submit(foo);
$('a').click(function (e) {
x = true;
$('#my_form').submit();
return false;
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/Lf8hhwvq/1/
There are quite a few problems with this code. First of all, you are mixing old parts of the DOM API with jQuery. In your case I would recommend just to stick to jQuery. Amongst other things:
You should put all render-blocking code (that includes code that changes the DOM) before the </body> Tag, not in the <head>. Depending on the size of your JavaScript dependencies, your page will load very slowly.
Don't use window.load =, especially if jQuery has its very own $(document).ready() function, that probably meets your needs even better.
If you want to set an event handler, don't try to set it with the attr function. That's a very old way of doing it and also the source of your problem. Use the jQuery .on() function instead (the jQuery equivalent of .addEventListener).
If you can avoid it, don't use global variables. Wrap all your code in an IIFE instead.
Thus, your code becomes:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title!</title>
</head>
<body>
<form id="my_form" action="">
<input type="submit">
</form>
Click here!
<script src="/jquery-2.1.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var x = false;
function foo() {
alert (x);
return true;
}
$('#my_form').on('submit', foo);
$('a').on('click', function(e) {
x = true;
$('#my_form').submit();
return false;
});
});
</script>
</body>
</html>
Codepen: http://codepen.io/anon/pen/zvaOLR
Related
When I click a button I want to change the onclick of the html tag.
Here's my code:
JavaScript:
function reset() {
//some code 1
}
function hit() {
//some code 2
document.getElementById("htmlId").onclick = reset;
}
HTML:
<!DOCTYPE html>
<html id = "htmlId">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width height=device-height">
</head>
<body>
<button id = "btn1" onclick = "hit();" class = "btn">Hit</button>
<script src="script.js">
</script>
</body>
</html>
When I click the button I expect for some code 2 to execute and on my next click for some code 1 to execute. But when I click both some code 1 and some code 2 execute immediately.
If you add an empty onclick before it, reset(); still runs.
JavaScript:
function empty() {
}
function hit() {
//some code 2
document.getElementById("htmlId").onclick = empty;
document.getElementById("htmlId").onclick = reset;
}
How can I fix this?
There are a few things going on here that are interesting to address:
You have JavaScript in HTML attributes which is no longer considered good practice.
Dealing with the whole HTML element and a button inside of that element that you want to manage will lead to bubble and capture issues
You want to change the listeners on elements but you are using the onclick property while modern practice is to use addEventListener and removeEventListener.
Here are my suggestions:
Put all of the JavaScript listeners in the JS file; your HTML should be free of JavaScript.
Use addEventListener instead of assigning to onclick.
Because event listener adding and removing can be tricky, consider using a variable that records whether the button has been pressed. Then your html click listener does a reset only if in that state.
So something like (code is not tested, but should get you started):
let shouldReset = false;
document.getElementById("btnId").addEventListener('click', (e) => {
shouldReset = true;
e.stopPropagation(); // so the big HTML element doesn't get it
}
document.getElementById("htmlId").addEventListener('click', () => {
if (shouldReset) {
reset();
}
}
So clicks on the html element do nothing unless the button has been first clicked. Hope that helps.
Simply create another function, and attach that once the first function has executed:
function hit() {
// you initial hit() function's code here
document.getElementById("btn1").onclick = '';
setTimeout(function(){
document.getElementById("btn1").addEventListener('click', function() {
/* define the next function */
})
}), 1);
};
or to better apply to your case :
function reset() { ... }
function hit() {
// you initial hit() function's code here
document.getElementById("btn1").onclick = '';
setTimeout(function(){
document.getElementById("btn1").addEventListener('click', reset)
}, 1);
};
This can be improved in many ways, but for the scope of your question it should do just fine.
I've created the function below to identify an onclick event which is dynamically generated with each page load. I'm able to get the onclick event into a variable (developer console output shown below). I want to execute that onclick event but can't find a good way of doing that. Any assistance is appreciated.
"ƒ onclick(event) {
mstrmojo.dom.captureDomEvent('*lK1129*kWA92AF1C396244F28902B3171F9642E57*x1*t1530820506700','click', self, event)
}"
function applyAll() {
//Get the self Link to click it
var linkBys = document.getElementsByClassName("mstrmojo-DocTextfield-valueNode");
// loop through each result
for(y = 0;y < linkBys.length;y++){
// retrieve the current result from the variable
var linkBy = linkBys[y];
// check the condition that tells me this is the one I'm looking for
if(linkBy.innerText.indexOf("link") !== -1){
// Find the right class
var idy = document.getElementsByClassName("mstrmojo-DocTextfield-valueNode")[y].onclick;
console.log(idy);
}
}
}
If the property 'onclick' is defined as a function, you can just run it as a function.
var idy = document.getElementsByClassName("")[y].onclick();
You could also handle it another way:
var idy = document.getElementsByClassName("")[y].onclick;
idy();
onclick is not an event, it's a function which gets executed when element is clicked. If you want to simulate click you can do element.click()
If you used:
element.addEventListener('click',()=>...);
instead of:
element.onclick=()=>...
then all you have to do is:
document.getElementsByClassName("mstrmojo-DocTextfield-valueNode")[y].dispatchEvent(new Event('click'));
You can call the function returned , adding parens:
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
function foo() {
var idy = document.getElementsByClassName("mstrmojo-DocTextfield-valueNode")[0].onclick;
console.log(idy);
idy();//like so
}
function alertMe() {
alert('Hello');
}
</script>
</head>
<body>
<button id="btn" class="mstrmojo-DocTextfield-valueNode" onclick="alertMe();">No click</button>
<button id="btn2" onclick="foo()">Click me</button>
</body>
</html>
I'm attempting to use html onload event to trigger javascript, but is not working. The original code was:
html:
<div id='map' onload="generateMap.createMap();"></div>
JS:
var generateMap = function(){
return{
createMap: function(){
console.log(this.attr('id'));
element = this.attr('id');
navigator.geolocation.getCurrentPosition(initialize);
}
};
}
In an attempt to test, I changed the html to:
<div id='map' onload="alert('test');"></div>
Can anyone tell me why nothing is working?
First, the onload attribute is not valid for a div tag. You most likely intended to place the onload in the body tag.
Unfortunately, that's not the only problem.
In your onLoad you are referencing generateMap as if it is an object with method createMap. However, this is not the case. You have assigned generateMap to an anonymous function.
To get your code working, generateMap needs to be an object with method createMap.
You just need to set it as an object in the first place:
var generateMap = {
createMap: function(){
console.log(this.attr('id'));
element = this.attr('id');
navigator.geolocation.getCurrentPosition(initialize);
}
};
Or if you need to retain the anonymous function for whatever reason, you can use an immediately executing function:
var generateMap = (function(){
return {
createMap: function(){
console.log(this.attr('id'));
element = this.attr('id');
navigator.geolocation.getCurrentPosition(initialize);
}
})();
There is no onload event for a div. You can use the script tag just after the div tag to emulate onload behavior.
Use this
<head>
<meta charset="utf-8">
<script type="text/javascript">
var generateMap = {
createMap: function(element) {
navigator.geolocation.getCurrentPosition(initialize);
}
};
</script>
</head>
<body>
<div id='map'></div>
<script type="text/javascript">
generateMap.createMap('map');
</script>
</body>
Assuming Chrome.. div tags do not have an onload event. Check the following two jsfiddles:
Does not work:
http://jsfiddle.net/o81e4dkr/
Works:
http://jsfiddle.net/p3osqrdn/
I do not know of a way to have an event fired when a div is loaded, unless it is being loaded in via jQuery.load(), in which case you can use the callbacks.
If you're using jQuery then I like the following function which adds onload capability to all tags:
$(document).ready (function () {
jQuery.each ($("[onload]"), function (index, item) {
$(item).prop ("onload").call (item);
return false;
});
});
So this is an answer to another question I posted and I think it is the correct solution. However, while it works wonderfully in jsfiddle it does not function whatsoever outside of that environment. I have tried multiple combinations and I cannot get this thing to work right.
I've tried onLoad in the body, Window.onload both in the header wrapping around the function and separately calling it at the base of the page after all the elements have loaded. Nothing works.
I always get this issue:
Uncaught TypeError: Cannot call method 'addEventListener' of null
Which is frustrating, because all other solutions to this error I have seen revolve around ensuring you do in fact have the specified ID the handler triggers off of in your HTML. Which I do.
I know its probably overkill to make a post here on this but I'm yanking my hair out.
Here's the JSfiddle: http://jsfiddle.net/fFW5r/1/
Here's a mockup page I made to test the concept (which never works):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
var link_container = document.getElementById('links');
function myFunction(){ link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}
</script>
</head>
<body onload="myFunction()">
<div id="links">
Inbound Link
Outbout Link
</div>
<script>window.onload=myFunction()</script>
</body>
</html>
This particular iteration I was trying to test it with the onload call at the bottom of the page after everything had loaded.
var link_container = document.getElementById('links'); need to be executed on document.onload so it has to be inside myFunction
In jsfiddle, the code is executed on load by default. in the fiddle at the left side panel > second select box if you select no wrap - in head you can recreate the problem.
Demo: Fiddle
<script type="text/javascript">
function myFunction(){
var link_container = document.getElementById('links'); // <<-- Move it inside `myFunction()`
link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}
</script>
The reason it doesn't work is that you are initializing link_container before the DOM is ready. Then when myFunction() runs, link_container has been initialized to undefined. Which causes it to fail. Initializing it in the function (after the DOM has loaded) should fix the issue
Put declare link_container inside the function.
var link_container = document.getElementById('links');
function myFunction(){
link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}
I have an <input> field in my web page, and I want to add a particular method on it, let say fooBar().
Here is what I do:
<input id="xxx" .../>
<script type="text/javascript">
$("xxx").fooBar = function() { ... };
</script>
This works well. However, for some reasons I will not detail here (in fact the HTML is generated by JSF components), the <script> will be declared before the <input> tag.
So in others words, I will have that in my HTML:
<script type="text/javascript">
$("xxx").fooBar = function() { ... };
</script>
<input id="xxx" .../>
So of course this code will not work correctly, as the script will try to get ($("xxx")) and modify an element that does not exist yet.
If I want to stick on the exact order of these two tags, what is the best way to accomplish what I want?
Edit
In my case, $ refers to prototype, but I am also using jQuery in my application. And I must be compatible with IE6 :o(
You need to run your script after the document is loaded. With jQuery you'd do that with:
$(document).ready(function () {
//do stuff here
});
I can't tell which library you're using here, but they all have an equivalent of jQuery's document ready.
Here's the prototype equivalent:
document.observe("dom:loaded", function() {
// do stuff
});
Try putting your code in load event:
$(window).load(function(){
$("#xxx").fooBar = function() { ... };
});
If the code has to be directly before the input, you can check if it has loaded after a certain period of time.
<script type="text/javascript">
//Sets up a function to execute once the input is loaded
f = function ()
{
//Checks if 'xxx' exists (may vary between frameworks)
if ($("xxx") !== undefined)
{
$("xxx").fooBar = function() { ... };
//Escapes the timer function, preventing it from running again
return true;
}
//If still not loaded check again in half a second (0.5s or 500ms)
setTimeout(f,500);
return false;
}
f();//Initialize the timer function
</script>
<input id="xxx" .../>
Instead of adding a method to the dom node, why not make it a separate function, so instead of
$("xxx").fooBar = function() {
doStuff(this);
};
you would have something like
function xxx_fooBar () {
var me = document.getElementById('xxx');
doStuff(me);
};
Another suggestion: If you can add attributes to the <input> element, you could do something like this...
<script>
function xxx_init (e) {
e.fooBar = function () {
doStuff(this);
};
}
</script>
<input onload="xxx_init(this)" id="xxx" .../>
Or you could do as others suggest and attach the scripts to the window.onload event.