I got a really bothering problem which I can not understand.
I have a div which contains 2 paragraphs, and a clickable button to delete the first p element, but the strange thing is that the button deletes it self and the p element continues to live!
This is the result of my code:
But when I click on the button I get this:
Below is my code:
<div>
<p id="id_1">The first paragraph.</p>
<p id="id_2">The second one.</p>
</div><br>
<button onclick="remove(document.getElementById('id_1'));">click me!</button>
<script>
function remove(elem)
{
var parent=elem.parentNode;
parent.removeChild(elem);
}
</script>
The function name "remove" is being hidden by the native "remove" method on the button element itself. If you change the name, it works as expected.
Event handlers established with HTML "onfoo" attributes execute in a specially-constructed scope that includes the methods (and other properties) on the DOM node for the element. That's just one of many reasons that it's preferable to use JavaScript to attach event handlers via addEventListener().
All you need to do is to rename your function and avoid using remove as its name(The reason for this is included in #Pointy's answer). Try this:
<div>
<p id="id_1">The first paragraph.</p>
<p id="id_2">The second one.</p>
</div><br>
<button onclick="removeElement(document.getElementById('id_1'));">click me! </button>
<script>
function removeElement(elem)
{
var parent=elem.parentNode;
parent.removeChild(elem);
}
</script>
Related
I am working on an app with vue.js and quill.js in which I am creating some documents.
The content of a document is stored in document.content which is one giant string with a bunch of html tags in it coming straight from quill.js.
When previewing the document I'm rendering the big html string inside a div with v-html attribute like this:
<div v-html="document.content"></div>
i.e.
document.content = "<p>Hello</p><p>World</p><p>Hello World</p><p>Hello</p>"
It's rendereded as (you get the idea):
<div data-v-4ee08204>
<p>Hello</p>
<p>World</p>
<p>Hello World</p>
<p>Hello</p>
</div>
The question is:
When clicking somewhere inside the div is there a way to get the exact index of the character/word/element I've clicked on (because I need to add a comment to it)?
I've tried to attach a click listener to the div, getting the outerHTML of the target element and trying to get the indexOf document.content, but it's not always working, because there can be similar stuff inside the big string like <p>Hello</p> twice and it will get the first one only.
It's possible that my whole approach is wrong, but I'm not really sure.
Any suggestion is welcome. Thanks!
What you could do is to clone the parent element, add the comment using DOM manipulation and then use the parent element's innerHTML, here is an example:
const parent = document.querySelector('#parent');
parent.addEventListener('click', event => {
event.target.classList.add('toBeModified');
const clone = parent.cloneNode(true);
const node = clone.querySelector('.toBeModified');
const comment = document.createElement('span');
comment.textContent = '(edited)';
node.appendChild(comment);
node.classList.remove('toBeModified');
event.target.classList.remove('toBeModified');
console.log(clone.innerHTML);
});
<div id="parent">
<p>Hello</p>
<p>World</p>
<p>Hello World</p>
<p>Hello</p>
</div>
What this does is to add a class (toBeModified) to the clicked element so it can be easily found once the parent is cloned.
Let's say I have a div with a button inside:
<div>
<button id='delete_btn'>delete</button>
</div>
What would be the jQuery code to delete that div and ONLY that div
As I have another button that dynamically adds copies of that sample code above.
So I could have something like this, but I only want the div that contains the button pressed, to be deleted.
<div>
<button id='delete_btn'>delete</button>
</div>
<div>
<button id='delete_btn'>delete</button>
</div>
thanks!
id should not be duplicate in a document. Use class instead. Inside the click handler function, you can target the parent of this element to remove:
$(document).on('click', '.delete_btn', function(){
$(this).parent().remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button class='delete_btn'>delete</button>
</div>
<div>
<button class='delete_btn'>delete</button>
</div>
This can easily be performed with Vanilla JS and the newer remove() method. If IE-support is not a necessity, consider the following; or, if IE-support is needed, it wouldn't take much to amend the following:
document.addEventListener('click', function (e) {
if (e.target.matches('.delete_btn'))
e.target.parentNode.remove()
}, false);
<div>
<button class='delete_btn'>delete 1</button>
</div>
<div>
<button class='delete_btn'>delete 2</button>
</div>
event / state
This binds an event to the document (ancestor of the button). The benefit from this is that the click handler will be called for any new delete buttons that are dynamically created after the page has loaded (and will still function).
class vs id
This also uses class in place of id. This is because id should be reserved for unique values and class is intended to be a handle to like-elements. JavaScript can produce unexpected behavior if multiple elements are named with the same ID.
remove()
Using remove() an element can be removed from the DOM as expected. An older method would be to call the removeChild() on the parent (e.g., parent=e.target.parentNode; parent.parentNode.removeChild(parent))
more ES6
Of course, you could simplify the code using a named-argument/destructuring-assignment, which essentially assigns event.target to a variables named btn and The code can further be reduced, using a common arrow function. See below.
document.addEventListener('click', ({target: btn})=>{
btn.matches('.delete_btn') && btn.parentNode.remove()
}, false);
<div><button class='delete_btn'>delete 1</button></div>
<div><button class='delete_btn'>delete 2</button></div>
{target: btn} plucks the event argument being passed into the function and takes the value of the target property and assigns it to a new variable called btn. If you just had {target} (without the assignment), in the function body you would replace btn with target (e.g., target.matches(…), target.parentNode)
For my program, i have a button that append's newly created div to the page and sequentially names these new divs in the sequence of MydivIDis1, MydivIDis2, MydivIDis3 and so on. Each of these newly created divs will have a 'delete' button. The delete button will delete the div that it is currently in. However, i do not know how to do this.
In the code below, i have tried to use javascript to create a "remove element" button within each div. The button is tied to an onclick function called remove. I have also specified in the button.onclick to take in the argument newDiv.id. This code is not working however.
<!DOCTYPE html>
<html>
<body>
<div id="MainContainer">
<input type="button" value="Add Element" id="add" onClick="add();">
<div id="InnerContainer">
</div>
</div>
<script>
var mainDiv=document.getElementById("MainContainer");
var innerDiv=document.getElementById("InnerContainer");
var clicks=0
var add=function(){
clicks += 1;
var newDiv=document.createElement("div");
newDiv.id="MydivIDis"+clicks;
newDiv.innerHTML=newDiv.id
mainDiv.appendChild(newDiv); //creates the new Div, with the id MydivIDis1, MydivIDis2, MydivIDis3
var button=document.createElement("button");
var t=document.createTextNode("Remove Element");
button.onclick=function(){
remove(newDiv.id); //Here i am trying to specify to the program to take newDiv.id as the input to the remove function.
};
button.appendChild(t); //creates new button and appends to each new Div
var remove=function(input){
mainDiv.removeChild(input);
}
mainDiv.appendChild(button);
};
</script>
</body>
</html>
removeChild takes a node as an argument instead of an element ID.
So the solution is to just give newDiv to the remove function.
button.onclick=function(){
remove(newDiv);
};
Your remove statement is wrong, remove element like this
mainDiv.removeChild(document.getElementById(input));
Also, as per your current design even after removing the div the remove button will still be there, if you want to remove that button also you have to replace this line
mainDiv.appendChild(button);
With this
newDiv.appendChild(button);
Why don't you just use jQuery?
It's an awesome library.
Just give an ID to the div tag you want to alter and remove it. I'll give you an example on using it.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
$("button").click(function(){
$("#div1").remove();
}
I have the following:
<div class="tab-pane" id="message">
<textarea rows="4" cols="50" id="send_message" placeholder="Enter text ..."> </textarea>
OK
Cancel
I want to bind the click method to the 'div' element , and when one of the child 'a' elements is clicked do separate things. I am trying to distinguish between them using the button text, but the following is not working:
$(function(){
$('#message').click(function(){
if($(this + ">a").is(":contains(OK)")) {
console.log("OK!!");
How can I fix this?
Okay there are two ways of doing this:
.find(selector)
if(this).find("a").is(":contains(OK)")) {
console.log("OK!!");
OR
$(selector,context)
if("a",this).is(":contains(OK)")) {
console.log("OK!!");
In javascript, this is essentially the context of the current function. In jQuery event callbacks, this is set to be the source element of the event - not the selector string, which is what you are treating it as.
Instead, you want to do a test like: if($("a", this).is(":contains(OK)")) {
This works because the second parameter to the jQuery selector is the context to search in, so you are only searching for the a tags under the source element of the click.
Binding the click element to the Div, then checking the text string of the A tags will make both events happen on every click. You want to bind 2 separate click events on each A tag. Add an ID to each A tag, then try this code
$('#okLinkID').click(function(){
console.log("OK!!");
});
$('#cancelLinkID').click(function(){
console.log("Cancel!!");
});
//Attaches only one listener to the #message div and listens for any 'a' element within it to be clicked.
$('a','#message').on('click',function(){
var $this = $(this),
btnText = $this.text();
console.log(btnText);
});
http://jsfiddle.net/YA7Ds/
Need to use one single button to toggle the show and hide for div
my code looks something like this
function showTable(number){
$('#div_'+number).show('slow');
$('#button_'+number).html("Hide Table").click(function(){
hideTable(number);
return false;
});
}
function hideTable(number){
$('#div_'+number).hide('slow');
$('#button_'+number).html("Show Table").click(function(){
showTable(number);
return false;
});
}
<div id="div_1" style="display:none"></div>
<button id="button_1" onClick="javascript:showTable(1)">Show Table</button>
<div id="div_2" style="display:none"></div>
<button id="button_2" onClick="javascript:showTable(2)">Show Table</button>
<div id="div_1" style="display:none"></div>
<button id="button_3" onClick="javascript:showTable(3)">Show Table</button>
The function is working fine at first. But after i show and hide it once, whenever I tried to show it again, it starts chaining show/hide/show/hide by itself without any clicks. And the more I do it, the longer it does the chaining. It seems it's just a loop that everytime it doubles the amount of looping(like show/hide for 2/4/8/16/32 times ....) the more I do the longer it loops. Anyone have a clue what's going on?
I tried to remove the click part in the hideTable function, the loop stops but still whenever I try to hit showTable, it will show then hide it self automatically like it's auto executing the stuff in the click function without any clicks...
Also is there anyway to use the jquery tagging style to call the function instead of using onclick? i know I can do like
$("#button_1").click(function(){......................});
$("#button_2").click(function(){......................});
$("#button_3").click(function(){......................});
but is there anyway I can group all of them together into a single function and still able to tell which button is clicked? Because I need a way to track which div to show and hide, and change the the text in corresponding button. Thank you very much in advance. m(_ _)m
You're piling on more and more redundant event handlers with each "click". That's what those calls to ".click()" in the handlers do — add another event handler.
You only need to add an event handler once. And adding an event handler does not remove the prior handler. Since you're using jQuery, use it to add the handlers, not old-fashioned "onclick" attributes.
Give all those <div> elements a class value, like "toggled".
<div id="div_1" style="display:none" class='toggled'>
You can do the same with the buttons. Then you can set up event handlers by using the class to refer to them in a jQuery selector.
A better way to do this is with toggle. Refer to JQuery toggle showhide
you should gove all your divs the same class eg class="toggleable" on the ones you want to toggle.
Then try:
jQuery(".toggleable input[type='button']").click(function()
{
jQuery(this).closest("div.toggleable").toggle();
});
This will put an onlick on your buttons inside your div which will find the closest parent div with class toggleable and will either hide/show your div.
To read about toggle():
http://api.jquery.com/toggle/
to read about selectors:
http://api.jquery.com/category/selectors/
I agree with Pointy but since I can't seem to add onto the answer, I must make another.
$('[data-show-table]').click(function() {
var $this_button = $(this);
$('#div_' + $(this).attr('data-show-table')).toggle(function() {
var msg = $(this).css('display') == 'none' ? 'Show table' : 'Hide table';
$this_button.html(msg);
});
});
<div id="div_1" style="display:none">Table 1</div>
<button id="button_1" data-show-table="1">Show Table</button>
<div id="div_2" style="display:none">Table 2</div>
<button id="button_2" data-show-table="2">Show Table</button>
<div id="div_3" style="display:none">Table 3</div>
<button id="button_3" data-show-table="3">Show Table</button>