The result ended Leeds' five-match winless run in the league and lifted Daniel Farke's side above Spurs into eighth place.
Leeds made the brighter start, with Gabriel Gudmundsson seeing an early penalty appeal rejected after his cross appeared to strike Mateus Fernandes on the arm. Ao Tanaka and Ethan Ampadu also threatened before Tottenham gradually settled into the contest. James Trafford was called into action to keep out a deflected Omar Marmoush effort before denying Mohammed Kudus.
The first half also produced a major talking point when Jayden Bogle caught Mathys Tel with a dangerous studs-up challenge. Despite a lengthy VAR review, no red card was shown, leaving Tottenham frustrated. Tel was unable to continue and was replaced by Dominic Solanke, while Leeds came close to taking advantage when Luis Nmecha's header was saved by Antonin Kinsky.
Leeds continued to cause problems after the break, with Micky van de Ven making an important intervention to prevent Bogle's delivery from reaching Calvert-Lewin. Tottenham coach Roberto De Zerbi became increasingly frustrated when Pedro Porro was booked for a challenge on Nmecha, protesting that the decision was harsh compared with the earlier incident involving Tel. De Zerbi was also shown a yellow card.
Calvert-Lewin missed an opportunity to put Leeds ahead after being played through by Sean Longstaff, while Tanaka subsequently fired over the crossbar. Tottenham nearly punished those missed chances when substitute Conor Gallagher sent a long-range effort narrowly wide, but Leeds continued to press for a breakthrough.
Kinsky then produced an excellent save to tip Longstaff's powerful effort over the crossbar as the hosts increased the pressure. Leeds finally found the goal their performance deserved in the 79th minute when Tottenham failed to deal with a long throw into the penalty area. Okafor took advantage, driving forward before producing a composed finish beyond Kinsky.
Tottenham struggled to find a response in the closing stages, although Trafford was required to save a Jan Paul van Hecke header. The visitors were left to reflect on another damaging result, extending their record to 50 consecutive matches without a win in all competitions when conceding first, with 12 draws and 38 defeats.