Unable to trigger event in IE during cloning - javascript

Following is the code which will clone a set of div with their events (onclick) which is working fine for Firefox but in case of IE it is not firing events associated with each div:
<html>
<head>
<style type='text/css'>
.firstdiv{
border:1px solid red;
}
</style>
<script language="JavaScript">
function show_tooltip(idx,condition,ev) {
alert(idx +"=="+condition+"=="+ev);
}
function createCloneNode () {
var cloneObj = document.getElementById("firstdiv").cloneNode(true);
document.getElementById("maindiv").appendChild(cloneObj);
}
function init(){
var mainDiv = document.createElement("div");
mainDiv.id = 'maindiv';
var firstDiv = document.createElement("div");
firstDiv.id ='firstdiv';
firstDiv.className ='firstdiv';
for(var j=0;j<4;j++) {
var summaryDiv = document.createElement("div");
summaryDiv.id = "sDiv"+j
summaryDiv.className ='summaryDiv';
summaryDiv.onmouseover = function() {this.setAttribute("style","text-decoration:underline;cursor:pointer;");}
summaryDiv.onmouseout = function() {this.setAttribute("style","text-decoration:none;");}
summaryDiv.setAttribute("onclick", "show_tooltip("+j+",'view_month',event)");
summaryDiv.innerHTML = 'Div'+j;
firstDiv.appendChild(summaryDiv);
}
mainDiv.appendChild(firstDiv);
var secondDiv = document.createElement("div");
var linkDiv = document.createElement("div");
linkDiv.innerHTML ='create clone of above element';
linkDiv.onclick = function() {
createCloneNode();
}
secondDiv.appendChild(linkDiv);
mainDiv.appendChild(secondDiv);
document.body.appendChild(mainDiv);
}
</script>
</head>
<body>
<script language="JavaScript">
init()
</script>
</body>
</html>
Can anybody tell me what's the problem in above code? Please correct me.

You have multiple problems with your code that make it either not working in some browsers or partial working in others:
onmouseover/onmouseout event
handlers assigned as properties do
not and shall not be copyied when
cloning (in any browser according to DOM specification), that is why you do not see
text-underline effect in any browser
In Internet Explorer (prior to IE9) it is not possible to assign an event handler by setting a onxxx attribute with setAttribute method
You clone an HTML structure with id attributes and insert it into the same document which creates a problem of duplicate id's - this is "illegal" and can lead to unpredictable behavior
So the only solution for you code to start working properly in every browser is to clone fragment without ids and (re-)assign event handlers manually.

I agree with #Sergey Ilinsky. You're running head first into DOM differences between IE and FF.
Try this code, it should help.
<html>
<head>
<style type='text/css'>
.firstdiv{
border:1px solid red;
}
</style>
<script language="JavaScript">
var cloneCount = 0;
var bname = navigator.appName;
var isIE = false;
if (bname == "Microsoft Internet Explorer"){
isIE = true;
}
else{
isIE = false;
}
function show_tooltip(idx,condition,ev) {
alert(idx +"=="+condition+"=="+ev);
}
function createCloneNode () {
var cloneObj = document.getElementById("firstdiv").cloneNode(false);
cloneObj.id += cloneCount++;
createSummaryNodes(cloneObj);
document.getElementById("maindiv").appendChild(cloneObj);
}
function createSummaryNodes(firstDiv){
for(var j=0;j<4;j++) {
var summaryDiv = document.createElement("div");
summaryDiv.id = firstDiv.id+"sDiv"+j
summaryDiv.className ='summaryDiv';
if(isIE){
summaryDiv.onmouseover = function() {this.style.textDecoration="underline";this.style.cursor="pointer";}
summaryDiv.onmouseout = function() {this.style.textDecoration="none";}
summaryDiv.onclick = function() { show_tooltip(j,'view_month',event); };
}
else{
summaryDiv.onmouseover = function() {this.setAttribute("style","text-decoration:underline;cursor:pointer;");}
summaryDiv.onmouseout = function() {this.setAttribute("style","text-decoration:none;");}
summaryDiv.setAttribute("onclick", "show_tooltip("+j+",'view_month',event)");
}
summaryDiv.innerHTML = 'Div'+j;
firstDiv.appendChild(summaryDiv);
}
}
function init(){
var mainDiv = document.createElement("div");
mainDiv.id = 'maindiv';
var firstDiv = document.createElement("div");
firstDiv.id ='firstdiv';
firstDiv.className ='firstdiv';
createSummaryNodes(firstDiv);
mainDiv.appendChild(firstDiv);
var secondDiv = document.createElement("div");
var linkDiv = document.createElement("div");
linkDiv.innerHTML ='create clone of above element';
linkDiv.onclick = function() {
createCloneNode();
}
secondDiv.appendChild(linkDiv);
mainDiv.appendChild(secondDiv);
document.body.appendChild(mainDiv);
}
</script>
</head>
<body>
<script language="JavaScript">
init();
</script>
</body>
</html>
EDIT: I added some VERY basic browser detection, took out the deep copy with cloneNode, restructured some of the code, and added some browser specific code.

Related

Load map from myshiptracking after page load

In addition to this topic execute a javascript after page load is complete I noticed the solution didn't work for loading a map. I do have a similar use case. However, if I follow the script the script needed doesn't load.
I want to load a map after the loading of the page is finished, however I do see the script in the page source, but no script is executed.
The source is:
var mst_width = "96%";
var mst_height = "350vh";
var mst_border = "0";
var mst_map_style = "simple";
var mst_mmsi = "244770624";
var mst_show_track = "true";
var mst_show_info = "true";
var mst_fleet = "";
var mst_lat = "";
var mst_lng = "";
var mst_zoom = "";
var mst_show_names = "0";
var mst_scroll_wheel = "true";
var mst_show_menu = "true";
window.onload = function () {
var element = document.createElement("script");
element.src = "http://www.myshiptracking.com/js/widgetApi.js";
document.getElementsByTagName("head")[0].appendChild(element);
}
In the page source I see:
var mst_width = "96%";
var mst_height = "350vh";
var mst_border = "0";
var mst_map_style = "simple";
var mst_mmsi = "244770624";
var mst_show_track = "true";
var mst_show_info = "true";
var mst_fleet = "";
var mst_lat = "";
var mst_lng = "";
var mst_zoom = "";
var mst_show_names = "0";
var mst_scroll_wheel = "true";
var mst_show_menu = "true";
window.onload = function () {
var element = document.createElement("script");
element.src = "http://www.myshiptracking.com/js/widgetApi.js";
document.getElementsByTagName("head")[0].appendChild(element);
}
Can someone please point me in the direction on how to get the script executed? I also assumed that the script should be appended to the 'body' instead of the 'head'm but I'm not sure about it.
Thanks!
Edit based change of head to body:
<script>
var mst_width="96%";var mst_height="350vh";var mst_border="0";var mst_map_style="simple";var mst_mmsi="244770624";var mst_show_track="true";var mst_show_info="true";var mst_fleet="";var mst_lat="";var mst_lng="";var mst_zoom="";var mst_show_names="0";var mst_scroll_wheel="true";var mst_show_menu="true";
window.onload = function() {
var element = document.createElement("script");
element.src = "http://www.myshiptracking.com/js/widgetApi.js";
document.getElementsByTagName("body")[0].appendChild(element );
}
</script>
So, finally I managed to solve the problem and got the desired map in my browser... using the following HTML+JS code (which you can run with the button below):
<html lang="en-US" prefix="og: http://ogp.me/ns#">
<head>
<script>
var mst_width="100%";var mst_height="450px";var mst_border="0";var mst_map_style="terrain";var mst_mmsi="";var mst_show_track="";var mst_show_info="";var mst_fleet="";var mst_lat="";var mst_lng="";var mst_zoom="";var mst_show_names="0";var mst_scroll_wheel="true";var mst_show_menu="true";
function loadMap() {
var element = document.createElement("script");
element.setAttribute("id", "myshiptrackingscript");
element.setAttribute("async", "");
element.setAttribute("defer", "");
element.src = "http://www.myshiptracking.com/js/widgetApi.js";
document.getElementById("mapContent").appendChild(element );
}
window.onload = loadMap
console.log('Registered onload')
</script>
</head><body>
<div id="mapContent" />
</body></html>
Two points of attention:
you should add the created script tag as child of a tag belonging to the body ot the page (I used <div id="mapContent"/> and getElementById to access it)
you should load the HTML page through a http:// URL, not through a a file:// one: with the latter you get an error with message like "Browser does not support embedded objects"
I hope this can help you to solve the problem in you real case!
There are many ways to invoke your function when the page has loaded.
My vanilla's js tool of choice most of the time is:
window.addEventListener('DOMContentLoaded', function(){
//your bindings and functions
}
That way of proceeding is preferred to your onload method as otherwise, you won't be able to attach multiple events when the DOM loads completely.
Try this:
window.onload=function(){
document.write('<script src="http://www.myshiptracking.com/js/widgetApi.js>
</script>');
}
wrap your javascript code with this:
if(document.readyState === 'complete') {
// good to go! Put your code here.}

Embedding should have been able to show the button

Please be advised that the following codes are generated by an engineer. (I don't have contact with the engineer right now)
Now here is the scenario. According to the engineer who had created this the whole collection of these scripts should be able to generate a button once edited properly and embedded to our website.
Before I implement this on our own website I want to test these codes to a simple page created through saving codes from our website. I ask the engineer if it is possible and he said yes.
Now here is the code that should be able to generate the button.
clickCall.js
(function () {
var createScriptElement = function (src, onload, onerror) {
var element = document.createElement("script");
element.type = "text\/javascript";
element.src = src;
element.onload = onload;
element.onerror = onerror;
return element;
};
var createLinkElement = function (src) {
var element = document.createElement('link');
element.href = src;
element.rel = 'Stylesheet';
element.media_type = 'text/css';
return element;
};
var createUI = function () {
var clickCallDiv = document.createElement('div');
clickCallDiv.style.cssText = 'width: 300px;height: 60px;position: fixed;z-index: 999;right: 20px;bottom: 320px;';
var call_btn = document.createElement("button");
call_btn.id = "dial_btn_call";
var session_div = document.createElement("div");
session_div.id = 'sessions';
var webcam_div = document.createElement("div");
webcam_div.style.cssText = 'height:0';
webcam_div.id = 'webcam';
var video_remote = document.createElement('video');
video_remote.id = 'remoteView';
video_remote.autoplay = 'autoplay';
video_remote.hidden = 'hidden';
var video_local = document.createElement('video');
video_local.autoplay = 'autoplay';
video_local.hidden = 'hidden';
video_local.muted = 'muted';
video_local.id = 'selfView';
webcam_div.appendChild(video_remote);
webcam_div.appendChild(video_local);
clickCallDiv.appendChild(call_btn); //add the text node to the newly created div.
var contain = document.createElement('div');
contain.appendChild(session_div);
contain.appendChild(webcam_div);
clickCallDiv.appendChild(contain);
return clickCallDiv;
};
var urls = {};
urls.rtcninja = 'rtcninja.js';
urls.jquery = 'jquery.js';
urls.i18n = "jquery.i18n.js";
urls.messagestore = "jquery.i18n.messagestore.js";
urls.jssip = 'jssip.js';
urls.init = 'init.js';
urls.gui = 'gui.js';
urls.css = 'style.css';
var rtcninja_script = createScriptElement(urls.rtcninja, function () {
// Must first init the library
rtcninja();
// Then check.
if (!rtcninja.hasWebRTC()) {
console.log('WebRTC is not supported in your browser :(');
} else {
document.body.appendChild(createUI());
}
});
var jquery_script = createScriptElement(urls.jquery, function(){
document.head.appendChild(i18_script);
document.head.appendChild(jssip_script);
document.head.appendChild(gui_script);
document.head.appendChild(init_script);
});
var i18_script = createScriptElement(urls.i18n, function(){
document.head.appendChild(messagestore_script);
});
var messagestore_script = createScriptElement(urls.messagestore);
var jssip_script = createScriptElement(urls.jssip);
var init_script = createScriptElement(urls.init);
var gui_script = createScriptElement(urls.gui);
var click_call_css = createLinkElement(urls.css);
document.head.appendChild(jquery_script);
document.head.appendChild(rtcninja_script);
document.head.appendChild(click_call_css);
})();
That script, when embedded, should be able to generate a button. The way he embedded the script on their website is through this
<script>
document.write('<script src="sourcefile/clickCall.js">/script>')
</script>
But this won't work on my side so I tried this
document.write('<sc' + 'ript src="clickCall.js">/sc' + 'ript>')
Now my first problem is that this script prevents all other scripts from loading, causing to have an empty output. another is that it won't display the expected button that it was suppose to show on the webpage. My solution to this problems was to implement DOM but I don't know how I'll implement it especially because I can't understand how it works and how to implement it. Could you kindly explain to me how DOM works and how am I going to implement it? Thanks
document.write when executed just writes the string and doesn't execute the inside script.
Hence, instead of this,
<script>
document.write('<script src="sourcefile/clickCall.js"></script>')
you can directly call your script.
<script src="sourcefile/clickCall.js"></script>

How to show a div what was hidden on img

So I have to make a hidden element (div) visible when you click on an image.
It worked on a button, but I can't seem to make it work on an image.
HTML code:
<div id="img4">
<img src="images/nummer1.png" alt="nummer1" data-hint="1"/>
</div>
<div id="hint" class="hidden">Hint 1</div>
JavaScript code:
window.onload = function () {
'use strict';
var button = document.getElementById("button");
var hint = document.getElementById("hint");
var showHint = function (event) {
console.log(this);
if data-hint === '1'
hint1.classList.toggle('hidden');
};
var img = document.querySelectorAll('img');
console.log(img);
for (var i = 0; i < img.length; i++) {
img[i].addEventListener("click", showHint);
};
function show(hint) {
};
button.addEventListener('click', show);
You see? It works on the button, but for some reason I can't make it work on an Image.
I notice you're not using jQuery. You might want to look into it, as it would make what you're trying to implement easier and much more readable.
But in any event:
hint1.classList.toggle('hidden');
Should be
hint.classList.toggle('hidden');
Also,
if data-hint === '1'
Needs to be
if (this.dataset.hint == 1)
which is how you check the data-hint attribute of this element (the one that was clicked).
http://jsfiddle.net/gunderjt/t46ws/
Should work:
$("img").click(function(){
$("div").show();
});
var showHint = function (event) {
console.log(this);
if(typeOf(hint) != 'null') hint.classList.toggle('hidden');
};
Actually you should update the hints id:s so for every image there are a corresponding hint, which shares the same id. So the first hint got a id of "hint-1".
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<style>
.hidden {
display: none;
}
.show {
display: block;
}
</style>
<div id="img4">
<img src="/test/img2.jpg" alt="nummer1" data-hint="1"/>
</div>
<div id="hint-1" class="hidden">Hint 1</div>
<script type="text/javascript">
window.onload = function() {
var images = document.getElementsByTagName("img");
for(var i=0;i<images.length;i++){
images[i].onclick = function() {
var that = this;
var id = that.getAttribute("data-hint");
var hint = document.getElementById("hint-" + id);
hint.className = "show";
};
}
};
</script>
</body>
</html>

one button two if statements for a css div in javascript

If I use two buttons it works fine now I wonder if I could use just one and how, this is the code for two buttons however I want to use only one button to execute the code that changes the style of the div, for instance the buttons code that I wrote is:
<title></title>
<style>#ok{width:100px;height:100px;background-color:black;}</style>
</head>
<body>
<div id="ok">ok</div>
<button id="a">on</button>
<button id="b">off</button>
<script>
var a=document.querySelector("#a");
var b=document.getElementById("ok");
a.addEventListener("click",k,false);
var c=document.querySelector("#b");
c.addEventListener("click",g,false);
function k(){
b.style.backgroundColor="yellow";
};
function g(){
b.style.backgroundColor="black";
};
</script>
I think what do you want to do is:
document.querySelector("#a").addEventListener("click", k, false);
function k() {
var a = document.querySelector("#a");
var ok = document.getElementById("ok");
if(ok.style.backgroundColor=="yellow"){
a.innerHTML = "on";
ok.style.backgroundColor = "black";
}
else{
a.innerHTML = "off";
ok.style.backgroundColor = "yellow";
}
};
This your working DEMO.

Change image in button on click

I've got a button with an image inside that I want to swap when clicked. I got that part working, but now I also want it to change back to the original image when clicked again.
The code I'm using:
<button onClick="action();">click me<img src="images/image1.png" width="16px" id="ImageButton1"></button>
And the Javascript:
function action() {
swapImage('images/image2.png');
};
var swapImage = function(src) {
document.getElementById("ImageButton1").src = src;
}
Thanks in advance!
While you could use a global variable, you don't need to. When you use setAttribute/getAttribute, you add something that appears as an attrib in the HTML. You also need to be aware that adding a global simply adds the variable to the window or the navigator or the document object (I don't remember which).
You can also add it to the object itself (i.e as a variable that isn't visible if the html is viewed, but is visible if you view the html element as an object in the debugger and look at it's properties.)
Here's two alternatives. 1 stores the alternative image in a way that will cause it to visible in the html, the other doesn't.
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
window.addEventListener('load', mInit, false);
function mInit()
{
var tgt = byId('ImageButton1');
tgt.secondSource = 'images/image2.png';
}
function byId(e){return document.getElementById(e);}
function action()
{
var tgt = byId('ImageButton1');
var tmp = tgt.src;
tgt.src = tgt.secondSource;
tgt.secondSource = tmp;
};
function action2()
{
var tgt = byId('imgBtn1');
var tmp = tgt.src;
tgt.src = tgt.getAttribute('src2');
tgt.setAttribute('src2', tmp);
}
</script>
<style>
</style>
</head>
<body>
<button onClick="action();">click me<img src="images/image1.png" width="16px" id="ImageButton1"></button>
<br>
<button onClick="action2();">click me<img id='imgBtn1' src="images/image1.png" src2='images/image2.png' width="16px"></button>
</body>
</html>
You need to store the old value in a global variable.
For example:
var globalVarPreviousImgSrc;
var swapImage = function(src)
{
var imgBut = document.getElementById("ImageButton1");
globalVarPreviousImgSrc = imgBut.src;
imgBut.src = src;
}
Then in the action method you can check if it was equal to the old value
function action()
{
if(globalVarPreviousImgSrc != 'images/image2.png')
{
swapImage('images/image2.png');
}else{
swapImage(globalVarPreviousImgSrc);
}
}
It's not a good idea to use global variables in javascripts use a closure or object literal. You can do something like using a closure
(function(){
var clickCounter = 0;
var imgSrc1 = "src to first image";
var imgSrc2 = "src to second image"
functions swapImage (src)
{
var imgBut = document.getElementById("ImageButton1");
imgBut.src = src;
}
function action()
{
if(clickCounter === 1)
{
swapImage(imgSrc1);
--clickCounter;
}else{
swapImage(imgSrc2);
++clickCounter;
}
}
})();
(I haven't run this code though)
This nice w3documentation gives you best practices.
Check this a working example just copy paste and run-
HTML
<button onClick="action();">click me<img src="http://dummyimage.com/200x200/000000/fff.gif&text=Image+1" width="200px" id="ImageButton1"></button>
JAVASCRIPT
<script>
function action()
{
if(document.getElementById("ImageButton1").src == 'http://dummyimage.com/200x200/000000/fff.gif&text=Image+1' )
document.getElementById("ImageButton1").src = 'http://dummyimage.com/200x200/dec4ce/fff.gif&text=Image+2';
else
document.getElementById("ImageButton1").src = 'http://dummyimage.com/200x200/000000/fff.gif&text=Image+1';
}
</script>
Check this working example - http://jsfiddle.net/QVRUG/4/

Categories