my code lists items from an rss feed onto an html page. although, the java script is a little finicky. it won't read some xml feeds, usually the feeds containing list items over 25. I just need another set of eyes to take a look at the code and tell me if i'm missing something obvious.
.js file-----------------------------------------------
//XML CODE
var http_request = false;
var dataFileName = new Array();
dataFileName[1] = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/americas/rss.xml";
//dataFileName[2] = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/uk_news/magazine/rss.xml";
//dataFileName[3] = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/business/rss.xml";
function getData(dataFileIndex) {
if (window.ActiveXObject) { //IE
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) { //other
http_request = new XMLHttpRequest();
} else {
alert("your browser does not support AJAX");
}
http_request.open("GET",dataFileName[dataFileIndex],true);
http_request.setRequestHeader("Cache-Control", "no-cache");
http_request.setRequestHeader("Pragma", "no-cache");
http_request.onreadystatechange = function() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
if (http_request.responseText != null) {
processRSS(http_request.responseXML);
} else {
alert("Failed to receive RSS file from the server - file not found.");
return false;
}
}
}
}
http_request.send(null);
}
function processRSS(rssxml) {
RSS = new RSS2Channel(rssxml);
outputData(RSS);
}
function RSS2Channel(rssxml) {
this.items = new Array();
var itemElements = rssxml.getElementsByTagName("item");
for (var i=0; i<itemElements.length; i++) {
Item = new RSS2Item(itemElements[i]);
this.items.push(Item);
}
}
function RSS2Item(itemxml) {
this.title;
this.link;
this.description;
this.pubDate;
this.guid;
var properties = new Array("title", "link", "description", "pubDate", "guid");
var tmpElement = null;
for (var i=0; i<properties.length; i++) {
tmpElement = itemxml.getElementsByTagName(properties[i])[0];
if (tmpElement != null) {
eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
}
}
}
function outputData(RSS) {
dataString = "";
for (var i=0; i<RSS.items.length; i++) {
dataString += "<div class='itemBlock'>";
newDate = new Date(RSS.items[i].pubDate);
dateString = (newDate.getMonth()+1) + "/" + newDate.getDate() + "/" + newDate.getFullYear();
dataString += "<div class='itemDate'>" + dateString + "</div>";
dataString += "<div class='itemTitle'><a href='" + RSS.items[i].link + "' target='afps_news'>" + RSS.items[i].title + "</a></div>";
//dataString += "<div class='itemDescription'>" + RSS.items[i].description + "</div>";
dataString += "</div>";
}
document.getElementById('outputBlock').innerHTML = dataString;
}
//SCROLL BAR CODE
var ie=document.all;
var nn6=document.getElementById&&!document.all;
var isdrag=false;
var x,y;
var dobj;
var scrollPercent;
var boxTop;
var maxHeight;
var toppoint;
function movemouse(e) {
if (isdrag) {
//dobj.style.left = nn6 ? tx + e.clientX - x : tx + event.clientX - x;
toppoint = (nn6) ? ty + e.clientY - y : ty + event.clientY - y;
boxTop = parseInt(document.getElementById('scrollBarBox').style.top) - scrollBarBoxOffset;
if (toppoint < boxTop) toppoint = boxTop;
boxHeight = parseInt(document.getElementById('scrollBarBox').style.height);
maxHeight = boxTop + boxHeight - parseInt(document.getElementById('scrollBar').style.height);
if (toppoint > maxHeight) toppoint = maxHeight;
dobj.style.top = toppoint + "px";
scrollPercent = toppoint / maxHeight;
document.getElementById('textWindow').style.top = parseInt(0 - (document.getElementById('textWindow').offsetHeight - parseInt(document.getElementById('scrollBarBox').style.height)) * scrollPercent );
return false;
}
}
function selectmouse(e) {
var fobj = nn6 ? e.target : event.srcElement;
var topelement = nn6 ? "HTML" : "BODY";
while (fobj.tagName != topelement && fobj.className != "dragme") {
fobj = nn6 ? fobj.parentNode : fobj.parentElement;
}
if (fobj.className == "dragme") {
isdrag = true;
dobj = fobj;
//tx = parseInt(dobj.style.left + 0);
ty = parseInt(dobj.style.top + 0);
//x = nn6 ? e.clientX : event.clientX;
y = nn6 ? e.clientY : event.clientY;
document.onmousemove = movemouse;
return false;
}
}
document.onmousedown = selectmouse;
document.onmouseup = new Function("isdrag=false;");
html file-------------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>TEST</TITLE>
<META http-equiv=Content-Type content="text/html; charset=windows-1252">
<SCRIPT src="script1.js"></SCRIPT>
<STYLE>BODY {
MARGIN: 0px; FONT: 8pt arial
}
#widgetBody {
BACKGROUND-Color:gray; WIDTH: 240px; POSITION: relative; HEIGHT: 299px
}
#textWindowBox {
LEFT: 63px; OVERFLOW: hidden; WIDTH: 152px; POSITION: absolute; TOP: 70px; HEIGHT: 221px
}
#textWindow {
PADDING-TOP: 7px; POSITION: relative
}
#scrollBarBox {
LEFT: 221px; WIDTH: 12px; POSITION: absolute; TOP: 74px; HEIGHT: 216px
}
#scrollBar {
BACKGROUND: url(images/widget_scroll-handle1.gif) no-repeat; WIDTH: 12px; POSITION: relative; HEIGHT: 40px
}
#defenseLinkLink {
LEFT: 4px; WIDTH: 20px; CURSOR: pointer; POSITION: absolute; TOP: 155px; HEIGHT: 140px; BACKGROUND-COLOR: transparent
}
#defenseLinkLink A {
DISPLAY: block; WIDTH: 20px; HEIGHT: 140px
}
.dragme {
POSITION: relative
}
.itemBlock {
PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 4px; MARGIN: 0px 0px 3px; PADDING-TOP: 0px; BORDER-BOTTOM: #adafb3 1px dotted
}
.itemDate {
FONT-SIZE: 0.9em; COLOR: #666; LINE-HEIGHT: 1.1em
}
.itemTitle {
FONT-WEIGHT: bold; LINE-HEIGHT: 1.1em
}
.itemTitle A {
COLOR: #254a7d; TEXT-DECORATION: none
}
.itemDescription {
}
</STYLE>
<SCRIPT>
var scrollBarBoxOffset = 74;
function init() {
document.getElementById('scrollBarBox').style.top = "74px";
document.getElementById('scrollBarBox').style.height = "216px";
document.getElementById('scrollBar').style.height = "40px";
}
</SCRIPT>
<META content="MSHTML 6.00.6001.18294" name=GENERATOR></HEAD>
<BODY onload=init()>
<DIV id=widgetBody>
<DIV id=textWindowBox>
<DIV id=textWindow>
<DIV id=outputBlock></DIV></DIV></DIV>
<DIV id=scrollBarBox>
<DIV class=dragme id=scrollBar></DIV></DIV>
<DIV style="CLEAR: both"></DIV></DIV>
<SCRIPT language=javaScript>getData(2)</SCRIPT>
</BODY></HTML>
Ok, got it working.
2 issues.
army.mil does not resolve! Please use "www.army.mil" instead.
IN RSS2Item replace this line:
if (tmpElement != null) {
with this:
if (tmpElement != null && tmpElement.childNodes[0]) {
Oh man, why are you using XMLHttpRequest directly? Use a library for that, and make your life easier :)
You could be running into cross-site scripting security problems. If the RSS feeds exist on a different domain than the page running the JavaScript, the browser will not let your JavaScript make the requests.
dataFileName[1] = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/americas/rss.xml";
Unless you are (a) a script running from the BBC, or (b) a browser extension, you cannot make an XMLHttpRequest to that server.
dataString += "<div class='itemTitle'><a href='" + RSS.items[i].link
HTML/script injection. If you insist on rolling innerHTML instead of using simple DOM methods you must do HTML escaping to turn <&" into <&".
eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
Don't use eval, except in the very few unusual cases you need it. This isn't one of them; you can access a JavaScript property by name using:
this[properties[i]]= tmpElement.firstChild.data;
Also, and this is probably where the unreliability is coming in, you can't be sure there will be a single child Text node. If there is no content in that element, firstChild/childNodes[0] will not exist and you will get an exception. If there is complex content in the element (which normally there shouldn't be, but for RSS 0.9 there can be as unencoded HTML), firstChild.nodeValue won't contain the text content of the element. Instead you would have to walk over the Text node descendents gathering their nodeValue/data.
Related
When the right arrow key is pressed I would like to increment the left position of a div by 10px using the style property. Here is my script and what I've tried so far:
document.onkeydown = KeyPressed;
function KeyPressed(k) {
var LeftBtn = 37;
var RightBtn = 39;
var UpBtn = 38;
var DownBtn = 40;
if (k.keyCode == RightBtn) {
document.getElementById("test").style.left = document.getElementById("test").style.left + 10px;
}
}
#test {
position: relative;
left: 0px;
width: 25px;
height: 80px;
background-color: black;
}
<div id="test"></div>
The style property of a DOM element is essentially a dictionary with string key-value pairs. It expects a CSS key, and a proper string value.
Your current code comes out as left: 10px10px and that doesn't make much sense for CSS.
In order for this to work, you'd have to regard the px.
document.onkeydown = KeyPressed;
function KeyPressed(k) {
var LeftBtn = 37;
var RightBtn = 39;
var UpBtn = 38;
var DownBtn = 40;
if (k.keyCode == RightBtn) {
var moveEl = document.getElementById("test"),
currLeft = parseInt(moveEl.style.left || 0);
moveEl.style.left = (currLeft + 10) + 'px';
}
}
#test {
position: relative;
left: 0px;
width: 25px;
height: 80px;
background-color: black;
}
<div id="test"></div>
Further reading and examples - HTMLElement.style
Remove px from 10.
if (k.keyCode == RightBtn) {
document.getElementById("test").style.left = document.getElementById("test").style.left + 10;
}
Try following way:
document.onkeydown = KeyPressed;
function KeyPressed(k) {
var LeftBtn = 37;
var RightBtn = 39;
var UpBtn = 38;
var DownBtn = 40;
if(k.keyCode == RightBtn) {
document.getElementById("test").style.left = parseInt(document.getElementById("test").style.left || 0) + 10 + 'px';
}
}
In my AngularJS application I am attempting to add a Facebook Native Web Ad to one of my views. I followed the steps outlined in the documentation to generate the necessary HTML snippet and added this to my view.
My application is using ui-router to resolve routes. When visiting the route/view containing this code snippet the FB ad is not displayed and neither of the callbacks are invoked (onAdLoaded or onAdError).
Facebook Generated HTML Snippet (added to view):
<div style="display:none; position: relative;">
<iframe style="display:none;"></iframe>
<script type="text/javascript">
var data = {
placementid: 'xxxxxxxxxxx_xxxxxxxx',
format: 'native',
testmode: true,
onAdLoaded: function (element) {
console.log('Audience Network ad loaded');
element.style.display = 'block';
},
onAdError: function (errorCode, errorMessage) {
console.log('Audience Network error (' + errorCode + ') ' + errorMessage);
}
};
(function (w, l, d, t) {
var a = t();
var b = d.currentScript || (function () {
var c = d.getElementsByTagName('script');
return c[c.length - 1];
})();
var e = b.parentElement;
e.dataset.placementid = data.placementid;
var f = function (v) {
try {
return v.document.referrer;
} catch (e) {
}
return '';
};
var g = function (h) {
var i = h.indexOf('/', h.indexOf('://') + 3);
if (i === -1) {
return h;
}
return h.substring(0, i);
};
var j = [l.href];
var k = false;
var m = false;
if (w !== w.parent) {
var n;
var o = w;
while (o !== n) {
var h;
try {
m = m || (o.$sf && o.$sf.ext);
h = o.location.href;
} catch (e) {
k = true;
}
j.push(h || f(n));
n = o;
o = o.parent;
}
}
var p = l.ancestorOrigins;
if (p) {
if (p.length > 0) {
data.domain = p[p.length - 1];
} else {
data.domain = g(j[j.length - 1]);
}
}
data.url = j[j.length - 1];
data.channel = g(j[0]);
data.width = screen.width;
data.height = screen.height;
data.pixelratio = w.devicePixelRatio;
data.placementindex = w.ADNW && w.ADNW.Ads ? w.ADNW.Ads.length : 0;
data.crossdomain = k;
data.safeframe = !!m;
var q = {};
q.iframe = e.firstElementChild;
var r = 'https://www.facebook.com/audiencenetwork/web/?sdk=5.3';
for (var s in data) {
q[s] = data[s];
if (typeof(data[s]) !== 'function') {
r += '&' + s + '=' + encodeURIComponent(data[s]);
}
}
q.iframe.src = r;
q.tagJsInitTime = a;
q.rootElement = e;
q.events = [];
w.addEventListener('message', function (u) {
if (u.source !== q.iframe.contentWindow) {
return;
}
u.data.receivedTimestamp = t();
if (this.sdkEventHandler) {
this.sdkEventHandler(u.data);
} else {
this.events.push(u.data);
}
}.bind(q), false);
q.tagJsIframeAppendedTime = t();
w.ADNW = w.ADNW || {};
w.ADNW.Ads = w.ADNW.Ads || [];
w.ADNW.Ads.push(q);
w.ADNW.init && w.ADNW.init(q);
})(window, location, document, Date.now || function () {
return +new Date;
});
</script>
<script type="text/javascript" src="https://connect.facebook.net/en_US/fbadnw.js" async></script>
<style>
.thirdPartyRoot {
background-color: white;
color: #444;
border: 1px solid #ccc;
border-left: 0;
border-right: 0;
font-family: sans-serif;
font-size: 14px;
line-height: 16px;
width: 320px;
text-align: left;
position: relative;
}
.thirdPartyMediaClass {
width: 320px;
height: 168px;
margin: 12px 0;
}
.thirdPartySubtitleClass {
font-size: 18px;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
height: 16px;
-webkit-box-orient: vertical;
}
.thirdPartyTitleClass {
padding-right: 12px;
line-height: 18px;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
height: 36px;
-webkit-box-orient: vertical;
}
.thirdPartyCallToActionClass {
background-color: #416BC4;
color: white;
border-radius: 4px;
padding: 6px 20px;
float: right;
text-align: center;
text-transform: uppercase;
font-size: 11px;
}
.fbDefaultNativeAdWrapper {
font-size: 12px;
line-height: 14px;
margin: 12px 0;
height: 36px;
vertical-align: top;
}
</style>
<div class="thirdPartyRoot">
<a class="fbAdLink">
<div class="fbAdMedia thirdPartyMediaClass"></div>
<div class="fbAdSubtitle thirdPartySubtitleClass"></div>
<div class="fbDefaultNativeAdWrapper">
<div class="fbAdCallToAction thirdPartyCallToActionClass"></div>
<div class="fbAdTitle thirdPartyTitleClass"></div>
</div>
</a>
</div>
</div>
I noticed that the Facebook Audience Network JS is loaded asynchronously and suspected that I might have a race condition causing the issue.
<script type="text/javascript" src="https://connect.facebook.net/en_US/fbadnw.js" async></script>
To test this, I've moved the FB code snippet out of my view and into my SPA index.html. The ad appears as expected. What callback does the fbadnw.js script call once the script is loaded? Is the closure within the FB generated code being invoked before fbadnw.js is loaded perhaps?
index.html (works)
<!DOCTYPE html>
<html ng-app="kcl-app">
<head>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title ng-bind="pageTitle"></title>
</head>
<body>
<!-- ui-router view -->
<div ui-view></div>
<!-- FB Begin -->
<div class="fb-native">
<div style="display:none; position: relative;">
<iframe style="display:none;"></iframe>
<script type="text/javascript">
var data = {
placementid: 'xxxxxxxxxxx_xxxxxxxx',
format: 'native',
testmode: true,
onAdLoaded: function (element) {
console.log('Audience Network ad loaded');
element.style.display = 'block';
},
onAdError: function (errorCode, errorMessage) {
console.log('Audience Network error (' + errorCode + ') ' + errorMessage);
}
};
(function (w, l, d, t) {
var a = t();
var b = d.currentScript || (function () {
var c = d.getElementsByTagName('script');
return c[c.length - 1];
})();
var e = b.parentElement;
e.dataset.placementid = data.placementid;
var f = function (v) {
try {
return v.document.referrer;
} catch (e) {
}
return '';
};
var g = function (h) {
var i = h.indexOf('/', h.indexOf('://') + 3);
if (i === -1) {
return h;
}
return h.substring(0, i);
};
var j = [l.href];
var k = false;
var m = false;
if (w !== w.parent) {
var n;
var o = w;
while (o !== n) {
var h;
try {
m = m || (o.$sf && o.$sf.ext);
h = o.location.href;
} catch (e) {
k = true;
}
j.push(h || f(n));
n = o;
o = o.parent;
}
}
var p = l.ancestorOrigins;
if (p) {
if (p.length > 0) {
data.domain = p[p.length - 1];
} else {
data.domain = g(j[j.length - 1]);
}
}
data.url = j[j.length - 1];
data.channel = g(j[0]);
data.width = screen.width;
data.height = screen.height;
data.pixelratio = w.devicePixelRatio;
data.placementindex = w.ADNW && w.ADNW.Ads ? w.ADNW.Ads.length : 0;
data.crossdomain = k;
data.safeframe = !!m;
var q = {};
q.iframe = e.firstElementChild;
var r = 'https://www.facebook.com/audiencenetwork/web/?sdk=5.3';
for (var s in data) {
q[s] = data[s];
if (typeof(data[s]) !== 'function') {
r += '&' + s + '=' + encodeURIComponent(data[s]);
}
}
q.iframe.src = r;
q.tagJsInitTime = a;
q.rootElement = e;
q.events = [];
w.addEventListener('message', function (u) {
if (u.source !== q.iframe.contentWindow) {
return;
}
u.data.receivedTimestamp = t();
if (this.sdkEventHandler) {
this.sdkEventHandler(u.data);
} else {
this.events.push(u.data);
}
}.bind(q), false);
q.tagJsIframeAppendedTime = t();
w.ADNW = w.ADNW || {};
w.ADNW.Ads = w.ADNW.Ads || [];
w.ADNW.Ads.push(q);
w.ADNW.init && w.ADNW.init(q);
})(window, location, document, Date.now || function () {
return +new Date;
});
</script>
<script type="text/javascript" src="https://connect.facebook.net/en_US/fbadnw.js" async></script>
<style>
.thirdPartyRoot {
background-color: white;
color: #444;
border: 1px solid #ccc;
border-left: 0;
border-right: 0;
font-family: sans-serif;
font-size: 14px;
line-height: 16px;
width: 320px;
text-align: left;
position: relative;
}
.thirdPartyMediaClass {
width: 320px;
height: 168px;
margin: 12px 0;
}
.thirdPartySubtitleClass {
font-size: 18px;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
height: 16px;
-webkit-box-orient: vertical;
}
.thirdPartyTitleClass {
padding-right: 12px;
line-height: 18px;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
height: 36px;
-webkit-box-orient: vertical;
}
.thirdPartyCallToActionClass {
background-color: #416BC4;
color: white;
border-radius: 4px;
padding: 6px 20px;
float: right;
text-align: center;
text-transform: uppercase;
font-size: 11px;
}
.fbDefaultNativeAdWrapper {
font-size: 12px;
line-height: 14px;
margin: 12px 0;
height: 36px;
vertical-align: top;
}
</style>
<div class="thirdPartyRoot">
<a class="fbAdLink">
<div class="fbAdMedia thirdPartyMediaClass"></div>
<div class="fbAdSubtitle thirdPartySubtitleClass"></div>
<div class="fbDefaultNativeAdWrapper">
<div class="fbAdCallToAction thirdPartyCallToActionClass"></div>
<div class="fbAdTitle thirdPartyTitleClass"></div>
</div>
</a>
</div>
</div>
</div>
<!-- FB End -->
</body>
</html>
I was able to resolve this issue by editing the boilerplate code provided by FB. In a nutshell, the provided closure (minified) attempts to:
Locate the iframe element where the Ad will be rendered and set it's
src and other attributes.
Attach an event handler to listen for post messages "message".
Initialize the Ad with FB Audience Network (ADNW.init())
My problem was with the assumptions this code makes in Step 1.
var b = d.currentScript || (function() {
var c = d.getElementsByTagName('script');
return c[c.length - 1];
})();
var e = b.parentElement;
The above code is attempting to locate this DIV.
<div style="display:none; position: relative;">
It does this by first trying to locate the parent of the last script element on the page. This is brittle and, in my case, did not work. The last script element added in my document was not the one this code expected.
I modified this code to explicitly select the correct element by ID.
Added an ID to containing DIV:
<div id="fb-ad-container" style="display:none; position: relative;">
Simplify the DOM parsing code (step 1) to select this DIV by ID:
var e = d.getElementById("fb-ad-container");
By selecting the correct element by ID I was able to alleviate the need to locate the current script element. The rest of the script ran as expected.
Im trying to create a program for one of my games(details not needed) nevertheless I can move around aside elements written in the code
<aside draggable="true" class="dragme" data-item="0">One</aside>
but if I create it at runtime(via button click) it gives me this error in the console
Uncaught TypeError: Cannot read property 'style' of undefined
Here is my full code anybody have ideas?
<!DOCTYPE HTML>
<html>
<head>
<style>
aside {
position: absolute;
left: 0;
top: 0;
width: 200px;
background: rgba(255, 255, 255, 1);
border: 2px solid rgba(0, 0, 0, 1);
border-radius: 4px;
padding: 8px;
}
.second {
left: 100px;
top: 100px;
}
body, html {
min-height: 100vh;
}
body{
width:700px;
height:700px;
}
</style>
</head>
<body ondragover="drag_over(event)" ondrop="drop(event)">
<div class="ControlPanel">
<button onclick="CreateNew('item1')">Item1</button>
</div>
<aside draggable="true" class="dragme" data-item="0">One</aside>
<script>
var dataNum = 0;
function CreateNew(item){
if(item == "item1"){
dataNum += 1;
var asi = document.createElement("ASIDE");
asi.setAttribute("draggable",true);
asi.setAttribute("class","dragme second");
asi.setAttribute("data-item",dataNum);
asi.setAttribute("style","left: 347px; top: 82px;");
document.body.appendChild(asi);
}
}
function drag_start(event) {
var style = window.getComputedStyle(event.target, null);
event.dataTransfer.setData("text/plain", (parseInt(style.getPropertyValue("left"), 10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"), 10) - event.clientY) + ',' + event.target.getAttribute('data-item'));
}
function drag_over(event) {
event.preventDefault();
return false;
}
function drop(event) {
var offset = event.dataTransfer.getData("text/plain").split(',');
var dm = document.getElementsByClassName('dragme');
dm[parseInt(offset[2])].style.left = (event.clientX + parseInt(offset[0], 10)) + 'px';
dm[parseInt(offset[2])].style.top = (event.clientY + parseInt(offset[1], 10)) + 'px';
event.preventDefault();
return false;
}
var dm = document.getElementsByClassName('dragme');
for (var i = 0; i < dm.length; i++) {
dm[i].addEventListener('dragstart', drag_start, false);
document.body.addEventListener('dragover', drag_over, false);
document.body.addEventListener('drop', drop, false);
}
</script>
</body>
</html>
You are registering the event listener only once during the page load. Therefore, when you create a new element, you need to re-register the events for the newly created elements too.
<script>
var dataNum = 0;
function CreateNew(item){
if(item == "item1"){
dataNum += 1;
var asi = document.createElement("ASIDE");
asi.setAttribute("draggable",true);
asi.setAttribute("class","dragme second");
asi.setAttribute("data-item",dataNum);
asi.setAttribute("style","left: 347px; top: 82px;");
document.body.appendChild(asi);
registerDragMe(); // --> Add this
}
}
function drag_start(event) {
var style = window.getComputedStyle(event.target, null);
event.dataTransfer.setData("text/plain", (parseInt(style.getPropertyValue("left"), 10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"), 10) - event.clientY) + ',' + event.target.getAttribute('data-item'));
}
function drag_over(event) {
event.preventDefault();
return false;
}
function drop(event) {
var offset = event.dataTransfer.getData("text/plain").split(',');
var dm = document.getElementsByClassName('dragme');
dm[parseInt(offset[2])].style.left = (event.clientX + parseInt(offset[0], 10)) + 'px';
dm[parseInt(offset[2])].style.top = (event.clientY + parseInt(offset[1], 10)) + 'px';
event.preventDefault();
return false;
}
// create a wrapper function
function registerDragMe(){
var dm = document.getElementsByClassName('dragme');
for (var i = 0; i < dm.length; i++) {
dm[i].addEventListener('dragstart', drag_start, false);
document.body.addEventListener('dragover', drag_over, false);
document.body.addEventListener('drop', drop, false);
}
}
registerDragMe();
</script>
Working example : https://jsfiddle.net/jcLjr70y/
I'm making a syntax highlighter in Javascript and HTML. It works fine at the moment but I think it's really inefficient because I have an interval with a time of 0 which runs a function that loops through all of the characters in the text area and then inserts them into a div behind the text area to provide the syntax highlighting.
I think my lexer is really bad too, but at the moment I'm more concerned with the function running like a million times a second that loops through every character in the text area each time.
Can anyone please think of a more efficient way to do this?
There doesn't seem to be any performance problems but I'm not sure if it will work on a lower-powered machine because I don't want it to crash the browser tab because I want to have several on a page so I need it to be as efficient as possible.
I understand that its annoying to be given loads of code and asked to help, but I thought for the problem to be easiest to debug you'd need the entire code.
Here you code:
<html>
<head>
<title>My Syntax Highlighter</title>
<style type="text/css">
#container {
width: 100%;
height: 100%;
position: relative;
padding: 0px;
}
#code {
width: 100%;
height: 100%;
outline:none;
position: absolute;
background-color: transparent;
border: none;
font-family: Courier;
font-size: 22px;
color: rgba(0,0,0,.2) !important;
}
#codeb {
width: 100%;
height: 100%;
position: absolute;
font-family: Courier;
font-size: 22px;
padding: 2px 2px;
color: #000;
}
.keyword {
/*font-weight: bold;*/
color: #E42D82;
}
.string {
/*font-weight: bold;*/
color: #0086b3;
}
</style>
<script type="text/javascript">
function u() {
var code = document.getElementById("code");
var codeb = document.getElementById("codeb");
var c = "";
var tok = "";
var cc = 0;
var t = "";
var takeaway = 0;
var stringStarted = false;
var string = "";
for (var i = 0; i < code.value.length; i++) {
tok += code.value[i];
c += code.value[i];
cc++;
if (tok == "print") {
t = "<span class=\"keyword\">print</span>";
takeaway += 5;
c = c.substring(0, cc - takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
} else if (tok == "var") {
t = "<span class=\"keyword\">var</span>";
takeaway += 3;
c = c.substring(0, cc-takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
} else if (tok == "\"") {
tok = "";
if (stringStarted == false) {
stringStarted = true;
string += "\"";
} else {
stringStarted = false;
string += "\"";
t = "<span class=\"string\">" + string + "</span>";
takeaway += string.length;
c = c.substring(0, cc-takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
string = "";
}
tok = "";
} else if (tok == " ") {
if (stringStarted == true) {
string += " ";
}
c+= "";
tok = "";
} else {
if (stringStarted == true) {
string += code.value[i];
tok = "";
}
}
codeb.innerHTML = c;
//console.log("test");
};
//alert(string);
if (code.value == "") {
codeb.innerHTML = "";
}
clearI(setInterval(function(){ u(); }, 0));
}
function clearI(interval) {
clearInterval(interval);
}
var interval = setInterval(function(){ u(); }, 0);
</script>
</head>
<body>
<div id="container">
<div id="codeb"></div>
<textarea id="code" autofocus></textarea>
</div>
</body>
</html>
Alright, so I have been killing myself over this for a while now. I simply want to take an XML response containing names from my arduino and then dynamically create buttons. Each button needs to say the name and have the name as its id for the GetDrink function to use to send back to the arduino. If anyone can give me some help, maybe some code to work off of it would be appreciated.
I am able to have a button call the CreateButton function to create more buttons which all work. But I need to dynamically create the buttons off of the XML response. Also, this has to be done strictly using JavaScript and HTML.
<!DOCTYPE html>
<html>
<head>
<title>The AutoBar</title>
<script>
// Drinks
strDRINK1 = "";
function GetArduinoIO()
{
nocache = "&nocache=" + Math.random() * 1000000;
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (this.readyState == 4) {
if (this.status == 200) {
if (this.responseXML != null) {
var count;
var num_an = this.responseXML.getElementsByTagName('alcohol').length;
for (count = 0; count < num_an; count++) {
document.getElementsByClassName("AlcStatus")[count].innerHTML =
this.responseXML.getElementsByTagName('alcohol')[count].childNodes[0].nodeValue;
}
}
}
}
}
request.open("GET", "ajax_inputs" + strDRINK1 + nocache, true);
request.send(null);
setTimeout('GetArduinoIO()', 1000);**strong text**
strDRINK1 = "";
}
function GetDrink(clicked_id)
{
strDRINK1 = "&" + clicked_id;
document.getElementById("AlcStatus").innerHTML = "Your " + clicked_id + " is being made";
}
function CreateButton(Drink_Name)
{
myButton = document.createElement("input");
myButton.type = "button";
myButton.value = Drink_Name;
placeHolder = document.getElementById("button");
placeHolder.appendChild(myButton);
myButton.id = Drink_Name;
myButton.onclick = function()
{
strDRINK1 = "&" + myButton.id;
document.getElementById("AlcStatus").innerHTML = "Your " + myButton.id + " is being made";
}
}
</script>
<style>
.IO_box {
float: left;
margin: 0 20px 20px 0;
border: 1px solid blue;
padding: 0 5px 0 5px;
width: 320px;
}
h1 {
font-size: 320%;
color: blue;
margin: 0 0 10px 0;
}
h2 {
font-size: 200%;
color: #5734E6;
margin: 5px 0 5px 0;
}
p, form, button {
font-size: 180%;
color: #252525;
}
.small_text {
font-size: 70%;
color: #737373;
}
</style>
</head>
<body onload="GetArduinoIO()" BGCOLOR="#F5F6CE">
<p> <center><img src="pic.jpg" /></center><p>
<div class="IO_box">
<div id="button"></div>
</div>
<div class="IO_box">
<h2><span class="AlcStatus">...</span></h2>
</div>
<div>
<button onclick="location.href='Edit_Bar.htm'">Edit Bar Menu</button>
<div>
</body>
</html>
Something like this?
var xml = "<items><alcohol>Bourbon</alcohol><alcohol>Gin</alcohol><alcohol>Whiskey</alcohol></items>";
var parser = new DOMParser();
var dom = parser.parseFromString(xml, "text/xml");
var alcohol = dom.querySelectorAll('alcohol');
function getDrink(event) {
alert(event.target.value);
}
function makeButton(value) {
var b = document.createElement('button');
b.innerHTML = value;
b.value = value;
b.id = value;
b.addEventListener('click', getDrink);
return b;
}
var list = document.getElementById('buttons');
for(var i = 0; i < alcohol.length; i++ ) {
var b = makeButton(alcohol[i].firstChild.nodeValue);
var li = document.createElement('li');
li.appendChild(b);
list.appendChild(li);
}
<ul id="buttons"></ul>