I'm developing a real-time multiplayer web/browser game where players must click on words starting with a specific letter. However, it's prone to cheating as users can exploit the browser's find-in-page feature.
After researching, I discovered that preventing find-in-page is challenging. Despite implementing a solution by appending the letter "r" to each word with opacity and font-size: 0, cheating is still possible.
I'm considering a new approach: creating SVGs for each letter and mapping them to the corresponding letters in the game. This might prevent find-in-page from working effectively. Before investing significant time into this, I'd like to know if it's a viable solution. Additionally, I'm open to alternative suggestions.
Is using SVGs a practical solution to confuse find-in-page, or do you have other recommendations? I appreciate any insights.
Nice "Free Friday" Challenge
Keeping all logic client side I would:
<words-puzzle>
Web Component innerHTML<news-word>
Web Component
<span>
to make reading HTML difficult (DOM parsing will take some time..)direction:rtl
to confuse HTML readers even moreonclick
handler when the First letter matches<words-puzzle>
innerHTML with the new "messy" HTML<style>
news-word {
unicode-bidi: embed;
direction: rtl;
cursor: pointer;
}
span {
display: inline-block;
}
</style>
<words-puzzle find="a">
Web Components is a suite of different technologies allowing you to create reusable
custom elements — with their functionality encapsulated away from the rest of your
code — and utilize them in your web apps.
</words-puzzle>
<script>
customElements.define("news-word", class extends HTMLElement {
connectedCallback() {
let word = this.getAttribute("word");
let decoy = "<span></span>".repeat(666);
this.innerHTML = word.split("").reverse().map(letter => {
return decoy + `<span>${letter}</span>` + decoy;
}).join("");
this.removeAttribute("word"); // clean up!!
let puzzle = this.closest("words-puzzle");
if (puzzle.find == word[0]) {
puzzle.h3 = (++puzzle.findcount);
this.onclick = () => {
this.style.backgroundColor = "lightgreen";
puzzle.h3 = (--puzzle.findcount);
}
}
}
})
customElements.define("words-puzzle", class extends HTMLElement {
get find() {
return this.getAttribute("find")
}
set h3(cnt) {
this.querySelector("h3").innerHTML = `Click the ${cnt} words starting with the letter: ${this.find}`;
}
connectedCallback() {
this.findcount = 0;
setTimeout(() =>
this.innerHTML = `<h3></h3>` +
this.innerHTML.trim().split(" ").map(word => {
return `<span><news-word word="${word}"></news-word></span>`
}).join(" "))
}
})
</script>
Ah, now I understand what you want.
Wack in transparent letters to make Ctrl-F selection unreadable
<style>
news-word {
unicode-bidi: embed;
direction: rtl;
cursor: pointer;
}
span {
display: inline-block;
position: relative;
}
.under {
position: absolute;
right:0;
color:transparent;
}
</style>
<words-puzzle find="a">
Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps.
</words-puzzle>
<script>
customElements.define("news-word", class extends HTMLElement {
connectedCallback() {
let word = this.getAttribute("word");
this.innerHTML = word.split("").reverse().map(letter => {
return `<span>${letter}<span class="under">a</span></span>`;
}).join("");
this.removeAttribute("word"); // clean up!!
let puzzle = this.closest("words-puzzle");
if (puzzle.find == word[0]) {
puzzle.h3 = (puzzle.findcount++);
this.onclick = () => this.style.backgroundColor = "lightgreen";
}
}
})
customElements.define("words-puzzle", class extends HTMLElement {
get find() {
return this.getAttribute("find")
}
set h3(cnt) {
this.querySelector("h3").innerHTML = `Click the ${cnt} words starting with the letter: ${this.find}`;
}
connectedCallback() {
this.findcount = 0;
setTimeout(() =>
this.innerHTML = `<h3></h3>` +
this.innerHTML.trim().split(" ").map(word => {
return `<span><news-word word="${word}"></news-word></span>`
}).join(" "))
}
})
</script>