Reputation: 13
Begin with a fresh plain HTML document, and only use HTML and Javascript.
Place on it the hyperlinked word ''food''
Upon clicking ''food'', it should be replaced with ''meat and vegetables''
Upon clicking ''meat'', it should be replaced with ''pork with bacon''
Upon clicking ''vegetables'', it should be replaced with ''carrots plus peas''
Upon clicking ''pork'', it should be replaced with ''tough and chewy''
Upon clicking ''tough'', it should be replaced with ''burnt and salty''
(And so on)
I've been trying to do this as far as I can, but I'm having escapecode problems.
Here is my code:
<span id="food"><a href="#" onclick="document.getElementById('food').innerHTML='<span id=\'meat\'><a href=\'#\' onclick=\'var meat = "<span id=&pork&><a href=#\ onclick=alert(2)>pork</a></span> with bacon"; document.getElementById("meat").innerHTML = meat\'>meat</a></span> and <span id=\'vegetables\'><a href=\'#\' onclick=\'var vegetables = "carrots plus peas"; document.getElementById("vegetables").innerHTML = vegetables\'>vegetables</a></span>'">food</a></span>
Here it is in action: http://jsfiddle.net/jshflynn/L6r5rrfx/
I'm sorry it's not spaced, but that threw up errors.
Notice that ''alert(2)'' has no delimiting characters around it, I don't know how to make it say alert(''Hello'').
I feel there must be some recursive way to do this, but I'm not sure.
Thanks in advance. Especially so if you can do the full problem.
Upvotes: 0
Views: 124
Reputation: 1920
Here you go, you get the idea: http://jsfiddle.net/8bhd8njh/
function bind(obj, evt, fnc) {
// W3C model
if (obj.addEventListener) {
obj.addEventListener(evt, fnc, !1);
return !0;
}
// Microsoft model
else if (obj.attachEvent) {
return obj.attachEvent('on' + evt, fnc);
}
// Browser don't support W3C or MSFT model, go on with traditional
else {
evt = 'on'+evt;
if(typeof obj[evt] === 'function'){
// Object already has a function on traditional
// Let's wrap it with our own function inside another function
fnc = (function(f1,f2){
return function(){
f1.apply(this,arguments);
f2.apply(this,arguments);
}
})(obj[evt], fnc);
}
obj[evt] = fnc;
return !0;
}
}
String.prototype.supplant = function (a, b) {
return this.replace(/{([^{}]*)}/g, function (c, d) {
return void 0!=a[d]?a[d]:b?'':c
})
};
var data = {
food : '{meat} and {vegetables}',
meat : '{pork} and {beef}',
pork : '{tough} and {chewy}',
tough : '{burnt} and {salty}',
vegetables : '{carrots} and {peas}'
};
var classname = 'game-clickable';
var init = function(obj, data) {
var template = '<span class="{classname}">{text}</span>';
obj.innerHTML = obj.innerHTML.replace(/{([^{}]*)}/g, function(a,b) {
return template.supplant({
classname : data[b] ? classname : '',
text : b
}, !0)
});
var objects = document.getElementsByClassName('game-clickable');
for (var i = 0; i < objects.length; i++) {
bind(objects[i], 'click', (function(o) {
return function() {
if (!data[o.innerHTML]) {
return;
}
var parent = o.parentNode;
var span = document.createElement('SPAN');
span.innerHTML = data[o.innerHTML];
parent.insertBefore(span, o);
parent.removeChild(o);
init(parent, data);
}
})(objects[i]));
}
};
init(document.getElementById('word-game'), data);
.game-clickable {
cursor: pointer;
text-decoration: underline;
}
<div id="word-game">
{food}
</div>
Upvotes: 1
Reputation: 10924
I think you are looking for something like the following:
var replacements = {
"food" : "meat and vegetables",
"meat" : "pork with bacon",
"vegetables" : "carrots plus peas",
"pork" : "tough and chewy",
"tough" : "burnt and salty"
};
function replaceAnchor(a) {
var elementType = "";
var lastElementType = "";
var target = a.innerHTML;
var replacement = replacements[target];
var words = replacement.split(' ');
var newElement = {};
for(var i = 0; i < words.length; i++) {
var word = words[i];
if (replacements[word]) {
elementType = "a";
} else {
elementType = "span";
}
if (elementType === "a" || elementType != lastElementType) {
newElement = document.createElement(elementType);
if (elementType === "a") {
newElement.onclick = function(e) {
replaceAnchor(this);
e.preventDefault();
};
}
a.parentNode.insertBefore(newElement, a);
}
if (elementType == "span") {
newElement.innerHTML = newElement.innerHTML + " " + word + " ";
} else {
newElement.innerHTML += word;
}
lastElementType = elementType;
}
a.parentElement.removeChild(a);
return false;
}
a {
text-decoration : underline;
color : blue;
cursor: pointer;
}
<a onclick="return replaceAnchor(this);">food</a>
Upvotes: 1