Curious about hide().after("") in jQuery - javascript

I have some code at here:
html:
<body>
<p>This is a paragraph.</p>
<button>click me</button>
</body>
Javascript:
$(document).ready(function(){
$("button").click(function(){
$("p").hide().after('<p>hello world</p>');
});
});
Actually, I've using JQuery 2.0.2 also.
In my understanding, When I click the button click me, "<p>This is paragraph<p>" will be replaced by <p>hello world</p>.
The first click is successful. However, many hello world with the growth rate of progression show after the first hello world shown. For example:
I've checked the source code by firebug, and find it is:
<p style="display: none;">This is a paragraph.</p>
<p>hello world</p>
<p style="display: none;">hello world</p>
<p>hello world</p>
<button>click me</button>
Why the first <p>hello world</p> wasn't be replaced by the new one?
Doesn't it suppose to show one p tag only?

That's cause you're creating paragraphs
<p>hello world</p>
and on every click the $('p') is a collection of all p elements on your page.
The more paragraphs you have... more appends. live demo - issue example
An element, even if set to display:none using .hide(), is still present in your document..
What you're up to is probably one of the following:
$("button").click(function(){
$("p").html('hello world');
});
$("button").click(function(){
$("p").text('hello world');
});
$("button").click(function(){
$("p").replaceWith('<p>hello world</p>');
});
$("button").click(function(){
$("p").after('<p>Hello world</p>').remove();
});

If only you want to change the text you an do like this
$(document).ready(function(){
$("button").click(function(){
$("p").html('hello world');
});
});
JS FIDDLE

after('<element/>') means generate an element and insert it after the selected element(s), you are generating and inserting an element after all the selected p element(s), on the first click you are adding 1 element, on the second click 2 elements and so on, because after each click there are more than one p elements. after doesn't replace anything.

Well, there is nothing surprising that is happening here. Actaully that is what should happen, since you are adding <p> tag after hiding the first <p> <p>This is paragraph<p>.
So your first click ends up having two <p> tag in the DOM and further clicks, adding more <p> tags. hide() does not removes the elements form the DOM; it just changes its display property. You can use replaceWith() or remove() to remove the first <p>, if you want this to work, as you needed.
$("p").after('<p>hello world</p>').remove(); //remove the selected `<p>` tag after `<p>is appended.</p>`
or
$("p").replaceWith('<p>hello world</p>');

It happens because you adding new p element after each p tag in document (even after hidden).

Related

Detect a word and addClass to body

The jQuery below detects the word first and third in any <p> text and adds a yellow or red background to it.
$(document).ready(function(){
$("p:contains(first)").css("background-color", "yellow");
$("p:contains(third)").css("background-color", "red");
});
<p>I'm the first sentence.</p>
<p>I'm the second sentence.</p>
<p>I'm the third sentence.</p>
<p>I'm the fourth sentence.</p>
JSFiddle: https://jsfiddle.net/3p0nmw4f/1/
However, instead of highlighting the text, I want to addClass to the body of the html document like this :
<body class="first">
or
<body class="third">
I know we can achieve this using $(document.body).addClass('first'); but I'm unable to put it together.
Please help.
You could search for the closest body HTML element.
You can do this by doing the following:
$(document).ready(function(){
$("p:contains(first)").closest('body').addClass('first');
$("p:contains(third)").closest('body').addClass('third');
});
Another possibility would be to simply search for the body element as follows:
$(document).ready(function(){
if ($("p:contains(first)"))
$("body").addClass("first")
if ($("p:contains(third)"))
$("body").addClass("third")
});
Source: https://jsfiddle.net/fk05dabw/

How to have a paragraph that is hidden unless you click on it in HTML(or XHTML)

I am writing pages using python in Confluence that is using XHTML, and I want to have a new page contains a paragraph that is hidden or say truncated when people come to that page but it can be seen if people click on it.
please check the two pictures I attached in order to better illustrate what I want
You can use jquery to achieve this. Assuming you are using an icon to illustrate those 3 dots.
<html>
<style>#hidden_para{display:none;} /* Hide the paragraph*/</style>
<p>This is a non hidden paragraph</p>
<img id="icon" src="3dottedicon.png">
<!-- Add an id attib to the paragraph -->
<p id="hidden_para">This is a hidden paragraph</p>
</html>
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<script type="text/javascript">
$("#icon").click(function(){
$(this).hide(); //this keyword refers to the icon itself.
//Access the element with the ID hidden_para and override the CSS.
$("#hidden_para").show();
});
</script>
When the above code is executed it first hides the icon and then adds a style attribute to the element with the ID hidden_para as style="display:block;"(this overrides the CSS specified)
Hope this helps!

Contenteditable elements change ID after modifications

I have some problems with a contenteditable div annoying behaviour. I have a few elements inside, let's say the code looks like that:
<div contenteditable="true">
<p id="element-id-1">element-id-1</p>
<p id="element-id-2">element-id-2</p>
</div>
All works as intended except for one thing - when I triple click the first paragraph to select and remove it (with delete or backspace) the second paragraph content 'jumps' into its place, but retains the first paragraph ID. Is there a way to prevent this, so after I triple click the first paragraph and remove it, the second paragraph remains with the same ID (#element-id-2)? JSFiddle with described functionality here: https://jsfiddle.net/t8e28bmx/ Thanks!
Try this code.
<div contenteditable="plaintext-only">
<p id="element-id-1">element-id-1</p>
<p id="element-id-2">element-id-2</p>
</div>
Reference: https://w3c.github.io/editing/contentEditable.html#h-contenteditable
<div>
<p contenteditable="true" id="element-id-1">element-id-1</p>
<p contenteditable="true" id="element-id-2">element-id-2</p>
</div>

How to toggle specific divs with jquery

Okay so I have a very limited amount of knowledge with this and I can not find my answer anywhere. What I am trying to do is create multiple buttons that toggle information. So when the first toggle is clicked div 1 is toggled, when i click the second toggle div two opens and preferably div 1 closes. My code is very basic I am very new to this. Right now no matter what values I input into the toggle area both divs close. Thank you and I hope this makes sense.
Here is my code:
<script>
$(document).ready(function(){
$("button").click(function(){
$("div.house").toggle();
});
});
</script>
<button>Toggle</button>
<div class="house">
<p>SAMPLE TEXT ETC...</p>
</div>
<button>Toggle</button>
<div class="tumble-by">
<p>SAMPLE TEXT ETC...</p>
</div>
You can select the next sibling:
$("button").click(function(){
$(this).next().toggle();
});
In the above code, JavaScript this keyword refers to the clicked element. $(this) creates a jQuery collection and .next() method selects the very next sibling of the collection's element.
I agree too, that first you need to hide all divs:
$("button").click(function () {
$('div').hide();
$(this).next().toggle();
});
<script>
$(document).ready(function () {
$(document).on("click", ".js-toggle__button", function (e) {
$(".js-toggle__text").hide();
$(this).next(".js-toggle__text").show();
});
});
</script>
<button class="toggle__button js-toggle__button">Toggle</button>
<div class="toggle__text js-toggle__text">
<p>SAMPLE TEXT 1 ETC...</p>
</div>
<button class="toggle__button js-toggle__button">Toggle</button>
<div class="toggle__text js-toggle__text">
<p>SAMPLE TEXT 2 ETC...</p>
</div>
It's better to use uniquely defined identifiers when you accessing elements from JS (and don't use them for CSS — use separate names).
Your HTML code some day can be changed dramatically and JS will work anyway because it depends on identifiers but not on structure or on tag names.

onclick alert jquery html javascript

I have a page so far with:
<div id="x1">Text paragraph 1<link here></div>
<div id="x2">Text paragraph 2<link here></div>
<div id="x3">Text paragraph 3<link here></div>
Where link here is like
google
What I am trying to do is add a link to the bottom of each paragraph of text so that when it is clicked it displays an alert with the div id of that text block.
So for example, if someone clicks on the link at the bottom of text paragraph 2, then they will get an alert saying "x2".
So far, I have only been able to think of a way involving an onclick event for each link in each div. But with 100 paragraphs this could become quite a lot and is messy code.
like
$('#x1').onclick(function(){
alert('x1');
});
How can I do this better?
The page is generated with php so I could put the div id's anywhere in that text block area (even make a new div around the link if required)...
EDIT - Many good answers, I don't know which to pick as best. I actually ended up using Loongawas for my purpose as its easy to make for my beginner level in php.
<div id='a1'>This text <a href="" onclick=tomato(1)>test</a>
</div>
<div id='a2'>This text <a href="" onclick=tomato(2)>test</a>
</div>
<div id='a3'>This text <a href="" onclick=tomato(3)>test</a>
</div>
and
function tomato(test){
alert(test);
};
Some of the others are incredibly interesting as they use higher functions. I'm going to spend the rest of the day looking into them. Thanks to all.
use jQuery's live or delegate functions:
$('div a').live('click', function(ev){
alert($(this).closest('div').attr('id'));
});
The benefit to the live/delegate functions is that there's actually only a single event on the entire page for this (as opposed to one event per link). If you add more links dynamically, this still works without having to attach more events.
The difference between live and delegate is that delegate is specific to a part of the page. If, for instance, you wrapped all of these DIVs in another div, the call would look like:
$('#wrapperDiv').delegate('a', 'click', function(ev){ ...
The advantage to this is that the internal jQuery code that checks to see if the click matches the selector only runs on clicks inside of #wrapperDiv instead of clicks anywhere on the page.
You could make a javascript function that takes a variable and then pass the paragraph number to the function. If the paragraph was number two you could call
myfunction(2);
or is the number not the problem?
$('#x1, #x2, #x3').click(function(){
alert($(this).parents().attr("id"));
});
EDIT:
Better version:
HTML:
<div class="x">Text paragraph 1<link here></div>
<div class="x">Text paragraph 2<link here></div>
<div class="x">Text paragraph 3<link here></div>
$('.x a').click(function(){
alert($(this).parents().attr("id"));
});
Have you considered using a class to name them all as opposed to explicit ids?
<div class="x">Text paragraph 1<link here></div>
<div class="x">Text paragraph 2<link here></div>
<div class="x">Text paragraph 3<link here></div>
so then you would be able to use a single click event for all of them?
$(".x a").click()
{
//Use $(this) to refer to the clicked item.
alert($(this).parents().attr("id"));
});
$('.myDivs').click(function(){
alert($(this).parent().attr("id"));
});
Or select the divs in some other way:
$('#x1').parent().children('div').click(...);
Something along these lines should work:
<div id="x1">Text paragraph 1 <a href='google.com'>google.com</a></div>
<div id="x2">Text paragraph 2 <a href='google.com'>google.com</a></div>
<div id="x3">Text paragraph 3 <a href='google.com'>google.com</a></div>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js'></script>
<script>
$('a').click(function() {
alert($(this).parent().attr('id'))
return false
})
</script>
Add a class to each div, so you can select all of 'em at once.
<div id="x1" class="x">Text paragraph 1 <a>Click</a></div>
<div id="x2" class="x">Text paragraph 2 <a>Click</a></div>
<div id="x3" class="x">Text paragraph 3 <a>Click</a></div>
Then you can do:
$('div.x a').live('click', function(e){
e.preventDefault();
alert($(this).closest('div.x').attr('id'));
});
http://jsfiddle.net/VGh3X/1/
A better approach to this is to make all of the clickable areas share something in common that you can use as a selector. For example, if all of the clickable divs had class='click', you'd be able to select them all using $('.click') and bind to that.
$('.click a').bind('click', function() {
var div = this.closest('.click');
alert(div.attr('id'));
return false;
});
$(document).ready(function() {
var links = $("div[id^='x'] a"); //get the a tags
$.each(links, function(i,v) {
$(v).click(function() { //bind on click
alert(v.parentNode.id); //alert div id
return false; // stop
});
});
});

Categories