Cloned content editable div not retaining keydown event - javascript

I'm very new to Jquery and looking to solve the reason a keydown event on a content editable div isn't cloning. I thought I had solved things when I discovered clone(true), but no my code still isn't working. The code below is a simplified version of what I'm trying to achieve.
Basically I'm attaching a keydown event to a content editable div then cloning it. However the cloned div isn't working like the original div.
I've been searching for a solution for a good while now and was hope someone could give me an answer so I can move on - many thanks.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>untitled</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var mymax1 = 10;
$('#List_1').keydown(function(e){ check_charcount(mymax1, e); });
function check_charcount(mymax1, e)
{
<!--prevent line breaks, that is the enter key from working-->
if(e.keyCode==13){
e.preventDefault();
}
if(e.which != 8 && $('#List_1').text().length > mymax1{
$("#List_1").css("background-color","yellow");
e.preventDefault();
}
}
<!---->
var $cloned = $('#hope').clone(true);
$('#placeHere').append($cloned.html());
});
</script>
</head>
<body>
<div id="hope">
<div id="List_1" contentEditable="true">TEXT</div>
</div>
</br>
<div id="placeHere"></div>
</body>
</html>

Some things were not correct in your code as pointed Ian.
In your keydown function you are using $('list_1'), you should use reference to element.
BTW, clone keep id attr which mean that your cloned element get same id as original, which is not valid. See working code:
$(document).ready(function () {
var mymax1 = 10;
$('#List_1').keydown(function (e) {
check_charcount(mymax1, e);
});
function check_charcount(mymax, e) {
if (e.keyCode == 13) {
e.preventDefault();
}
if (e.which != 8 && $(e.target).text().length > mymax) {
$(e.target).css("background-color", "yellow");
e.preventDefault();
}
}
var $cloned = $('#hope').clone(true);
$('#placeHere').append($cloned.contents().removeAttr('id'));
});
SEE DEMO

Related

Jquery not functioning on table created by javascript

I have table which i created entirely by javascript and my Jquery code dont want to work with it :/ If i use it on Table which is created manualy (in html) i works just fine. See fiddle below.
FYI this jquery code should just alow user to use arrow keys for navigation between inputs (table cells)
Here is that jsFiddle
I load my scripts in head:
<head>
<meta charset="UTF-8">
<title>My Page</title>
<link rel="stylesheet" type="text/css" href="css/stylesheet.css">
<script type='text/javascript' src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/js.js"></script>
</head>
Table is created here (in body):
<div id="myTable">
</div>
<script type="text/javascript">
createTable();
addPerson(1);
</script>
This is my jQuery:
$(document).ready(function() {
$('input').keydown(function(e) {
if (e.keyCode == 40 || e.keyCode == 13) {
var thisClass = $(this).parent().attr('class');
$(this).parent().parent().next('tr').children('.' + thisClass).children().focus();
}
});
$('input').keydown(function(e) {
if (e.keyCode == 39) {
$(this).parent().next('td').children('input').focus();
}
});
$('input').keydown(function(e) {
if (e.keyCode == 38) {
var thisClass = $(this).parent().attr('class');
$(this).parent().parent().prev('tr').children('.' + thisClass).children().focus();
}
});
$('input').keydown(function(e) {
if (e.keyCode == 37) {
$(this).parent().prev('td').children('input').focus();
}
});
});
You connect event listeners only to existing elements. You should connect it to document to deal with dynamically created elements:
$(document).on('keydown', 'input', function(e) {
// keycode first
if (e.keyCode==40 || e.keyCode==13) {
}
// keycode second etc.
if (e.keyCode==39) {
}
if (e.keyCode==38) {
}
if (e.keyCode==37) {
}
});
UPD actually it is a bad idea to connect listener to a document if it is very large. You can attach listener to an element after creating it.
You probably tried to bind the keydown event before the table was created. Try using the on method instead.
You also need to attach the event to an existing parent element that existed before the creation of the table, like in the body or another parent element.
$('body').on('keydown', "input", function(e) {
if (e.keyCode==40 || e.keyCode==13) {
var thisClass = $(this).parent().attr('class');
$(this).parent().parent().next('tr').children('.'+thisClass).children().focus();
}
});
Take this as an example. I would recommend you to use another wrapping element and bind via it's class or id, instead of element name.

Javascript: Eventhandler not functioning, works in JSFiddle

So this is an answer to another question I posted and I think it is the correct solution. However, while it works wonderfully in jsfiddle it does not function whatsoever outside of that environment. I have tried multiple combinations and I cannot get this thing to work right.
I've tried onLoad in the body, Window.onload both in the header wrapping around the function and separately calling it at the base of the page after all the elements have loaded. Nothing works.
I always get this issue:
Uncaught TypeError: Cannot call method 'addEventListener' of null
Which is frustrating, because all other solutions to this error I have seen revolve around ensuring you do in fact have the specified ID the handler triggers off of in your HTML. Which I do.
I know its probably overkill to make a post here on this but I'm yanking my hair out.
Here's the JSfiddle: http://jsfiddle.net/fFW5r/1/
Here's a mockup page I made to test the concept (which never works):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
var link_container = document.getElementById('links');
function myFunction(){ link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}
</script>
</head>
<body onload="myFunction()">
<div id="links">
Inbound Link
Outbout Link
</div>
<script>window.onload=myFunction()</script>
</body>
</html>
This particular iteration I was trying to test it with the onload call at the bottom of the page after everything had loaded.
var link_container = document.getElementById('links'); need to be executed on document.onload so it has to be inside myFunction
In jsfiddle, the code is executed on load by default. in the fiddle at the left side panel > second select box if you select no wrap - in head you can recreate the problem.
Demo: Fiddle
<script type="text/javascript">
function myFunction(){
var link_container = document.getElementById('links'); // <<-- Move it inside `myFunction()`
link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}
</script>
The reason it doesn't work is that you are initializing link_container before the DOM is ready. Then when myFunction() runs, link_container has been initialized to undefined. Which causes it to fail. Initializing it in the function (after the DOM has loaded) should fix the issue
Put declare link_container inside the function.
var link_container = document.getElementById('links');
function myFunction(){
link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}

Identify which element id or class was clicked using jQuery?

Suppose I have
<body>
<div id="stuff">
<div id="cat">a</div>
<div id="dog">b</div>
<div id="elephant">c</div>
<div id="rabbit">d</div>
<div id="frog">e</div>
</div>
</body>​
So far the closet I could get was with JS,
document.getElement('body').onclick = function(e){
alert(e.target.innerHTML);
}​
Which prints out the contents of the div when I want the literal div id like 'cat' or 'dog' not 'a' or 'b'. Also I am trying to accomplish this using jQuery, am I heading in the right direction?
You need to include jQuery js file in order to use jQuery methods.
With jQuery
$('body').click(function(e){
alert(e.target.innerHTML);
alert(e.target.id)
alert($(e.target).attr('id'));
}​);
With Javascript
document.getElement('body').onclick = function(e){
alert(e.target.innerHTML);
alert(e.target.id)
}​
Sample html page using JQuery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery demo</title>
</head>
<body>
jQuery
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
document.getElement('body').onclick = function(e){
alert(e.target.innerHTML);
alert(e.target.id)
}​
</script>
</body>
</html>
http://jsbin.com/ohotuv/1/edit
document.getElementById('stuff').onclick = function( e ){
alert( e.target.id );
};
jQ way:
$('#stuff').click(function( e ){
alert( e.target.id );
});
If it has not an ID, but has a CLASS (and you want it!) you can do:
http://jsbin.com/ohotuv/3/edit - (where "elephant" is a class)
$('#stuff').click(function( e ){
var name = e.target.id || e.target.className;
alert(name);
});
If you are using pure javascript you may need to make it cross browser compatible.
window.onload=function(){
document.getElementsByTagName('body')[0].onclick = function(e){
e = e ? e : window.event;
var source = e.target || e.srcElement;
alert(source.id);
}
}
I'd recommend reading up on jQuery.on().
In your example I'd recommend:
$("body").on("click", function(event){
alert($(this).id);
});
Although it's highly recommended to reduce the scope what what elements you're looking for the click event. For example:
$("#stuff").on("click", "div", function(event){
alert($(this).id);
});
Which would only handle ANY div element inside the html tag with the id of stuff. Reducing the context of handling events can help with encapsulation and debugging problems.

How to get the element that fired the "onclick" event

<script>
function clicky(e){
console.log(e) //the clicked element
}
</script>
<span onClick="clicky(this)">Clickable</span>
In the script above, the console.log(e) will give me the <span> that I clicked on.
Is there any way that I could omit the clicky(this) and still get the element?
It's because I don't want to put (this) all over the document.
Any answer are welcomed.
See this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
<div id="foo" style="background:blue; width:100px; height:100px">
<script>
function clicky(e){
console.log(e);
}
var foo = document.getElementById("foo");
foo.onclick = function(e){clicky((e || window.event).target);}
</script>
</body>
</html>
You could try this, not tested though.
var spans = document.getElementsByTagName('span');
spans.attachEvent('click'.'clicky');
function clicky(e){
console.log(e) //the clicked element
}
or
var spans = document.getElementsByTagName('span');
for (i in spans)
{
spans[i].attachEvent('click'.'clicky');
}
function clicky(e){
console.log(e) //the clicked element
}
function clicky(e, elem){
<span onClick="clicky(event, this)">Clickable</span>
Or you could use Prototype or jQuery or any other library. I would improve your life.

iOS automatic hover fix?

Is there a jQuery plugin or JavaScript script that automagically loops through each CSS hover (found in an external stylesheet) and binds it with a double touchdown event?
Touchdown 1 - CSS :hover is triggered
Touchdown 2 - Click (link following or form action)
If there isn't something like this yet, can it be made and how (guidelines)?
EDIT:
To be clear, I am not in search of a double tap. Touchdown 1 is a single tab just like Touchdown 2 is. There can be as less as 0 seconds between both or as much as 3 minutes, that's the user's choice.
No touch:
:hover -> element becomes visible
click -> following link or other action
Touch (iOS):
touchdown 1 -> element becomes visible
touchdown 2 -> following link or other action
Try this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>iPad Experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
if(navigator.platform == "iPad") {
$("a").each(function() { // have to use an `each` here - either a jQuery `each` or a `for(...)` loop
var onClick; // this will be a function
var firstClick = function() {
onClick = secondClick;
return false;
};
var secondClick = function() {
onClick = firstClick;
return true;
};
onClick = firstClick;
$(this).click(function() {
return onClick();
});
});
}
});
</script>
<style type="text/css">
a:hover {
color:white;
background:#FF00FF;
}
</style>
<body>
Google
stackoverflow.com
</body>
</html>
... or check out the demo on my web site. Note that it's set up to only work its magic on the iPad - detecting all versions of the iOS is another question in my books ;)
It works on the basis of the fact that...
After you click a link on the iphone or ipad, it leaves a simulated mouse hover that triggers the a:hover css styling on that link. If the link has a javascript handler that keeps you on same page, the hover state will not change until you click on another link.
Citation: Safari iphone/ipad “mouse hover” on new link after prior one is replaced with javascript
I've used this:
$(document).ready(function() {
$('.hover').bind('touchstart touchend', function(e) {
e.preventDefault();
$(this).toggleClass('hover_effect');
});
});
Before, to allow hover on certain elements. Obviously you'll need to tweak it for your own use, but it's a nice way to allow a touch and hold hover effect.
Here is a further optimized version that also handles closing the :hover
You'll have to encapsulate your site with a
<div id="container"></div>
for it to work. Just putting the closing event on the body did nothing
var bodyBound = false;
var container;
if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/iPad/i))
{
container = $("#container");
// Provoke iOS :hover event
$("a.someLink").on("mouseover", handleHoverClick);
}
function handleClose(event)
{
container.off("click", handleClose);
bodyBound = false;
}
function handleHoverClick(event)
{
if (!bodyBound)
{
bodyBound = true;
// Somehow, just calling this function—even if empty—closes the :hover
container.on("click", handleClose);
}
}
I created this update apon Richard JP Le Guens solution. It works GREAT, but my version fixes the issue recognized by DADU.
Also I fixed his workaround to detect iPads. My solution detects any other touch devices too (except IE10 on MS surface, I didn't remember the MS special treatment).
My fix is not a 100% perfect solution, but it resets the hover fix at least when hovering another link.
<!DOCTYPE html>
<html>
<head>
<title>TouchDevice Experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
if(document.createEvent("TouchEvent")) { // using document.createEvent is more reliable than navigator (Modernizr uses this practice)
$("a").each(function() { // have to use an `each` here - either a jQuery `each` or a `for(...)` loop
var onClick; // this will be a function
var firstClick = function() {
$("a").trigger("JWUnhover"); // triggering hoverfix reset if any link gets touched
onClick = secondClick;
return false;
};
secondClick = function() {
onClick = firstClick;
return true;
};
onClick = firstClick;
$(this).click(function() {
return onClick();
});
$(this).bind('JWUnhover', function(){ onClick = firstClick; });
});
}
});
</script>
<style type="text/css">
a:hover {
color:white;
background:#FF00FF;
}
</style>
</head>
<body>
Google
stackoverflow.com
</body>
</html>
There is no jQuery plugin that I know of to do such a thing.
You cannot trigger a css psuedo class such as ":hover". You can however loop through the anchor elements and add a css class ".hover" on touchstart and touchend events as follows:
var pageLinks = document.getElementsByTagName('a');
for(var i = 0; i < pageLinks.length; i++){
pageLinks[i].addEventListener('touchstart', function(){this.className = "hover";}, false);
pageLinks[i].addEventListener('touchend', function(){this.className = "";}, false);
}
To add a double finger tap gesture recognizer, you can use a plugin such as:
http://plugins.jquery.com/project/multiswipe
This worked for me!
// Ipad Navigation Hover Support
$('#header .nav li a').bind('touchstart touchend', function(e) {
if( $(this).attr("href") != "" ){
window.location = $(this).attr("href");
}
});
Here's an optimized version of the jQuery code provided by Richard JP Le Guen:
$(document).ready(function() {
$('a').each(function() {
var clicked = false;
$(this).bind('click', function() {
if(!clicked) return !(clicked = true);
});
});
});
There is a more simpler way to fix the issue with iOS and hover states, using CSS. For the link you have an issue with set the cursor property to pointer and the hover state will be ignored on iOS. For all links to function as expected, see below:
a
{cursor: pointer;}

Categories