I'm using this code to change the content of an div
mydiv.innerHTML = "html code with text and images";
Is there some events I can use to get a notification when everything is loaded? (no matter if there is no or many images )
I guess I could go through all child elements and addeventlisteners to them, but wish there is some other way.
Maybe something like this, just to give you an idea in vanilla javascript
var updateContent = function(element, content) {
element.innerHTML = content;
var images = element.querySelectorAll('img');
var loadedItems = 0;
var totalItems = images.length;
var loaded = function() {
loadedItems++;
console.log('loaded item: ' + loadedItems);
if(loadedItems == totalItems) {
element.classList.add('load-completed')
console.log('finished loading all images');
}
};
for(var i=0; i < totalItems; i++){
if(images[i].complete) {
loaded();
} else {
images[i].addEventListener('load', loaded);
images[i].addEventListener('error', function() {
console.log('error');
});
}
}
}
updateContent(
document.querySelector('.my-div'),
'<h1>hello world<\h1><img src="https://picsum.photos/id/237/200/300"><img src="https://picsum.photos/id/1/200/300">'
);
.my-div {
border:solid 5px orange;
}
.my-div img {
width: 300px;
height: 200px;
}
.load-completed {
border: dashed 5px green;
}
<div class="my-div"></div>
Edit 2012 live The live method is deprecated as of jQuery 1.7.0.
The .on() event is now recommended for attaching event handlers.
This replaces .bind(), .delegate(), and .live().
See the docs: http://api.jquery.com/on/
Original Answer
i think jQuery .live() event might be what you're looking for.
try this
mydiv.live('load', function () {
//code here
});
Related
I have a layout which I dont think its necessary to post here. But its basically a parent div with a very small width and height that stays on bottom right of a page, if clicked on it, it enlarges width and height.
Here where I had issue:
The parent contains onclick, if its click, it then change its size as well as disabling its onclick and adding onclick to an image, which is a button to minimise the parent div to its original size.
If the image is clicked then again, I disable the onclick on the image and add onclick on the main parent. However Javascript is executing onclick on the parent as it thinks its been clicked, since the image is inside the parent.
To fix this issue I had to set a setTimeout to add the onclick to the parent, that solved the issue, but is there a better way, and why does that happen?
Tahnks
function adjust_window_displayed(el, main_el){
var val = el.value;
var img_el = document.getElementById("img_envelope");
if(val === "true"){
document.getElementById("display_mail_info").style.display = "block";
img_el.src = "https://co.uk/minimise.png";
img_el.style.cursor = "pointer";
main_el.style.cursor = "default";
main_el.onclick = function () {
return false;
};
el.value = "false";
img_el.onclick = function () {
adjust_window_displayed(el, main_el);
console.log("first");
};
console.log("first " + main_el.className);
}else{
document.getElementById("display_mail_info").style.display = "none";
img_el.src = "https://dco.uk/envelope.png";
img_el.style.cursor = "default";
main_el.style.cursor = "pointer";
el.value = "true";
img_el.onclick = function () {
return false;
};
setTimeout(function() {
main_el.onclick = function () {
adjust_window_displayed(el, main_el);
console.log("sec");
};
}, 700);
console.log("second " + main_el.className);
}
}
What happens is due to the event bubble, when you click on the <img> the click event fire once, then a second time for the parent, now if you don't handle that in your function properly it'll give you problems.
Now I have no idea how you're calling that function nor what parameters, you're passing to it, so i tried to reproduce the problem myself.
If you would assign the click event useing the .onclick = function(){}
you can use it to alter between the two, since you're using the same function.
document.querySelector('#parent').onclick = lol;
function lol(e){
var type = e.target.nodeName;
if (type == "DIV")
{
if (e.target.onclick)
{
alert('clicked parent');
e.target.onclick = "";
document.querySelector('#kid').onclick = lol;
}
}
else if (type == "IMG")
{
if (e.target.onclick)
{
alert('clicked kid');
e.target.onclick = "";
document.querySelector('#parent').onclick = lol;
}
}
}
#parent{
width: 500px;
height: 500px;
background-color: red;
}
img{
width: 10%;
height: 10%;
}
<div id="parent">
<img id="kid">
</div>
I have responsive design, with padded container around input. Problem is, when user clicks in padded area, input wont be focused.
In jQuery the working code is:
$('.wrap').on('click', function (e) {
$(this).find('input').focus();
});
But can't seem to get it working in JS:
var elm_rows = document.getElementsByClassName("wrap");
elm_rows.addEventListener("click", function (e) {
e.getElementsByTagName("input").focus();
});
https://jsfiddle.net/2f9sq3tf/
Try accessing each of your getElementsBy functions as an array.
Example:
var elm_rows = document.getElementsByClassName("wrap")[0];
elm_rows.addEventListener("click", function (e) {
this.getElementsByTagName("input")[0].focus();
});
To resolve the remaining concern just wrap this in a loop like:
var elm_rows = document.getElementsByClassName("wrap");
for (i in elm_rows) {
elm = elm_rows[i];
elm.addEventListener("click", function (e) {
this.getElementsByTagName("input")[0].focus();
});
}
Could be better, but this works.
This should work:
let wrap = document.querySelectorAll('.wrap');
wrap.forEach((el) => {
el.addEventListener('click', (e) => {
// whatever you need to do goes here
});
});
today you can use querySelector to find elements on the DOM (and inside some NODE too).
Example:
var els = document.querySelectorAll('.wrap');
for(var i = 0; i < els.length; i++){
els[i].addEventListener('click',function(ev){
var input = ev.target.querySelector('input');
if(input) input.focus();
});
}
The if is required because with that code if you click on the input node, the event will propagate to the .wrap element, and your callback will execute too, but ev.target will be the input node and the query will return null.
var elm_rows = document.getElementsByClassName("wrap");
elm_rows[0].addEventListener("click", function (e) {
e.currentTarget.children[0].focus();
});
.wrap {border: 3px solid blue; padding: 15px;}
input {width: 100%;}
<div class="wrap">
<input type="text" name="" value="" />
</div>
i am currently having a problem. I am using css to hide and display elements depending on the mouse function. One of my elements (a navigation arrow) depends on some other things. I now need a cancleable timer function which counts for lets say 2 seconds on mouseleave and then changes the class attribute. But it should have a timer which cancels on mouseover immediately. I dont want it to disappear too early.
Below my code with which i tried so far. I have no idea how to access the current timings of that setIntervall stuff. I alreasy experimented with Date.now(). But now i hope some of the geeks is able to help me.
Thanks in advance.
function hideElementOnMouseOut(el)
{
el.addEventListener("mouseleave", function( event )
{
mySlideAction = setInterval( function()
{
}, 1000 );
}
}
You can initialize interval on mouseleave function and clear this interval on mouseover function, which would prevent executing it's function.
Check the snippet below.
function hideElementOnMouseOut(el)
{
var interval;
el.addEventListener("mouseleave", function(event)
{
el.innerHTML = 'mouse out';
interval = setInterval(function()
{
el.innerHTML = 'time out';
el.className = 'out';
}, 1000);
});
el.addEventListener("mouseover", function(event)
{
el.innerHTML = 'mouse in';
el.className = '';
if(interval) {
clearInterval(interval);
}
});
}
hideElementOnMouseOut(document.getElementById("element"));
#element {
display: block;
width: 200px;
height: 200px;
background: red;
}
#element.out {
background: blue;
}
<div id="element"></div>
I would just like to know if it is good practice to have a click event listener in a function like the example below. (Don't try to understand what the code does, I just wanted to show an example of a situation where a click event is in a function )
function someFn(classClickedBtn, popupId) {
$(classClickedBtn).click(function(e) {
e.preventDefault();
var active = "active";
var mainClass = ".dialogBox";
if ( $(popupId).hasClass(active) ) {
$(popupId).removeClass(active);
}else{
for (var i = 0; i< $(mainClass).length; i++) {
if ( $(mainClass).hasClass("active") ) {
$(mainClass).removeClass("active"); } }
$(popupId).addClass(active);
}
});
}
someFn(".btn1", "#popup");
someFn(".btn2", "#popup");
If your purpose is to attach an event handler for 'click' event of 'triggerBtnClass', only if something call your function before, so yes.
I'm okay with calling the listener from within your function. You can make things a little easier on yourself by calling the function one time with all arguments included. Have a look at the refactored code below. I'm using an object literal to store the function arguments and calling the function one time, passing the object as a single parameter.
function someFn(fn_data) {
$(fn_data.btns).on("click", function(e) {
var active = "active";
var mainClass = $(".dialogBox");
var popup = $(fn_data.popupId);
e.preventDefault();
if (popup.hasClass(active)) {
popup.removeClass(active);
} else {
for (var i = 0; i < mainClass.length; i++) {
if ( mainClass.hasClass("active") ) {
mainClass.removeClass("active");
}
}
popup.addClass(active);
}
});
}
someFn({
btns: ".btn1, .btn2",
popupId: "#popup"
});
#popup {
margin-top: 1em;
}
#popup.active:after {
content: 'Popup active!';
}
#popup:after {
content: 'Popup not active!';
color: #555;
display: block;
height: 20px;
white-space: nowrap;
margin-top: 10px;
border: 1px solid orange;
padding: 0.5em 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="btn1">button 1</button>
<button class="btn2">button 2</button>
<div id="popup">popup goes here</div>
I'm using the CSS3 :target pseudo selector to create in-page navigation without reloading the page. This works really well!
But I have a problem, I need to reset the forms in a page when the page targetted, how can I know if an element is targetted with javascript? Like element.ontarget = function();
Or maybe something like element.ondisplaychange -> element.oncsschange?
BETTER UPDATE:
var hashcache = document.location.hash;
window.onhashchange = function() {
if(hashcache != document.location.hash) {
$(hashcache + ' form input').each(function() {
$(this).val('');
});
hashcache = document.location.hash;
}
}
UPDATE:
$('a[href^="#"]').each(function() {
this.onclick = function() {
href = $(this).attr('href');
if(href != document.location.hash) {
$(href + ' form input').each(function() {
$(this).val('');
});
}
}
});
If you're using JavaScript for the navigation, I'd suggest just adding the check to that. But I'm guessing from your question you're not, that you're instead using plain links with just anchors (e.g., <a href='#target1'>, <a href='#target2'>, ...).
A couple of options:
Use a Timer
In that case, basically what you want to do boils down to receiving an event when the anchor changes. As far as I know, and as far as the people answering this other question on StackOverflow in January knew, you can only do that with a timer. (Edit: But see ide's comment below, there's a new hashchange event we'll be able to use soon!) E.g.:
(function() {
var lastHash = window.location.hash;
setTimeout(function() {
var newHash = window.location.hash;
if (newHash !== lastHash) {
lastHash = newHash;
// Trigger your target change stuff
}
}, 250);
})();
That checks for changes every quarter second. That may not be enough for you, you could lower the 250, but beware running too much and slowing everything else down.
But as you say below, this is inefficient.
Hook the Link's click event
Since you're already using JavaScript on the page, I'd recommend using handlers on your links instead. If you add a class name or something to them (I bet they already have one; I'll us "navlink" below), this is easily set up:
var links, index, link;
links = document.getElementsByTagName('a');
for (index = 0; index < links.length; ++index) {
link = links.item(index);
if ((" " + link.className + " ").indexOf(" navlink ") >= 0) {
hookEvent(link, 'click', clickHandler);
}
}
function clickHandler() {
// `this` will reference the element that was clicked
}
// The 'hook' function:
var hookEvent = (function() {
var elm = document.createElement('a');
function hookEventViaAttach(element, event, handler) {
element.attachEvent("on" + event, handler);
}
function hookEventViaAddListener(element, event, handler) {
element.addEventListener(event, handler, false);
}
function hookEventDOM0(element, event, handler) {
element["on" + event.toLowerCase()] = handler;
}
if (elm.attachEvent) {
return hookEventViaAttach;
}
if (elm.addEventListener) {
return hookEventViaAddListener;
}
// I usually throw a failure here saying not supported, but if you want,
// you can use the DOM0-style stuff.
return hookEventDOM0;
})();
A lot of the complication of the above goes away if you use a library like jQuery, Prototype, YUI, Closure, or any of several others.
For instance, the jQuery version:
$("a.navlink").click(clickHandler);
function clickHandler() {
// `this` will reference the element that was clicked
}
The Prototype version:
$$("a.navlink").invoke('observe', 'click', clickHandler);
function clickHandler() {
// `this` will reference the element that was clicked
}
The onfocus property returns the onFocus event handler code on the current element.
event handling code = element.onfocus
The onblur property returns the onBlur event handler code, if any, that exists on the current element.
element.onblur = function;
Example: http://jsfiddle.net/g105b/cGHF7/
<html>
<head>
<title>onblur event example</title>
<script type="text/javascript">
var elem = null;
function initElement()
{
elem = document.getElementById("foo");
// NOTE: doEvent(); or doEvent(param); will NOT work here.
// Must be a reference to a function name, not a function call.
elem.onblur = doEvent;
};
function doEvent()
{
elem.value = 'Bye-Bye';
alert("onblur Event detected!")
}
</script>
<style type="text/css">
<!--
#foo {
border: solid blue 2px;
}
-->
</style>
</head>
<body onload="initElement()";>
<form>
<input type="text" id="foo" value="Hello!" />
</form>
<p>Click on the above element to give it focus, then click outside the
element.<br /> Reload the page from the NavBar.</p>
</body>
</html>
Maybe youcan just code like this
function hashChangeEvent(){
$(window.location.hash)//do something
}
window.onhashchange = hashChangeEvent;//when hash change
hashChangeEvent();//first load