Skip to content

Commit ec0c623

Browse files
committed
refactor: streamline HTML structure and improve JavaScript functionality for IP lookup and ping tools
1 parent cf365f3 commit ec0c623

2 files changed

Lines changed: 86 additions & 165 deletions

File tree

index.html

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,13 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Tool Dashboard</title>
7-
<!-- Add Google Fonts -->
8-
<link rel="preconnect" href="https://fonts.googleapis.com">
9-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10-
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap" rel="stylesheet">
117
<link rel="stylesheet" href="styles.css" />
128
</head>
139
<body class="light-theme">
1410
<header>
1511
<h1>Tool Dashboard</h1>
1612
</header>
1713

18-
<!-- From Uiverse.io by kamehame-ha -->
1914
<div class="cards">
2015
<div class="card red" onclick="openNetworkTools()">
2116
<p class="tip">Network Tools</p>
@@ -36,31 +31,20 @@ <h2>Check My IP</h2>
3631

3732
<div class="tool-section">
3833
<h2>IP Lookup</h2>
39-
<div class="input-group">
40-
<input type="text"
41-
id="ip-input"
42-
placeholder="Enter an IP address or domain" />
43-
<button onclick="lookupIP()">Lookup</button>
44-
</div>
34+
<input type="text" id="ip-input" placeholder="Enter IP or domain">
35+
<button onclick="lookupIP()">Lookup</button>
4536
<p id="ip-info"></p>
4637
</div>
4738

4839
<div class="tool-section">
4940
<h2>Ping</h2>
50-
<input type="text" id="ping-url" placeholder="Enter URL" />
41+
<input type="text" id="ping-url" placeholder="Enter URL">
5142
<button onclick="ping()">Ping</button>
5243
<p id="ping-results"></p>
5344
</div>
54-
55-
<div class="tool-section">
56-
<h2>Speed Test</h2>
57-
<button onclick="runSpeedTest()">Run Test</button>
58-
<p id="speed-results"></p>
59-
</div>
6045
</div>
6146

6247
<div id="error-message" class="error-message"></div>
63-
6448
<script src="scripts.js"></script>
6549
</body>
6650
</html>

scripts.js

Lines changed: 83 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -1,157 +1,127 @@
11
// Ensure functions are globally accessible
22

3-
// Show the tools container when the Network Tools card is clicked
3+
// Cache DOM elements
4+
const elements = {
5+
toolsContainer: null,
6+
ipInput: null,
7+
pingUrl: null,
8+
myIp: null,
9+
ipInfo: null,
10+
pingResults: null,
11+
errorMessage: null
12+
};
13+
14+
// Initialize DOM elements and event listeners
15+
function initializeApp() {
16+
// Cache DOM elements
17+
elements.toolsContainer = document.getElementById('tools-container');
18+
elements.ipInput = document.getElementById('ip-input');
19+
elements.pingUrl = document.getElementById('ping-url');
20+
elements.myIp = document.getElementById('my-ip');
21+
elements.ipInfo = document.getElementById('ip-info');
22+
elements.pingResults = document.getElementById('ping-results');
23+
elements.errorMessage = document.getElementById('error-message');
24+
25+
// Add Enter key support
26+
if (elements.ipInput) {
27+
elements.ipInput.addEventListener('keypress', (e) => {
28+
if (e.key === 'Enter') lookupIP();
29+
});
30+
}
31+
32+
if (elements.pingUrl) {
33+
elements.pingUrl.addEventListener('keypress', (e) => {
34+
if (e.key === 'Enter') ping();
35+
});
36+
}
37+
}
38+
39+
// Show/hide the tools container
440
function openNetworkTools() {
5-
const toolsContainer = document.getElementById('tools-container');
6-
if (toolsContainer) {
7-
toolsContainer.style.display = 'block';
41+
const container = document.getElementById('tools-container');
42+
if (container) {
43+
container.style.display = container.style.display === 'none' ? 'block' : 'none';
844
}
945
}
1046

11-
// Fetch and display the user's IP address
47+
// Get user's IP address
1248
async function getMyIP() {
1349
try {
14-
// Using a basic DNS resolver API
15-
const response = await fetch('https://1.1.1.1/cdn-cgi/trace');
16-
const text = await response.text();
17-
const ip = text.split('\n')
18-
.find(line => line.startsWith('ip='))
19-
?.split('=')[1];
20-
50+
const response = await fetch('https://api.ipify.org?format=json');
51+
if (!response.ok) throw new Error('Network response was not ok');
52+
const data = await response.json();
2153
const myIpElement = document.getElementById('my-ip');
22-
if (myIpElement && ip) {
23-
myIpElement.textContent = `Your IP: ${ip}`;
54+
if (myIpElement) {
55+
myIpElement.textContent = `Your IP: ${data.ip}`;
2456
}
2557
} catch (error) {
26-
showError('Unable to fetch IP address.');
58+
showError('Unable to fetch IP address');
2759
console.error('Error fetching IP:', error);
2860
}
2961
}
3062

31-
// Validate input for IP or domain
32-
function validateInput(input) {
33-
// IP address regex
34-
const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
35-
// Basic domain regex
36-
const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/;
37-
38-
return ipRegex.test(input) || domainRegex.test(input);
39-
}
40-
41-
// Lookup details for an IP address or domain
63+
// Lookup IP or domain
4264
async function lookupIP() {
4365
try {
44-
const ipInput = document.getElementById('ip-input');
45-
if (!ipInput || !ipInput.value.trim()) {
46-
throw new Error('Please enter an IP address or domain');
47-
}
48-
49-
const input = ipInput.value.trim();
50-
if (!validateInput(input)) {
51-
throw new Error('Invalid IP address or domain format');
52-
}
66+
const input = elements.ipInput?.value?.trim();
67+
if (!input) throw new Error('Please enter an IP or domain');
5368

54-
// Using DNS resolver that works with both IP and domains
5569
const response = await fetch(`https://dns.google/resolve?name=${input}`);
70+
if (!response.ok) throw new Error('Lookup failed');
5671
const data = await response.json();
5772

58-
const ipInfoElement = document.getElementById('ip-info');
59-
if (ipInfoElement) {
60-
ipInfoElement.textContent = data.Answer
61-
? `Domain/IP resolves successfully\nResolved addresses: ${data.Answer.map(a => a.data).join(', ')}`
62-
: `Lookup failed`;
73+
if (elements.ipInfo) {
74+
elements.ipInfo.textContent = data.Answer
75+
? `Resolved: ${data.Answer[0].data}`
76+
: 'Lookup failed';
6377
}
6478
} catch (error) {
65-
showError(error.message || 'Unable to lookup address.');
79+
showError(error.message || 'Unable to lookup address');
6680
console.error('Error during lookup:', error);
6781
}
6882
}
6983

70-
// Ping function with improved domain handling
84+
// Ping function
7185
async function ping() {
7286
try {
73-
const urlInput = document.getElementById('ping-url');
74-
if (!urlInput || !urlInput.value.trim()) {
75-
throw new Error('Please enter a URL or domain');
76-
}
87+
const input = elements.pingUrl?.value?.trim();
88+
if (!input) throw new Error('Please enter a URL');
7789

78-
const input = urlInput.value.trim();
79-
const url = formatUrl(input);
8090
const startTime = performance.now();
81-
82-
const response = await Promise.race([
83-
fetch(url, {
84-
mode: 'no-cors',
85-
cache: 'no-cache'
86-
}),
87-
new Promise((_, reject) =>
88-
setTimeout(() => reject(new Error('Request timeout')), 5000)
89-
)
90-
]);
91-
92-
const endTime = performance.now();
93-
const pingTime = Math.round(endTime - startTime);
94-
95-
const resultsElement = document.getElementById('ping-results');
96-
if (resultsElement) {
97-
resultsElement.textContent = `Ping time: ${pingTime}ms`;
91+
await fetch(`https://${input.replace(/^https?:\/\//, '')}`, {
92+
mode: 'no-cors'
93+
});
94+
95+
if (elements.pingResults) {
96+
elements.pingResults.textContent =
97+
`Ping time: ${Math.round(performance.now() - startTime)}ms`;
9898
}
9999
} catch (error) {
100-
const resultsElement = document.getElementById('ping-results');
101-
if (resultsElement) {
102-
resultsElement.textContent = 'Host is reachable';
103-
}
100+
showError('Unable to ping the specified URL');
101+
console.error('Error during ping:', error);
104102
}
105103
}
106104

107-
// Helper function to format URLs
105+
// Format URL helper
108106
function formatUrl(input) {
109107
try {
110-
// Remove any protocol if present
111-
let cleanInput = input.replace(/^(https?:\/\/)/, '');
112-
// Remove any paths or query parameters
113-
cleanInput = cleanInput.split('/')[0];
114-
// Construct final URL
108+
let cleanInput = input.toLowerCase().trim()
109+
.replace(/^(https?:\/\/)/, '')
110+
.split('/')[0];
115111
return `https://${cleanInput}`;
116112
} catch (error) {
117113
throw new Error('Invalid URL format');
118114
}
119115
}
120116

121-
// Validate and secure URL
122-
function validateAndSecureURL(url) {
123-
try {
124-
let secureUrl = url.toLowerCase().trim();
125-
if (!secureUrl.startsWith('http://') && !secureUrl.startsWith('https://')) {
126-
secureUrl = 'https://' + secureUrl;
127-
} else if (secureUrl.startsWith('http://')) {
128-
secureUrl = secureUrl.replace('http://', 'https://');
129-
}
130-
131-
const urlObj = new URL(secureUrl);
132-
return urlObj.href;
133-
} catch {
134-
throw new Error('Invalid URL format');
135-
}
136-
}
137-
138-
// Show error message
117+
// Show error messages
139118
function showError(message) {
140119
const errorElement = document.getElementById('error-message');
141-
if (!errorElement) {
142-
console.error('Error element not found');
143-
return;
144-
}
120+
if (!errorElement) return;
145121

146122
errorElement.textContent = message;
147123
errorElement.style.display = 'block';
148-
149-
setTimeout(() => {
150-
const element = document.getElementById('error-message');
151-
if (element) {
152-
element.style.display = 'none';
153-
}
154-
}, 5000);
124+
setTimeout(() => errorElement.style.display = 'none', 5000);
155125
}
156126

157127
// Run speed test
@@ -198,45 +168,12 @@ document.getElementById('theme-toggle').addEventListener('change', function () {
198168
}
199169
});
200170

201-
// Initialize event listeners
202-
document.addEventListener('DOMContentLoaded', () => {
203-
// Add any initialization code here
204-
const toolsContainer = document.getElementById('tools-container');
205-
if (toolsContainer) {
206-
toolsContainer.style.display = 'none';
207-
}
208-
initializeInputHandlers();
209-
});
210-
211-
// Initialize input handlers for Enter key
212-
function initializeInputHandlers() {
213-
const pingInput = document.getElementById('ping-url');
214-
if (pingInput) {
215-
pingInput.addEventListener('keypress', function(event) {
216-
if (event.key === 'Enter') {
217-
event.preventDefault();
218-
ping();
219-
}
220-
});
221-
}
222-
}
223-
224-
// Add event listener for Enter key
225-
function initializeInputHandlers() {
226-
const ipInput = document.getElementById('ip-input');
227-
if (ipInput) {
228-
ipInput.addEventListener('keypress', function(event) {
229-
if (event.key === 'Enter') {
230-
event.preventDefault();
231-
lookupIP();
232-
}
233-
});
234-
}
235-
}
171+
// Initialize app when document loads
172+
document.addEventListener('DOMContentLoaded', initializeApp);
236173

237-
// Expose functions to global scope
238-
window.getMyIP = getMyIP
239-
window.lookupIP = lookupIP
240-
window.runSpeedTest = runSpeedTest
241-
window.ping = ping
242-
window.openNetworkTools = openNetworkTools
174+
// Expose necessary functions to global scope
175+
window.getMyIP = getMyIP;
176+
window.lookupIP = lookupIP;
177+
window.runSpeedTest = runSpeedTest;
178+
window.ping = ping;
179+
window.openNetworkTools = openNetworkTools;

0 commit comments

Comments
 (0)