As I am learning javascript I was testing different things. I made a small function:
foo("div", "button");
function foo(divId, buttonId)
{
var flag = 1;
var button2;
document.getElementById(buttonId).onclick = function() {
if (flag) {
button2 = createButton("Ceaning Service");
var span = createSpan("I will be removed");
var div = document.getElementById(divId);
div.appendChild(span);
document.body.insertBefore(button1, div);
flag = 0;
}
if (!flag) {
button2.onclick = function() {
div.removeChild(span);
document.body.removeChild(button1);
flag = 1;
return;
}
}
}
}
function createButton(text)
{
var button = document.createElement("BUTTON");
button.innerHTML = text;
return button;
}
function createSpan(text)
{
var span = document.createElement("SPAN");
span.innerHTML = text;
return span;
}
I can click the second button without errors only when I click the first button Click Me once. When I click Click Me button more than once and try to click the second button, it shows div is undefined. (span is undefined too, but it won't show because browser reaches div first).
Html:
<!DOCTYPE html>
<html>
<head>
<title>Testing</title>
</head>
<body>
<button id="button">Click Me</button><br>
<div id="div"></div>
<script src="test3.js"></script>
</body>
</html>
I played around with this function and when I declare span and div before ...(buttonId).onclick =... it works.
So why this code only works when I click Click Me once? I think with the second click it cannot reference to the created elements, but not sure why.
And although it removes those elements, will they be removed by the garbage collection as well or is there some kind of a memory leak happening?
And please try not to reference jQuery or some other libraries/frameworks. It would only complicate things for me for now.
Related
I am trying to make a simple Shopping List App in which user can Add, Delete and mark the task done when completed. So far, I am able to add the task but facing problem in executing the done and delete functions. I am getting an error because when I execute it, the done and delete buttons are not there but what should I do to fix it?
var inp = document.getElementById("form");
var button = document.getElementById("click");
//Create List Function with Done and Delete Buttons
function addVal() {
var ul = document.getElementById("list");
var li = document.createElement("li");
var span = document.createElement("span");
var done = document.createElement("button");
var del = document.createElement("button");
li.appendChild(document.createTextNode(""));
span.appendChild(document.createTextNode(inp.value));
done.appendChild(document.createTextNode("Done"));
del.appendChild(document.createTextNode("Delete"));
li.appendChild(span);
li.appendChild(done);
li.appendChild(del);
done.setAttribute("class", "doneBut");
del.setAttribute("class", "delBut");
ul.appendChild(li);
inp.value = "";
}
//Get Input Length
function checkLength() {
return inp.value.length;
}
//Run function on Button Click
function onButtonClick() {
if (checkLength() > 0) {
addVal();
}
}
//Run function on Enter Keypress
function onEnter(event) {
if (checkLength() > 0 && event.which === 13) {
addVal();
}
}
//Trigger Events
button.addEventListener("click", onButtonClick);
inp.addEventListener("keypress", onEnter);
//Done and Delete Button Functions
var doneButton = document.getElementsByClassName("doneBut");
var deleteButton = document.getElementsByClassName("delBut");
function doneTask() {
doneButton.parentNode.classList.add("done");
}
function delTask() {
deleteButton.parentNode.classList.add("delete");
}
doneButton.addEventListener("click", doneTask);
deleteButton.addEventListener("click", delTask);
<input type="text" placeholder="Enter Your Task..." id="form" />
<button id="click">Add Task</button>
<h2>List:</h2>
<ul id="list"></ul>
Please Help.
Your problem is that the code tries to add events before the buttons exist. The buttons don’t exist until the addVal function gets called. Since addVal is not being called before the you try to add your event handlers, the getElementById returns null, and you attempt to add an event listener to null.
Additionally it looks like you’re planning to add multiple done and delete buttons. That wouldn’t normally be a problem, except you’re referencing them by ID, and IDs MUST be unique. You’ll need to switch this to a class or an attribute, since you’ll need one per item in the shopping cart.
You’ll probably want to look into event delegation, so that you can add your events once to the page before any buttons exist. https://javascript.info/event-delegation
It's most likely because your script is running before your code is running. Add the <script> tags just before the closing </body> tag to fix it:
<script>/* Your code here */</script>
</body>
You need to place this in a window.onload function, or run it in a function inside of the body tag's onload. Those elements don't exist yet when the script is run:
window.onload = function() {
var inp = document.getElementById("form");
var button = document.getElementById("click");
button.addEventListener("click", onButtonClick);
inp.addEventListener("keypress", onEnter);
}
I am trying to program a click function that if a certain condition is true, each time the button is clicked it will overwrite the current string and replace it with a new string character.
I created a simple example below to illustrate what I am trying to accomplish.
$(document).ready(function() {
const hello = document.getElementById("hi");
const button =
document.getElementById("replace");
let clicked = false;
let goodBye = function() {
clicked = true;
if (hello.innerHTML.length < 9) {
if (clicked) {
// I want to clear the current HTML first, then I went the new HTML to add a single 9 every time the button is clicked.
hello.innerHTML += "9";
}
}
}
button.addEventListener("click", goodBye);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id="hi">01234567</h1>
<button id="replace">click me</button>
While I'm sure this is very simple I'm still relatively new to working with JS and I've been stuck trying to figure this out for over a week now. Any help is appreciated.
I removed your jQuery as it's not needed. I believe this is what you are looking for.
Steps:
Obtain a reference to your elements (hello and button)
Bind an event listener to your button click
When button is clicked, get the current value of your hello element
Run logic (if statement) and do what you need.
https://jsfiddle.net/3ho2by8t/14/
(() => {
const hello = document.getElementById("hi");
const button = document.getElementById("replace");
button.addEventListener('click', (evt) => {
const helloText = hello.innerHTML;
if (helloText.length > 9) {
hello.innerHTML = '9';
} else {
hello.innerHTML += helloText.length;
}
});
})();
<h1 id="hi">01234567</h1>
<button id="replace">click me</button>
I have been trying to find a way to inject a button when a textarea in the window document got clicked(onfocus) ...for weeks, but I failed to do so.
The function is similar as how Grammarly's extension does.
Grammarly's extension
The thing is, I want to add a button nearby or in the textarea when it is onfocus or keypressed. Then I could return the text value to the extension. What is the right way to detect the div in the content script?
the button code is like this:
function appendBtn (){
var btn = document.createElement("INPUT");
btn.setAttribute("type", "button");
btn.setAttribute("value", "button");
document.body.appendChild(btn);
}
document.onclick = function() {
appendBtn();
}
what I want is to find the right div instead of appending the element after body...which it always show at the bottom of the page, especially on facebook page, which I can't even target the input boxes of the comment area..
Please help me with this! I am so desperate right now...
Use the focusin event (it bubbles unlike the focus event) in a content script of your extension:
var btn = createButton();
document.addEventListener('focusin', onFocusIn);
function onFocusIn(event) {
var el = event.target;
if (el.contentEditable ||
el.matches('input, textarea') && el.type.match(/email|number|search|text|url/))
{
appendButton(el);
}
}
function createButton() {
var btn = document.createElement('button');
btn.textContent = 'Yay!';
btn.onclick = function(event) {
btn.textContent += '!';
};
return btn;
}
function appendButton(textElement) {
textElement.parentElement.insertBefore(btn, textElement.nextElementSibling);
}
I do not have a <input> or any form. I want some way to toggle a plain text to something like **** on click of a button.
for example I have
<p id='one'>google_yahoo</p>
<button id='two'>toggle</button>
so when I click the button once, <p> should become:
<p>************</p>
Then when I click the button then I should again get back google_yahoo
But by default I want it be in ***** form.
What I did:
<script>
function myfunction(){
$("#two").click(function(){
$("#one").text("abc");
});
};
</script>
Any straightforward, easy to understand solution anyone?
You need to create some variables to store value of your text. Try it on JSFiddle.
var txt = document.getElementById('one');
var btn = document.getElementById('two');
var visible = 1;
var value = '';
btn.addEventListener('click', function(){
if(visible){
value = txt.innerHTML;
txt.innerHTML = '*'.repeat(value.length);
}else{
txt.innerHTML = value;
}
visible = !visible;
});
var pMemory = null;
$('button').click(function() {
var pElement = $('p').get(0);
if (pMemory === null) {
// save to cache
pMemory = $(pElement).text();
}
if (pMemory === $(pElement).text()) {
$(pElement).text('*'.repeat(pMemory.length));
} else {
$(pElement).text(pMemory);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>google_yahoo</p>
<button>toggle</button>
Using text-security css property as an option.
$(document).ready(function(){
$("#two").on("click", function(){
$("#one").toggleClass("password_field");
})
})
.password_field{
-webkit-text-security:disc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id='one' class="password_field">google_yahoo</p>
<button id='two'>Toggle</button>
I want to be able to click anywhere inside the body except that one specific element. I can't find out what's wrong with the code I have done.
When I click on the one specific element .except inside body, I don't want it to hide but when I click on body it should hide.
HTML
<html>
<head>
<title>Click anywhere except that specific element</title>
</head>
<body id="wrapper">
<center>
<div id="except"></div>
</center>
</body>
</html>
JS
var body = document.getElementById('wrapper');
var except = document.getElementById('except');
if(body.addEventListener)
body.addEventListener("click", function(){bodyClick("yes")}, false);
else
body.attachEvent("onclick", bodyClick);
function bodyClick(clicked){
except.addEventListener("click", exceptClick,false);
function exceptClick(){
bodyClick("no");
if(clicked === "yes")
except.style.display = "none";
}
if(clicked === "yes")
except.style.display = "none";
else
except.style.display = "show";
}
Any help is appreciated. Forgive me for the incorrect formatting (it's my first post here). Thank You!
You need to stopPropagation to the outer element.
Here's a simple illustration: http://jsfiddle.net/5mhqrhwk/3/
var body = document.getElementById('wrapper');
var except = document.getElementById('except');
body.addEventListener("click", function () {
alert("wrapper");
}, false);
except.addEventListener("click", function (ev) {
alert("except");
ev.stopPropagation(); //this is important! If removed, you'll get both alerts
}, false);
HTML:
<div id="wrapper">
<center>
<div id="except"></div>
</center>
</div>
You don't really need any flags to do this. Just listen on body click and do different thing depending on the item clicked (event.target). This code should do exactly what you wanted (based on your code):
var body = document.getElementById('wrapper');
var except = document.getElementById('except');
if(body.addEventListener)
body.addEventListener("click", bodyClick, false);
else
body.attachEvent("onclick", bodyClick);
function bodyClick(event){
if(event.target != except)
except.style.display = "none";
}
Instead of stopping propagation on the except element, I'd prefer something like this:
var wrapper = document.querySelector('wrapper');
document.addEventListener('click', function(e) {
if ( !wrapper.contains(e.target) ) {
// Do something when user clicked outside of wrapper element
}
})
You are missing one piece to this. You need to stop the event from bubbling up from the except object if it is clicked
except.addEventListener("click", function(event){event.stopPropagation()}, false);