Tahazzot
Tahazzot

Reputation: 1262

Get focused element on mouse cursor move using JavaScript

When I click any block it adds a new class .is-selected. It works fine when I get focus by click on the blocks. But It does not work when I use the arrow keys to get focus on another block. How can I get this focus when I use arrow keys?

let getBlocks = document.querySelectorAll(".block");

getBlocks.forEach((single) => {
  single.addEventListener("focus", () => {
    //remove all activated class
    getBlocks.forEach((x) => {
      x.classList.remove("is-selected");
    });
    
    //add the class to this new focus block
    single.classList.add("is-selected");
  });
});
* {
  box-sizing: border-box;
}

.root {
  max-width: 600px;
  margin: 1rem auto;
}
.root:focus,
.block:focus {
  outline: 0;
}

.is-selected {
  background-color: #f4f8ff !important;
  border: 1px solid #deebff !important;
}
<div class="root" contenteditable>
  <p name="jYdi0" class="block" tabindex="0">1</p>
  <p name="Hdy89" class="block" tabindex="0">2</p>
  <p name="wEldk" class="block" tabindex="0">3</p>
</div>

Upvotes: 4

Views: 1037

Answers (2)

Pranav Rustagi
Pranav Rustagi

Reputation: 2721

UPDATED :

var ind = 0;

let getBlocks = document.querySelectorAll(".block");

function caretInfo(up = true) {
  let sel = window.getSelection();
  let offset = sel.focusOffset;
  if (up) {
    sel.modify("move", "backward", "character");
    if (offset == sel.focusOffset) return true;
    else {
      sel.modify("move", "forward", "character");
      return false;
    }
  } else {
    sel.modify("move", "forward", "character");
    if (offset == sel.focusOffset) return true;
    else {
      sel.modify("move", "backward", "character");
      return false;
    }
  }
}

function selection(item) {
  getBlocks.forEach((x, index) => {
    if (x === item) {
      ind = index;
    }
    x.classList.remove("is-selected");
  });

  //add the class to this new focus block
  item.classList.add("is-selected");

}

getBlocks.forEach((item) => {
  item.addEventListener('focus', () => {
    selection(item);
  });
});

document.addEventListener("keydown", function(event) {
  let change = false;
  if (event.keyCode == 38 || event.keyCode == 40) {
    if (event.keyCode == 38 && ind > 0) {
      change = caretInfo();
      if (change) {
        ind--;
      }
    } else if (event.keyCode == 40 && ind < document.querySelectorAll('.root p').length - 1) {
      change = caretInfo(false);
      if (change) {
        ind++;
      }
    }

    if (change) {
      let cur = document.querySelectorAll('.root p')[ind];
      cur.focus();
    }
  }
})
* {
  box-sizing: border-box;
}

.root {
  max-width: 600px;
  margin: 1rem auto;
}

.root:focus,
.block:focus {
  outline: 0;
}

.is-selected {
  background-color: #f4f8ff !important;
  border: 1px solid #deebff !important;
}
<div class="root">
  <p name="jYdi0" class="block" tabindex="0" contenteditable>1</p>
  <p name="Hdy89" class="block" tabindex="0" contenteditable>It was single line but now it's multiple line Just amazine what can be happen here. Here is the problem try to click "me" and then press arrow up. Ops :( but it should be on the first line</p>
  <p name="wEldk" class="block" tabindex="0" contenteditable>lorem ipsumlorem ipsumlorem ipsum3</p>
</div>

Upvotes: 2

Prabin
Prabin

Reputation: 33

You can also do something like

   document.addEventListener("keypress", (event) => {
       if(event.which === someEventCode) {
         // your code here
       }
    })

Here, the someEventCode variable is different for different key presses.

Upvotes: 0

Related Questions