How to prevent first onclick execution - javascript

I'm writing a javascript function that dynamically creates an Iframe with a button that if pressed can delete its iframe.
These are my javascript functions:
function createIframe (iframeName, width, height) {
var iframe;
if (document.createElement && (iframe = document.createElement('iframe'))) {
iframe.name = iframe.id = iframeName;
iframe.width = width;
iframe.height = height;
var connectIP = document.getElementById("ip").value;
var connectPORT = document.getElementById("port").value;
iframe.src = "http://"+connectIP+":"+connectPORT;
document.body.appendChild(iframe);
addElement(iframe.name);
}
return iframe;
}
function removeIframe(iframeName) {
iframe = document.getElementById(iframeName);
if (iframe) {
var x=iframe.parentNode.removeChild(iframe)
}
}
function addElement(iframeName) {
var butt = document.createElement('button');
var butt_text = document.createTextNode('Remove');
butt.appendChild(butt_text);
butt.onclick = removeIframe(iframeName);
document.body.appendChild(butt);
}
The problem is that, when the button is created, the onclick function is executed immediately and not only when the user presses it, so my new Iframe is immediately deleted and I cannot see it.
How can I solve this problem?
Moreover, is it possible to add the button not in the parent body but directly into the new created iframe?
Thanks in advance.

The onclick has to be a function, replace following line
butt.onclick = removeIframe(iframeName);
with
butt.onclick = function() { removeIframe(iframeName); }

You need to pass function handler instead of function call result to onclick attribute.
You can do that using anonymously function:
butt.onclick = function() { removeIframe(iframeName); };

Related

JS & jQuery script inside iframe function as if from parent html

The below code is in a script which has been loaded into the iframe #contframe source html. The button is inside the iframe.
Why does this only work when I reference the function as if it is coming from the parent HTML?
For example, the below code works:
$(document).ready(function() {
var kuf = $('#contframe').contents().find('#zbtn');
kuf.click(function() {
alert("hello");
});
});
However the below function does not work at all:
$(document).ready(function() {
$('#zbtn').click(function() {
alert("oi");
});
});
I was completely appending my scripts; I believe using the doc.createElement fixed the issue.
The following solved my issue - some slight edits from Andriy F. https://stackoverflow.com/a/13344966/10824788
//CREATES NEW JS & CSS TAGS RESPECTIVELY
function insertScript(doc, target, src, callback) {
var insertjs = doc.createElement("script");
insertjs.type = "text/javascript";
insertjs.src = src;
target.appendChild(insertjs);
}
function insertCss(doc, target, href, callback) {
var insertcss = doc.createElement("link");
insertcss.type = "text/css";
insertcss.rel = "stylesheet";
insertcss.href = href;
target.appendChild(insertcss);
}
//ADDS ABOVE TO IFRAME
$('#contframe').on('load', function(){
var context = this.contentDocument;
var frameHead = context.getElementsByTagName('head').item(0);
insertScript(context, frameHead, '/scripts/jquery.min.js');
insertScript(context, frameHead, '/scripts/content.js');
insertCss(context, frameHead, '/scripts/content.css');
});

Issue Using JavaScript's onmouseover Event Within a Class

Earlier today I got some simple code to work allowing an image to slide over on mouse over, and decided to try to turn that into a class so I could instantiate it. However, I'm running into some problems.
init() is called on window load, which sets up shifttabout() as a function to be called upon mousing over the image. However, when shifttabout() is called, I get the following error: "this.movetabout is not a function." How can this be?
<script type="text/javascript">
function SlidingTab(img)
{
this.self = this;
this.outtimer;
this.intimer;
this.left = 0;
this.interval = 20;
this.animatingout = false;
this.animatingin = false;
this.increment = 10;
this.extenddist = 100;
this.imgobj = img;
this.movetabout = function(){
alert("moveout");
this.animatingout = true;
this.left = parseInt(this.imgobj.style.left);
if(this.left != this.extenddist)
{
this.imgobj.style.left = this.left + this.increment + 'px';
this.self = this;
this.outtimer = setTimeout(this.self.movetabout, this.interval);
}
else
{
this.animatingout = false;
}
};
this.shifttabout = function(){
alert("shiftout");
if(this.animatingin)
{
this.animatingin = false;
clearTimeout(this.intimer);
}
if(!this.animatingout)
{
this.movetabout();
}
}
this.init = function(){
this.imgobj.style.position = 'relative';
this.imgobj.style.left = '0px';
this.self = this;
this.imgobj.onmouseover=this.self.shifttabout;
}
}
function init(){
var img1 = document.getElementById("tab1");
var tab1 = new SlidingTab(img1);
tab1.init();
}
window.onload = init;
</script>
Presumably I am setting up the onmouseover function incorrectly somehow, since all class variables appear to be undefined or otherwise messed up in shifttabout() when it is called by mouse hover, but not when it is called directly via init().
your problem looks to be caused by these lines. Youre on the right track, in that you need to be properly setting the context of your function.
this.self = this;
this.imgobj.onmouseover=this.self.shifttabout;
change it to the following should properly set the context
this.imgobj.onmouseover=this.shifttabout.bind(this);
#bind(this) sets the scope of this inside the function to the input you pass it (in this case its the current scope)
The this you're using in the shifttabout refers to the shifttabout this - not the SlidingTab this.
You should pass the vars needed from outside shifttabout into it to use them properly.
Hope that helps.

addEventListener won't work because of null

All I'm trying to do is have the user click the button, and when that event occurs I want an image to display within a div. I inspected the element, and it says that tableButton is undefined, but I defined it right before the addEventListener. What am I doing wrong? Sorry, I'm new to javascript.
function openTable() {
var code = "<img src='PeriodicTableOfElements.png'>";
var periodic = document.getElementById("Periodic");
periodic.innerHTML = code;
}
var tableButton = document.getElementById("openTable");
tableButton.addEventListener("click", openTable, false);
Have you made sure to wrap it in window.onload, elements can't exist if the window hasn't loaded.
window.onload = function(){
function openTable() {
var code = "<img src='PeriodicTableOfElements.png'>";
var periodic = document.getElementById("Periodic");
periodic.innerHTML = code;
}
var tableButton = document.getElementById("openTable");
tableButton.addEventListener("click", openTable, false);
}

Creating two elements using js and then having access to them later in another function

I am building some js functionality where I will be creating 2 elements on a page
var createBtn = function(
var btn = document.createElement('button')
...
)
var createIframe = function(
var iframe = document.createElement('iframe')
...
)
Pretty basic stuff, but later on I want to add an event listener to the button that will apply a style attribute to the iframe.
Something like:
var displayIframe = function(
Iframe.style['display'] = 'block'
)
button.addEventListener('click', displayIframe)
My question is how can I access the elements after I have created them without going through the annoyance of attaching classes to them and accessing them all over again that way. Is there someway of getting access to them in the create functions from the beginning.
Your codes is almost correct, but some changes is needed
var btn, iframe;
var createBtn = function () {
btn = document.createElement('button');
...
}
var createIframe = function () {
iframe = document.createElement('iframe');
...
}
Callback function
var displayIframe = function(){
iframe.style['display'] = 'block'
}
Attach click listener
btn.addEventListener('click', displayIframe);
Your mistakes:
you should declare btn and iframe as global variables to be accessible to other functions
function starts with { and ends with } not (, )
so far your codes is correct, without any error, but you won't see anything on the page because you have not attached your newly created elements to the body, For accomplish this try this function
function attachToBody(){
document.body.appendChild(btn);
document.body.appendChild(iframe);
}
In your example, I dont know why you use functions to create element, but you must have your point. Try this and let me know does this work for you.
//this is equivalent to: var btn = document.createElement('button');
var btn = (function(){
var btn = document.createElement('button');
return btn;
})();
var iframe = (function{
var iframe = document.createElement('iframe');
return iframe;
})();
document.getElementById("parentId").appendChild(btn);
document.getElementById("parentId").appendChild(iframe);
btn.addEventListener('click', function(){
iframe.style.display = "none";
});
var createBtn = function() {
var btn = document.createElement('button')
btn.setAttribute("id", "myButton");
return btn;
}
var createIframe = function() {
var iframe = document.createElement('iframe')
iframe.setAttribute("id", "myFrame");
return iframe;
}
document.body.appendChild(createBtn()); // Append button to body.
document.body.appendChild(createIframe()); // Append iFrame to body.
// Get Elements by Id.
var myButton = document.getElementById("myButton");
var myFrame = document.getElementById("myFrame");
// Add event listener.
myButton.addEventListener("click", function() {
myFrame.style.display = "none", false);
}

Updating page HTML causes endless loop

I'm writing a Firefox extension. The extension replaces certain words on the page with other words. Here's the basic code I'm using:
function startup() {
gBrowser.addEventListener("load", pageLoad, true);
}
function pageLoad(event) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
}
The problem is that this code is causing an endless loop. When I set the innerHTML property of the body, it sends another load event, which causes the endless loop.
How can I modify the page when it loads without causing the page load event to fire again?
You could use the following code to check if it has already been run before.
var loaded = false;
function pageLoad(event) {
if (!loaded) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
loaded = true;
}
}
Alternatively, if you wanted to keep the loaded variable out of global scope, you could use a closure:
var pageLoad = (function () {
var loaded = false;
return function(event) {
if (!loaded) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
loaded = true;
}
}
}();
The outer function gets executed immediately and returns the inner function which will have visibility of the loaded variable due to closure.
Would having a div or span tag immediately inside of your body tag be an option? Then you could just update the innerHTML of that element, and not the entire body...

Categories