ã¦ã§ããã¼ã¸ã¯è¦åºããããã¹ãã®æ®µè½ãç»åããã¿ã³ãªã©ã®ãè¦ç´ ãã§æ§æããã¦ããããããã®è¦ç´ ã«çºçããã¤ãã³ããå¾ ã¡åããããã¨ãã§ãããã¨ãè¦ã¦ãã¾ãããä¾ãã°ããã¿ã³ã«ãªã¹ãã¼ã追å ããã¨ãã¦ã¼ã¶ã¼ããã¿ã³ãã¯ãªãã¯ããã¨ãã«å®è¡ãããã¨ãã§ãã¾ãã
ã¾ãããããã®è¦ç´ ã¯ä»ã®è¦ç´ ã®ä¸ã«ãå
¥ãåãã«ãããã¨ãã§ãã¾ããä¾ãã°ã<button>
㯠<div>
è¦ç´ ã®ä¸ã«ç½®ããã¨ãã§ãã¾ãããã®å ´åã <div>
è¦ç´ ã親è¦ç´ ã <button>
è¦ç´ ãåè¦ç´ ã¨å¼ã³ã¾ãã
ãã®ç« ã§ã¯ãã¤ãã³ãã®ãããªã³ã°ãè¦ã¦ã¿ã¾ããããã¯ã親è¦ç´ ã«ã¤ãã³ããªã¹ãã¼ã追å ããã¦ã¼ã¶ã¼ãåè¦ç´ ãã¯ãªãã¯ããã¨ãã«ç¾ãããã®ã§ãã
åæç¥è: HTMLããã³CSS ã®åºç¤ãçè§£ããããã¾ã§ã®ã¬ãã¹ã³ã§èª¬æãã JavaScript ãææ¡ãã¦ãããã¨ã å¦ç¿ææ:stopPropagation()
ã§æ¢ãããã¨ãã¤ãã³ãã®ãããªã³ã°ã«ã¤ãã¦ãä¾ãæãã¦ç´¹ä»ããå®ç¾©ãã¦ã¿ã¾ãããã
親è¦ç´ ã¸ã®ãªã¹ãã¼ã®è¨å®ãã®ãããªã¦ã§ããã¼ã¸ãããã¨ãã¾ãã
<div id="container">
<button>ãããã¯ãªãã¯</button>
</div>
<pre id="output"></pre>
ããã§ã¯ãã¿ã³ã¯å¥ã®è¦ç´ <div>
ã®ä¸ã«ããã¾ããããã§ã¯ã<div>
è¦ç´ ã¯ããããæ ¼ç´ããè¦ç´ ã®è¦ªã§ããã¨è¨ãã¾ãã親è¦ç´ ã«ã¯ãªãã¯ã¤ãã³ããã³ãã©ã¼ã追å ãããã¿ã³ãã¯ãªãã¯ããã¨ã©ããªãã§ããããï¼
const output = document.querySelector("#output");
function handleClick(e) {
output.textContent += `${e.currentTarget.tagName} è¦ç´ ãã¯ãªãã¯ãã¾ãã\n`;
}
const container = document.querySelector("#container");
container.addEventListener("click", handleClick);
ã¦ã¼ã¶ã¼ããã¿ã³ãã¯ãªãã¯ããã¨ã親ã®ã¯ãªãã¯ã¤ãã³ããçºçãããã¨ãåããã¾ãã
DIV è¦ç´ ãã¯ãªãã¯ãã¾ãã
ããã§ããã®ãã¿ã³ã¯ <div>
ã®ä¸ã«ããã®ã§ããã¿ã³ãã¯ãªãã¯ããã¨ããã®ä¸ã«ããè¦ç´ ãæé»ã®ãã¡ã«ã¯ãªãã¯ãããã¨ã«ãªããã¨ãåããã¾ãã
ãã¿ã³ã¨ãã®è¦ªã«ã¤ãã³ããªã¹ãã¼ã追å ãããã©ããªãã§ããããï¼
<body>
<div id="container">
<button>ãããã¯ãªãã¯</button>
</div>
<pre id="output"></pre>
</body>
ãã¿ã³ã¨ãã®è¦ª (<div>
)ãããã¦ä¸¡æ¹ãæ ¼ç´ãã <body>
è¦ç´ ã«ã¯ãªãã¯ã¤ãã³ããã³ãã©ã¼ã追å ãã¦ã¿ã¾ãããã
const output = document.querySelector("#output");
function handleClick(e) {
output.textContent += `${e.currentTarget.tagName} è¦ç´ ãã¯ãªãã¯ãã¾ãã\n`;
}
const container = document.querySelector("#container");
const button = document.querySelector("button");
document.body.addEventListener("click", handleClick);
container.addEventListener("click", handleClick);
button.addEventListener("click", handleClick);
ã¦ã¼ã¶ã¼ããã¿ã³ãã¯ãªãã¯ããã¨ã 3 ã¤ã®è¦ç´ ãã¹ã¦ã§ã¯ãªãã¯ã¤ãã³ããçºè¡ããããã¨ãåããã¾ãã
BUTTON è¦ç´ ãã¯ãªãã¯ãã¾ãã DIV è¦ç´ ãã¯ãªãã¯ãã¾ãã BODY è¦ç´ ãã¯ãªãã¯ãã¾ãã
ãã®å ´åã¯æ¬¡ã®ããã«ãªãã¾ãã
<div>
è¦ç´ ï¼ã®ã¯ãªãã¯ãç¶ãã¾ãã<div>
è¦ç´ ã®è¦ªï¼<body>
è¦ç´ ï¼ã®ã¯ãªãã¯ãç¶ãã¾ãããã®ãã¨ããã¯ãªãã¯ãããæãå å´ã®è¦ç´ ããã¤ãã³ããããã«ã¢ããããã¨è¨ãã¾ãã
ãã®åä½ã¯æçãªãã¨ãããã°ãäºæãã¬åé¡ãçºçããããã¨ãããã¾ãããã®ç¯ã§ã¯ããã®åä½ãå¼ãèµ·ããåé¡ãè¦ã¦ã解決çãæ¢ãã¾ãã
åç»ãã¬ã¤ã¤ã¼ã®ä¾ãã®ä¾ã§ã¯ãæåã¯é表示ã«ãªã£ã¦ããåç»ã¨ããåç»ã表示ãã¨è¡¨ç¤ºããããã¿ã³ããã¼ã¸ã«ããã¾ãã以ä¸ã®ããã«æä½ãããã¨æãã¾ãã
HTML ã¯ãã®ããã«ãªãã¾ãã
<button>åç»ã表示</button>
<div class="hidden">
<video>
<source
src="/shared-assets/videos/flower.webm"
type="video/webm" />
<p>
ãã®ãã©ã¦ã¶ã¼ã¯ HTML ã®åç»ã«å¯¾å¿ãã¦ãã¾ããã
代ããã«<a href="rabbit320.mp4">åç»ã¸ã®ãªã³ã¯</a>ãããã¾ãã
</p>
</video>
</div>
以ä¸ã®ãã®ãããã¾ãã
<button>
è¦ç´ <div>
è¦ç´ ã§ãåæç¶æ
ã§ã¯ class="hidden"
屿§ããã<video>
è¦ç´ ï¼<div>
è¦ç´ ã®ä¸ã«ããï¼CSS ã使ç¨ãã¦ã"hidden"
ã¯ã©ã¹ãè¨å®ããè¦ç´ ãé表示ã«ãã¦ãã¾ãã
div {
width: 100%;
height: 100%;
background-color: #eee;
}
.hidden {
display: none;
}
div video {
padding: 40px;
display: block;
width: 400px;
margin: 40px auto;
}
JavaScript ã¯ãã®ããã«ãªãã¾ãã
const btn = document.querySelector("button");
const box = document.querySelector("div");
const video = document.querySelector("video");
btn.addEventListener("click", () => box.classList.remove("hidden"));
video.addEventListener("click", () => video.play());
box.addEventListener("click", () => box.classList.add("hidden"));
ãã㯠3 ã¤ã® 'click'
ã¤ãã³ããªã¹ãã¼ã追å ãã¾ãã
<button>
ã§ããã㯠<video>
ãæ ¼ç´ãã <div>
ã表示ããã¾ãã<video>
ã§ãããã¯åç»ã®åçãå§ãããã®ã§ãã<div>
ã§ãåç»ãé表示ã«ãã¾ãããããã©ã®ããã«åä½ããã®ãè¦ã¦ã¿ã¾ãããã
ãã¿ã³ãã¯ãªãã¯ããã¨ãããã¯ã¹ã¨ã³ã³ããã¼ãã®ãã®ã表示ããã¾ããããããåç»ãã¯ãªãã¯ããã¨ãåç»ã®åçã¯å§ã¾ãã¾ãããããã¯ã¹ã¯åã³é表示ã«ãªãã¾ãã
åç»ã¯ <div>
ã®ä¸ã«ããããã®ä¸é¨ãªã®ã§ãåç»ãã¯ãªãã¯ããã¨ä¸¡æ¹ã®ã¤ãã³ããã³ãã©ã¼ãå®è¡ããããã®ãããªåä½ãçºçãã¾ãã
åã®ç¯ã§è¦ãããã«ãã¤ãã³ãã®ãããªã³ã°ã¯æã«åé¡ãå¼ãèµ·ãããã¨ãããã¾ããããããé²ãæ¹æ³ãããã¾ãã Event
ãªãã¸ã§ã¯ãã«ã¯ stopPropagation()
ã¨ãã颿°ããããã¤ãã³ããã³ãã©ã¼å
ã§å¼ã³åºãããã¨ããã®ã¤ãã³ããä»ã®è¦ç´ ã«ãããªã³ã°ããã®ãé²ãã¾ãã
JavaScript ãæ¬¡ã®ããã«å¤æ´ãããã¨ã§ãç¾å¨ã®åé¡ãä¿®æ£ãããã¨ãã§ãã¾ãã
const btn = document.querySelector("button");
const box = document.querySelector("div");
const video = document.querySelector("video");
btn.addEventListener("click", () => box.classList.remove("hidden"));
video.addEventListener("click", (event) => {
event.stopPropagation();
video.play();
});
box.addEventListener("click", () => box.classList.add("hidden"));
ããã§ãã£ã¦ãããã¨ã¯ã<video>
è¦ç´ ã® 'click'
ã¤ãã³ããã³ãã©ã¼ã®ã¤ãã³ããªãã¸ã§ã¯ãã«å¯¾ã㦠stopPropagation()
ãå¼ã³åºãã¦ããã ãã§ããããã«ããããã®ã¤ãã³ããããã¯ã¹ã¾ã§ä¸ãã£ã¦ããã®ãæ¢ãããã¨ãã§ãã¾ããããã§ããã¿ã³ã¨åç»ã®ä¸¡æ¹ãã¯ãªãã¯ãã¦ã¿ã¦ãã ããã
<button>åç»ã表示</button>
<div class="hidden">
<video>
<source
src="/shared-assets/videos/flower.webm"
type="video/webm" />
<p>
ãã®ãã©ã¦ã¶ã¼ã¯ HTML ã®åç»ã«å¯¾å¿ãã¦ãã¾ããã
代ããã«<a href="rabbit320.mp4">åç»ã¸ã®ãªã³ã¯</a>ãããã¾ãã
</p>
</video>
</div>
div {
width: 100%;
height: 100%;
background-color: #eee;
}
.hidden {
display: none;
}
div video {
padding: 40px;
display: block;
width: 400px;
margin: 40px auto;
}
ã¤ãã³ãã®ãã£ããã£
ã¤ãã³ã伿ã®å¥ã®å½¢æ ã¨ãã¦ããã¤ãã³ããã£ããã£ããããã¾ããããã¯ã¤ãã³ããããªã³ã°ã®ãããªãã®ã§ãããé åºãéã«ãªãã¾ããã¤ã¾ããã¤ãã³ãã¯å¯¾è±¡ã¨ãªãæãå å´ã®è¦ç´ ã§æåã«çºçãããã®å¾ãå ¥ãåã®è¦ç´ ãæµ ããªã£ã¦ããã®ã§ã¯ãªããã¤ãã³ãã¯æãå ¥ãåã®æµ ãè¦ç´ ã§æåã«çºçãããã®å¾ã対象ã¨ããè¦ç´ ã«éããã¾ã§ãå ¥ãåã®è¦ç´ ãæ·±ããªã£ã¦ããã¾ãã
ã¤ãã³ãã®ãã£ããã£ã¯æ¢å®ã§ã¯ç¡å¹ã§ããæå¹ã«ããã«ã¯ addEventListener()
ã§ capture
ãªãã·ã§ã³ã渡ãå¿
è¦ãããã¾ãã
ãã®ä¾ã¯ãcapture
ãªãã·ã§ã³ã使ç¨ãã¦ãããã¨ãé¤ãã°ãå
ã»ã©è¦ããããªã³ã°ã®ä¾ã¨åãã§ãã
<body>
<div id="container">
<button>ãããã¯ãªãã¯</button>
</div>
<pre id="output"></pre>
</body>
const output = document.querySelector("#output");
function handleClick(e) {
output.textContent += `${e.currentTarget.tagName} è¦ç´ ãã¯ãªãã¯ãã¾ãã\n`;
}
const container = document.querySelector("#container");
const button = document.querySelector("button");
document.body.addEventListener("click", handleClick, { capture: true });
container.addEventListener("click", handleClick, { capture: true });
button.addEventListener("click", handleClick);
ãã®å ´åãã¡ãã»ã¼ã¸ã®é çªã¯éã«ãªãã¾ãã<body>
ã¤ãã³ããã³ãã©ã¼ãæåã«èµ·åããç¶ã㦠<div>
ã¤ãã³ããã³ãã©ã¼ãèµ·åããç¶ã㦠<button>
ã¤ãã³ããã³ãã©ã¼ãèµ·åãã¾ãã
BODY è¦ç´ ãã¯ãªãã¯ãã¾ãã DIV è¦ç´ ãã¯ãªãã¯ãã¾ãã BUTTON è¦ç´ ãã¯ãªãã¯ãã¾ãã
ãªããããããã£ããã£ã¨ãããªã³ã°ã®ä¸¡æ¹ã使ãã®ã§ãããããæããã©ã¦ã¶ã¼éã®äºææ§ãä»ãããã£ã¨ä½ãã£ãé ãNetscape ã¯ã¤ãã³ããã£ããã£ã®ã¿ã使ç¨ããã¤ã³ã¿ã¼ãããã¨ã¯ã¹ããã¼ã©ã¼ã¯ã¤ãã³ããããªã³ã°ã®ã¿ã使ç¨ãã¦ãã¾ãããW3C ãåä½ãæ¨æºåããã³ã³ã»ã³ãµã¹ãå¾ããã¨æ±ºããã¨ããå½¼ãã¯ç¾è¡ãã©ã¦ã¶ã¼ã«å®è£ ããã¦ããããã®ä¸¡æ¹ãå«ãã·ã¹ãã ã«è¡ãçãã¾ããã
æ¢å®ã§ã¯ãã»ã¨ãã©ãã¹ã¦ã®ã¤ãã³ããã³ãã©ã¼ã¯ãããªã³ã°ãã§ã¼ãºã§ç»é²ããããã®æ¹ãã»ã¨ãã©ã®å ´åã«ããã¦æå³ãããã¾ãã
ã¤ãã³ãã®å§è²åç¯ã§ã¯ãã¤ãã³ããããªã³ã°ãçºçãããåé¡ã¨ããããä¿®æ£ããæ¹æ³ã«ã¤ãã¦è¦ã¦ããã¾ãããããããã¤ãã³ããããªã³ã°ã¯åã«è¿·æãªã ãã§ã¯ããã¾ãããå ·ä½çãªä¾ã¨ãã¦ã¯ãã¤ãã³ãå§è² ãããã¾ãããã®æ¹æ³ã§ã¯ãã¦ã¼ã¶ã¼ã夿°ã®åè¦ç´ ã®ãããããæä½ããã¨ãã«ã³ã¼ããå®è¡ãããå ´åãåè¦ç´ ã«ã¤ãã³ããªã¹ãã¼ãåå¥ã«è¨å®ããã®ã§ã¯ãªããåè¦ç´ ã®è¦ªè¦ç´ ã«ã¤ãã³ããªã¹ãã¼ãè¨å®ããåè¦ç´ ã§çºçããã¤ãã³ãã親è¦ç´ ã«ããã«ã¢ãããããããã«ãã¾ãã
æåã®ä¾ã«æ»ãã¾ããããã¦ã¼ã¶ã¼ããã¿ã³ãã¯ãªãã¯ããã¨ãã«ãã¼ã¸å ¨ä½ã®èæ¯è²ãè¨å®ãã¾ããããã®ä»£ããã«ããã¼ã¸ã 16 ã®ã¿ã¤ã«ã«åå²ããã¦ãã¦ãã¦ã¼ã¶ã¼ãã¿ã¤ã«ãã¯ãªãã¯ããã¨ãã«åã¿ã¤ã«ã«ã©ã³ãã ãªè²ãè¨å®ãããã¨ãã¾ãã
ãã¡ãã HTML ã§ãã
<div id="container">
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
</div>
ã¿ã¤ã«ã®ãµã¤ãºã¨ä½ç½®ãè¨å®ããããã«ãã¡ãã£ã¨ãã CSS ãè¨å®ãã¾ãã
#container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
ããã§ JavaScript ã§ããã¹ã¦ã®ã¿ã¤ã«ã«ã¯ãªãã¯ã¤ãã³ããã³ãã©ã¼ã追å ãããã¨ãã§ãã¾ããããããããã·ã³ãã«ã§å¹ççãªãªãã·ã§ã³ã¯ã親ã«ã¯ãªãã¯ã¤ãã³ããã³ãã©ã¼ãè¨å®ããã¦ã¼ã¶ã¼ãã¿ã¤ã«ãã¯ãªãã¯ããã¨ãã«ãã³ãã©ã¼ã確å®ã«å®è¡ãããããã«ã¤ãã³ããããªã³ã°ã«é ¼ã£ã¦ãããã¨ã§ãã
function random(number) {
return Math.floor(Math.random() * number);
}
function bgChange() {
const rndCol = `rgb(${random(255)} ${random(255)} ${random(255)})`;
return rndCol;
}
const container = document.querySelector("#container");
container.addEventListener("click", (event) => {
event.target.style.backgroundColor = bgChange();
});
åºåã¯ä»¥ä¸ã®ã¨ããã§ãï¼ã¯ãªãã¯ãã¦ã¿ã¦ãã ããï¼ã
ã¡ã¢: ãã®ä¾ã§ã¯ãevent.target
ã使ç¨ãã¦ãã¤ãã³ãã®å¯¾è±¡ã¨ãªã£ãè¦ç´ ï¼ã¤ã¾ããæãå
å´ã®è¦ç´ ï¼ãåå¾ãã¦ãã¾ããããããã®ã¤ãã³ããå¦çããè¦ç´ ï¼ãã®ç¨éã§ã¯ã³ã³ããã¼ï¼ã«ã¢ã¯ã»ã¹ãããå ´åã¯ãevent.currentTarget
ã使ç¨ãããã¨ãã§ãã¾ãã
ã¡ã¢: å®å ¨ãªã½ã¼ã¹ã³ã¼ã㯠useful-eventtarget.html ãåç §ãã¦ãã ããããã¡ãã®ã©ã¤ãå®è¡ãåç §ãã¦ãã ããã
target
ããã³ currentTarget
ãã®ãã¼ã¸ã§ç´¹ä»ããä¾ãããè¦ã¦ããã¨ãã¯ãªãã¯ãããè¦ç´ ã«ã¢ã¯ã»ã¹ããããã«ã¤ãã³ããªãã¸ã§ã¯ãã® 2 ã¤ã®ç°ãªãããããã£ã使ç¨ãã¦ãããã¨ããããã¾ãã親è¦ç´ ã¸ã®ãªã¹ãã¼ã®è¨å®ã§ã¯ãevent.currentTarget
ã使ç¨ãã¦ãã¾ããããããã¤ãã³ãç§»è²ã§ã¯ãevent.target
ã使ç¨ãã¦ãã¾ãã
target
ã¯æåã«ã¤ãã³ããçºçããè¦ç´ ãåç
§ããcurrentTarget
ã¯ãã®ã¤ãã³ããã³ãã©ã¼ãæ¥ç¶ããã¦ããè¦ç´ ãåç
§ããã¨ããéããããã¾ãã
ã¤ãã³ããããã«ã¢ãããã¦ããé target
ã¯åãã¾ã¾ã§ãããcurrentTarget
ã¯é層å
ã®æ¥ç¶ããã¦ããè¦ç´ ãç°ãªãã°ãã¤ãã³ããã³ãã©ã¼ãç°ãªãã¾ãã
ä¸ã®ãããªã³ã°ã®ä¾ãå°ãã¢ã¬ã³ã¸ããã¨ããã®ãã¨ããããã¾ããå ã»ã©ã¨åã HTML ã使ç¨ãã¦ãã¾ãã
<body>
<div id="container">
<button>ãããã¯ãªãã¯</button>
</div>
<pre id="output"></pre>
</body>
JavaScript ã¯ã»ã¨ãã©åãã§ãããtarget
㨠currentTarget
ã®ä¸¡æ¹ããã°åºåãã¦ãã¾ãã
const output = document.querySelector("#output");
function handleClick(e) {
const logTarget = `target: ${e.target.tagName}`;
const logCurrentTarget = `currentTarget: ${e.currentTarget.tagName}`;
output.textContent += `${logTarget}, ${logCurrentTarget}\n`;
}
const container = document.querySelector("#container");
const button = document.querySelector("button");
document.body.addEventListener("click", handleClick);
container.addEventListener("click", handleClick);
button.addEventListener("click", handleClick);
ãã¿ã³ãã¯ãªãã¯ããã¨ããã¤ãã³ããã³ãã©ã¼ããã¿ã³èªèº«ã<div>
ã<body>
ã®ãããã«æ¥ç¶ããã¦ãã¦ããtarget
ã¯å¸¸ã«ãã¿ã³è¦ç´ ã§ãããã¨ã«æ³¨æãã¦ãã ãããããããcurrentTarget
ã¯ç¾å¨å®è¡ãã¦ããã¤ãã³ããã³ãã©ã¼ã®è¦ç´ ãç¹å®ãã¾ãã
target
ããããã£ã¯ãä¸è¨ã®ã¤ãã³ãç§»è²ã®ä¾ã®ããã«ãã¤ãã³ãç§»è²ã§ãã使ç¨ãã¾ãã
ãã®è¨äºã®æå¾ã«éãã¾ããããæã大åãªæ å ±ãè¦ãã¦ãã¾ããï¼æ¬¡ã«é²ãåã«ããã®æ å ±ã身ã«ä»ãããã©ããã確èªãããã¹ããããã¾ããã¹ãã«ãã¹ã: ã¤ãã³ããåç §ãã¦ãã ããã
ã¾ã¨ãããã§ããã®æ©ã段éã§ã¦ã§ãã¤ãã³ãã«ã¤ãã¦ç¥ã£ã¦ããã¹ããã¨ã¯ãã¹ã¦ããã£ãã¯ãã§ãã åè¿°ããããã«ãã¤ãã³ãã¯å®ã®ã¨ãã JavaScript ã®ã³ã¢ã«ã¯å±ãã¾ããããã©ã¦ã¶ã¼ã® Web API ã§å®ç¾©ããã¦ãã¾ãã
ã¾ããJavaScript ã使ç¨ããããã¾ãã¾ãªã³ã³ããã¹ãã«ã¯ãç°ãªãã¤ãã³ãã¢ãã«ããããã¨ãçè§£ãããã¨ãéè¦ã§ããWeb API ããããã©ã¦ã¶ã¼ã® WebExtensions ã Node.js (ãµã¼ãã¼ãµã¤ã JavaScript) ãªã©ã®ä»ã®é åã¾ã§ã§ãã ããã§ãããã®é åããã¹ã¦çè§£ã§ããã¨ã¯æã£ã¦ãã¾ããããã¦ã§ãéçºãå¦ç¿ãã¦ããä¸ã§ãã¤ãã³ãã®åºæ¬ãçè§£ãã¦ãããã¨ã¯ã¨ã¦ãå½¹ã«ç«ã¡ã¾ãã
次ã«ãããæ°ãããã¯ã®çè§£åº¦ãæ¤æ»ããåé¡ãæ¢ãã¾ãã
é¢é£æ å ±RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4