For example I have the following HTML named index.html:
<html>
<head>
<style>
#content { float:left; }
#sub { float:right; }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="action.js"></script>
</head>
<body>
<h2>Test de</h2>
<div id="content">
Content
<button class="loadSub">Load</button>
</div>
<div id="sub">
Sub content
</div>
</body>
</html>
And a simple JS file named action.js:
$(document).ready(function(){
$('button.loadSub').click(function(){
$('#sub').load('test.html');
});
$('button.hide').click(function(){
$('#sub').fadeOut('slow');
});
});
As you can see, when I click the button .loadSub the div #sub will be loaded with the new content from test.html:
<h2>This is the sub content</h2>
<button class="hide">Hide</button>
I got two problems here:
Firstly, the .loadSub button did successfully load the the div of id subcontent, but the .hide button did not work.
Secondly, after I had tried inserting
script type="text/javascript" src="action.js"
inside test.html, the hide button worked and faded out its content. But then in turn, I found out that the button loadSub no longer functioned. I couldn't load the subcontent again.
Is there any other way around to just once declare source of js file and make my button.loadSub work whenever I click it? Could anybody please explain the problem and give me a hint to fix it.
You're loading dynamic HTML into your page. This means that at the time you called $('button.hide').click(), the button.hide element did not exist in your page yet, so the click handler could not be attached.
You might want to try doing a delegate attachment instead.
$('#sub').on('click', 'button.hide', function () {
$('#sub').fadeOut('slow');
});
On the first page, put this. You can insert my JQQuery code into your action.js file. On the second page, the one you are loading into your div, put the second Jquery code I added.
On First page:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<style>
#content{float:left;}
#sub{float:right;}
</style>
<script type="text/javascript">
$(document).ready(function(){
$(function(){
$('.loadSub').click(function(){
$('#sub').show();
$('#sub').load('test.html');
});
});
});
</script>
</head>
<body>
<h2>Test de</h2>
<div id="content">
Content
<button class="loadSub">Load</button>
</div>
<div id="sub">Sub content</div>
</body>
</html>
On the second page (the page that's loaded into the div, add this:
<script type="text/javascript">
$(document).ready(function(){
$(function(){
$('.hide').unbind("click").click(function(){
$('#sub').fadeOut('slow');
});
});
});
</script>
<h2>This is the sub content</h2>
<button class="hide">Hide</button>
The hide button isn't on the page when you try to bind the event so it is never registered.
Change it to use on like this (assuming version 1.7+)
$(document).on('click', 'button.hide', function(){
$('#sub').fadeOut('slow');
});
or delegate if an older version:
$(document).delegate('button.hide', 'click', function(){
$('#sub').fadeOut('slow');
});
This attaches the event handler at the document level so will work for any new content added to the page.
Related
I have a main page that I have loaded another page on it via ajax when document is ready ,also I have a button that when I click It I shows an alert and, I have that button in the second page too. but when i click on it in that page that code does not work ?
how can i solve this problem ?
because I do not want to repeat js codes on the second page ?
here is my first page code :
first page code:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="captcha" style="border:1px solid red;">
</div>
<div class="details1">cccc</div>
<script>
$(document).ready(function(e) {
$(".captcha").load("/secondpage.htm");
$(".details1").click( function()
{
alert('button clicked');
}
);
});
</script>
</body>
</html>
and this is my second page that I have loaded into div with classname captcha:
second page code:
<html>
<head>
</head>
<body>
<section class="details1"> Details </section>
</body>
</html>
When you need to create new elements on-the-fly, you can not use standard click etc. events. Dynamically created elements are not born with the same event handlers as the existing elements. You have to dynamically attach event handlers to newly created elements.
Replace 'click' with 'on'.
$("body").on("click", ".details1", function(){
alert('button clicked');
});
This is the first time I'll try to move all the script from html file to an external Javascript file because I think it will be more organized to separate display from script codes.
So originally I have
html
<body>
<a href="#menu-toggle" class="btn btn-default" id="menu-toggle" >Menu</a>
<script>
$("#menu-toggle").click(function (e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
</script>
</body>
Which I tried to translate or move to an external file.
html
<body>
Menu
<script src="myjsfolder/externalJavascript.js"></script>
</body>
externalJavascript
function showHideMenu(){
$("#menu-toggle").click(function (e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
}
I know this may look like a silly question but I just can't get it correctly. But I know I need to move the script outside. Everything works correctly when inside the html file.
Thanks.
You need to
Not add the onclick=... to your HTML
Wrap your Javascript in the other file in `$(document).ready(function(){//your code here//});
Edit
as nnnnn pointed out, since you are including the file inside the <body> tag instead of the <head> tag (where I normally put my scripts) then you don't really need the $(document).ready() wrapper.
$(document).ready(function() {
$("#menu-toggle").click(function(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
Menu
<!-- <script src="your-file.js" type="text/javascript"></script> -->
</body>
Edit 2
Using the onclick syntax would look something like this.
//your-file.js
function menu_toggle_click(e) {
$("#wrapper").toggleClass("toggled");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
Menu
<!-- <script src="your-file.js" type="text/javascript"></script> -->
</body>
I have Index.asp
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<!--#include file="blocks/header.asp"-->
<!--#include file="blocks/bottom.asp"-->
<!--#include file="blocks/footer.asp"-->
</body>
</html>
blocks/header.asp
<div class="hideMeIamHeader"></div>
blocks/bottom.asp
<div class="hideMeIambottom"></div>
blocks/footer.asp
<div class="hideMeIamfooter"></div>
<button id="Hideheader">Hide Header</button>
<button id="Hidebottom">Hide bottom</button>
<button id="Hidefooter">Hide footer</button>
<script>
$(function() {
$('#Hideheader').on('click',function(){$('.hideMeIamHeader').hide();});
$('#Hidebottom').on('click',function(){$('.hideMeIambottom').hide();});
$('#Hidefooter').on('click',function(){$('.hideMeIamfooter').hide();});
});
</script>
How to make this example working? I cant access .hideMeIamHeader and .hideMeIambottom from footer.asp
UPDATE (SOLVED)
So index.asp must look like
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<!--#include file="blocks/header.asp"-->
<!--#include file="blocks/bottom.asp"-->
<!--#include file="blocks/footer.asp"-->
<script>
$(function() {
$('#Hideheader').on('click',function(){$('.hideMeIamHeader').hide();});
$('#Hidebottom').on('click',function(){$('.hideMeIambottom').hide();});
$('#Hidefooter').on('click',function(){$('.hideMeIamfooter').hide();});
});
</script>
</body>
</html>
The most likely scenario is that these items do not exist in the DOM yet at the time the click handlers are being set. You can rectify this by using jQuery's ready() function:
$(document).ready(function() {
$('#Hideheader').on('click',function(){$('.hideMeIamHeader').hide();});
$('#Hidebottom').on('click',function(){$('.hideMeIambottom').hide();});
$('#Hidefooter').on('click',function(){$('.hideMeIamfooter').hide();});
});
jQuery Documentation: https://api.jquery.com/ready/
Your code should be executed once DOM is ready,
$(document).ready( function(){
//Your code goes here
$('#Hideheader').on('click',function(){$('.hideMeIamHeader').hide();});
$('#Hidebottom').on('click',function(){$('.hideMeIambottom').hide();});
$('#Hidefooter').on('click',function(){$('.hideMeIamfooter').hide();});
});
More Explanation: Your code is being executed when file is being loaded, and not when whole page is loaded, so when Javascript page is loaded actually page and DOM elements are not created, so jquery is not able to find the elements.
So First you need to let load all the DOM content and then you and work on DOM elements, So you code should be always executed once DOM is ready...
I am using jQuery and Ajax.
HOME.html
<html>
<head>
<script src="jquery.js"></script>
<script src="javascript.js"></script>
</head>
<body>
<div id="div1"></div>
<button>click</button>
</body>
</html>
javascript.js
$(document).ready(function(){
$('button').click(function(){
alert('Button is clicked');
$("#div1").load("test2.html");
});
$("#b2").click(function(){
$("#div2").hide();
});
});
TEST2.html
<body>
<div id="div2">
some content
<input type="button" id="b2" value="hide" />
</div>
</body>
<head><script src="javascript.js"></script></head>
When I click on button, Ajax loads the content in div. But when I again click on button then it is clicked twice. I know why this click twice happens, because I again load the javascript.js file.
If I can't do that then the hide button is not working because the JavaScript loads before the div2, that's why hide button is not working.
SOLUTION:
There is one solution is that I use the hide button code in test2.html instead of in javascript.js But I don't want to do that.
Beacuse this is a demo in my original code this is very difficult to do that.
Is there another solution to this?
Repeatedly re-loading the JavaScript is a bad idea.
If you just want to handle clicks on buttons that are dynamically added, you can do that using event delegation. Remove javascript.js from test2.html entirely, and hook up your handlers like this (e.g., change javascript.js to the following):
$(document).on("click", "button", function(){
alert('Button is clicked');
$("#div1").load("test2.html");
});
$(document).on("click", "#b2", function(){
$("#div2").hide();
});
That watches for the click event on the document, but only fires the associated handler if the event passed through an element in the bubbling phase that matches the selector in the second argument. When firing the handler, jQuery makes it look a lot like you had the handler actually attached to that element, rather than to document.
There's a lot more in test2.html than there should be. jQuery will only append the bit in the body (and run the script, but we're removing that). test2.html should just be:
<div id="div2">
some content
<input type="button" id="b2" value="hide" />
</div>
Side note: If you're going to replace it on the next click, I'd use $("#div1").empty() rather than $("#div2").hide() so that you actually proactively remove the content you're going to replace later, rather than just hiding it.
I do something like this:
$("#id1").html(data);
I refill a div with html but when I try to get the html of a child of this refilled div I get an empty string although it has, it's like the old child is still there but without html.
Edit:
I tried to reproduce my problem, here is the html: (click 2x times on refill and after click open you will see that nothing is going to happen)
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.min.js"></script>
<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/themes/dot-luv/jquery-ui.css"/>
</head>
<body>
<script type="text/javascript">
$(function(){
$("#r1").click(function(){
var x = $("#main").html();
$("#main").html(x);
});
});
</script>
refill
<div id="main">
<a id="a1" href="#" >open</a>
<script type="text/javascript">
$(function(){
$("#a1").click(function(){$("#forDialog").dialog();});
$("#a2").click(function(){$("#forDialog").dialog('close');});
});
</script>
<div id="forDialog">
hi
<a id="a2" href="#" >close</a>
</div>
</div>
</body>
</html>
I'm generating this javascript dynamically so the scripts that register a1.click and a2.click need to be inside the main div
I'm not quite sure as to the exact goal of your code, but I can make 3 general suggesions:
Use .delegate() to attach to once and future elements.
You can .hide() the HTML for you dialog box.
You can prevent the page from refreshing when a link is clicked using event.preventDefault(); in the click handler of that link.
Applying those suggestions to your code results in the following working code:
<script type="text/javascript">
$("body").delegate("#a1", "click", function(){
$("#forDialog").dialog();
});
$("body").delegate("#a2", "click", function(){
$("#forDialog").dialog('close');
});
$(function(){
// Hide HTML for the dialog.
$("#forDialog").hide();
$("#r1").click(function(event){
var x = $("#main").html();
$("#main").html(x);
// If you don't want the page to refresh by clicking
// on this A element, use the following:
event.preventDefault();
});
});
</script>
refill
<div id="main">
<a id="a1" href="#" >open</a>
<div id="forDialog">
hi
<a id="a2" href="#" >close</a>
</div>
</div>
jsFiddle example
The old sub-DOM under the element will be gone after you reset its content with .html(stuff). It may exist floating around in memory somewhere, but it's detached from the DOM and you can't get at it.