Passing innerHTML to an element and attaching event - javascript

I have to pass innerHTML to a div using my JavaScript function.The innerHTML that I am passing also has a div for which I have to attach a click event so that on click of it, the element responds to the click event.
I have a fiddle here to explain the problem:
http://jsfiddle.net/K2aQT/2/
HTML
<body>
<div id="containerFrame">
</div>
</body>
JavaScript
window.onload = function(){usersFunction();};
function usersFunction(){
var someHtml = '<div> <div class ="btnSettings"> </div> <span></span> </div>';
changeSource(someHtml);
}
function changeSource(newSource){
document.getElementById("containerFrame").innerHTML = newSource;
}
While passing the source, how do I tell JavaScript function that this HTML being passed also has some element which has to be bound to a click event?

If you have to do it this way, you could consider adding the click handler inside the HTML string itself:
var someHtml = '<div> <div class ="btnSettings" onclick="return myFunction()"> </div> <span></span> </div>';
Alternatively, after modifying the .innerHTML, find the right <div>:
var frame = document.getElementById('containerFrame');
frame.innerHTML = newSource;
var settings = frame.getElementsByClassName('btnSettings')[0];
// depends on the browser, some IE versions use attachEvent()
settings.addEventListener('click', function(event) {
}, false);

i think you need something like that:
document.getElementById("containerFrame").onclick = function() {
// put your function here
};

Related

In JavaScript and HTML, how can I get the access to the <div> that the current button locates?

In HTML, I have
<div>
<button onclick="action()">button</button>
</div>
Without giving an ID or class to the div element, what can I do in JavaScript to get an access to it and use it?
Pass this into action:
<button onclick="action(this)">button</button>
and then in action
function action(btn) {
var div = btn.parentNode;
// ...
}
or if you want a bit more flexibility, use the (relatively-new) closest method:
function action(btn) {
var div = btn.closest("div");
// ...
}
Side note: Rather than onxyz-attribute-style event handlers, consider using modern event handling (addEventListener, attachEvent on obsolete browsers). If you have to support obsolete browsers, my answer here provides a function you can use to deal with the lack of addEventListener.
Grab the event then get the currentTarget then find the parentNode. Very simple way to do it. This will work no matter which element is clicked. Please see code snippet demonstration.
function getParentNode(event) {
console.log(event.currentTarget.parentNode);
}
<div id="div1"><button onclick="getParentNode(event)">Click</button></div>
<div id="div2"><button onclick="getParentNode(event)">Click</button></div>
using this in the onclick=action() and then the parent is .parentNode
then your method would look like :
<div>
<button onclick="action(this);">button</button>
</div>
function action(el) {
console.log(el.parentNode);
}
but I rather prefer .addEventListenerand for your next question then :
var $el = document.getElementById("a");
$el.addEventListener("click", function(e) {
// Create a <button> element
var btn = document.createElement("BUTTON");
// Create a text node
var t = document.createTextNode("CLICK ME");
// Append the text to <button>
btn.appendChild(t);
// Append <button> to the parentNode
this.parentNode.appendChild(btn);
});
<div>
<button id="a">Button</button>
</div>
Also in case you wonder for a shorter version and probably introducing to the jQuery :
;$(function(){
$("#a").on("click", function(e) {
$(this).parent().append('<button>Click Me</button>');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button id="a">Button</button>
</div>
Another but not straight way to get the parent instead of .parentNode is .closest() method:
element.closest("div"); // also supported in jQuery
Returns the first ancestor of element, that is a <div> element:
If it is possible, pass this (button) to action. Then you can access parent by element.parentNode. Example: https://jsbin.com/fidufa/edit

javascript onClick=funct(this) replacement using addEventListener

I'm looking for a clear replacement for the old onClick=funct(this) html event handler when generating code dynamically. The problem is that I can't seem to find one no matter how I look.
I'm creating a <div> tag as part of a function, and inside it is a <a> tag with a html event handler for onClick, where it passes itself as a parameter so I can find the related elements inside its <div>. But I know this is bad practice now, and I'd like to instead use the preferred addEventListener way, but I've no idea how to pass the caller into the function unless because as far as I know the following won't work.
renamehead.addEventListener('click', 'rename(renamehead)');
My current code: the js, and the html it generates.
function makeActivity(name) {
var act = document.createElement('div');
act.setAttribute('class', 'activity');
var acthead = document.createElement('div');
acthead.setAttribute('class', 'acthead interface_element');
act.appendChild(acthead);
namehead = document.createElement('h3');
var txt = document.createTextNode(name);
namehead.appendChild(txt);
namehead.setAttribute('contenteditable', 'true')
acthead.appendChild(namehead);
var renamehead = document.createElement('a');
txt = document.createTextNode('Rename');
renamehead.appendChild(txt);
renamehead.setAttribute('class', 'headcommand');
renamehead.setAttribute('href', 'javascript:void(0)');
renamehead.setAttribute('onClick', 'rename(this)');
var delhead = document.createElement('a');
txt = document.createTextNode('Delete');
delhead.appendChild(txt);
delhead.setAttribute('class', 'headcommand');
delhead.setAttribute('href', 'javascript:void(0)');
delhead.setAttribute('onClick', 'delActivity(this)');
txt = document.createTextNode(' ');
acthead.appendChild(renamehead);
acthead.appendChild(txt);
acthead.appendChild(delhead);
var actions = document.createElement('div');
actions.setAttribute('class', 'actactions');
actions.appendChild(makeDropDiv());
act.appendChild(actions);
return act;
}
<div id="activitydiv">
<div class="activity">
<div class="acthead interface_element">
<h3>Record</h3>
Rename
Delete
</div>
</div>
<div class="activity">
<div class="acthead interface_element">
<h3>Stop</h3>
Rename
Delete
</div>
</div>
</div>
Pass in real functions instead, and you can simply use the local variables.
renamehead.addEventListener('click', function() {
rename(renamehead);
});
You really don't want to pass a string the execute to addEventListener. Passing in a real javascript function will give you the flexibility you need here.
I prefer using .bind(),
renamehead.addEventListener('click', rename.bind(this,renamehead));
Here you can pass in the context you wish to be present for instance i'm using the same this.
This will keep the scope you require.

How can i get the Id from the next element?

I'm trying to get the ID from the next element, but i get this - "undefined"...
What am i doing wrong?
http://jsfiddle.net/84x9v/
HTML:
<a class="col" onclick="getId()">
<div id="1"><span>1</span></div>
</a>
JavaScript:
function getId(){
var get = $(this).next("div").attr("id");
alert(get);
}
remove the inline js
<a class="col">
<div id="1"><span>1</span></div>
</a>
and use an event handler
$('.col').on('click', function() {
var get = $(this).find("div").prop("id");
alert(get);
});
note that putting a block element inside an anchor generally isn't very good practice, and the div is a child of the anchor, it's not the next sibling.
'cause it's not the 'next' element.
function getId(){
var get=$(this).find("div").attr("id");
alert(get);
)
should work...
You're using jQuery and .next() wrong. Remove the inline event handler, use .find() instead of .next(), and try:
function getId() {
var get = $(this).find("div").attr("id");
alert(get);
}
$('a').click(getId)
jsFiddle example

Passing "this" and "event" in JS function

I have a button with an onclick event as follows:
<button type="button" onclick="captions(event)">
<img src="someimg.png">
</button>
I need to be able to change the img src without using an ID to reference it. I want to pass "this" and the event (I need to do some other things that require event to be passed) but I cannot get this to work. Example of JS is below:
function captions(event) {
this.src = this.src.replace("img2.png");
}
Thanks!
I suggest not using inline event handlers. You should bind the event "unobtrusively" using JavaScript.
First give the button a class:
<button type="button" class="captions">
<img src="someimg.png">
</button>
Then bind the event:
window.onload = function(){
var captions = document.getElementsByClassName('captions');
for(var i = 0, len = captions.length; i < len; i++){
captions[i].addEventListener('click', function(event){
// this is your button, what you clicked on
// you need to get the image
var image = this.getElementsByTagName('img')[0];
// this.src.replace("img2.png") doesn't do what you think it does
// String.replace takes 2 parameters
image.src = '/your/new/image';
});
}
};
DEMO: http://jsfiddle.net/WcFzq/
You can get the element that was clicked using the event.target property (http://www.w3schools.com/jsref/event_target.asp).
function captions(event) {
event.target.src = "img2.png";
}
Here is a jsfiddle.
Following will solve your problem.
function captions(event) {
var img = this.childNodes[0];
img.src = img.src.replace("img2.png");
}
If you want to do an inline onclick event, you should simply be able to pass a new variable that captures the element into the function, like this:
function captions(element, event) {
. . . do stuff . . .
}
Then you would call it, passing this in for the element parameter, like this:
<button type="button" onclick="captions(this, event);">
<img src="someimg.png">
</button>

Why do most of my jquery functions stop working after prepending a message to an existing list of messages?

HTML:
<div class='cf' id='content'>
<div id='leftColumn'>
</div>
<div class='microposts'>
<div class="micropostContent">
</div
</div>
<div id='rightColumn'>
</div>
</div>
Prepend:
$('.micropostContent').prepend('<%= j render("users/partials/micropost") %>');
Some of the functions:
$(".micropost_content").focus(function() {
this.rows = 7;
var micropostBox = $(this),
xButton = $(this).parent().find(".xButton");
micropostBox.hide().addClass("micropost_content_expanded").show().autoResize();
xButton.css("display", "block");
xButton.click(function() {
micropostBox.removeClass("micropost_content_expanded").addClass("micropost_content");
micropostBox.val("");
xButton.hide();
});
});
$(".comment_box").focus(function() {
this.rows = 7;
var $commentBox = $(this),
$form = $(this).parent(),
$cancelButton = $form.children(".commentButtons").children(".cancelButton");
$(this).removeClass("comment_box").addClass("comment_box_focused").autoResize();
$form.children(".commentButtons").addClass("displayButtons");
$form.children(".commentButtons").children(".cancelButton");
$cancelButton.click(function() {
$commentBox.removeClass("comment_box_focused").addClass("comment_box");
$form.children(".commentButtons").removeClass("displayButtons");
$commentBox.val("");
});
});
$('.micropostOptions').on('click',function(){
var postMenu = $(this).find('.postMenu');
if(postMenu.is(':hidden') ){
$('.postMenu').hide();
$('.micropostOptions').removeClass("postMenuHoverState");
postMenu.show();
$(this).hide().addClass('postMenuHoverState').show(60);
}else{
postMenu.hide();
$(this).removeClass("postMenuHoverState");
}
});
The functions that stop working are focus and click functions. They only work again after refreshing until I post another ajax message/micropost.
The .comment_box function doesn't work on the message that's been prepended but it works on all the previous messages. The .micropostOptions function doesn't work all. Then after refreshing everything works just fine.
Am I missing something?
Kind regards
Because the events are only bound to existing items when you declare them.. declare using on and attach to a parent element instead
$(document).on("focus", ".comment_box", function() {
//this will work with new elements
});
The closer the parent is to the element you are attaching functionality to the better, for example the parent container ".cf" or ".microposts" instead of document in your case.
To elaborate, in your example, you are only binding events to the individual elements, and when new items are added, they don't have the same event bindings... When you bind the event to a higher level element, then you are basically saying "apply this handler to everything inside of this parent element that matches this selector".

Categories