3

I am coding a log message box / same function as a chat and I would like to set my AutoScrollDown Boolean to false once someone selects text inside of the chat (if the user wants paste something for example).

I realized my log message/chat box with an ul and lis, which looks like this:

<ul id="1" class="logbox">
   <li class="debug"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.learn how to make a website. We offer free tutorials in all web development technologies.</li>
   <li class="error"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.</li>
   <li class="warning"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.</li>
   <li>blabla</li>
</ul>

I have tried the following events to check if content inside of my ul is selected or not, which didn't work:

  $("#1").on("focus", function() {
    autoScrollEnabled = 0;
  });

  $("#1").off("focus", function() {
    autoScrollEnabled = 1;
  });

My question: How can I set autoScrollEnabled to 0 once someone selects/highlights text inside of my ul and how can I check if the user has stopped selecting/highligting any text.

kentor
  • 16,553
  • 20
  • 86
  • 144
  • 1
    Possible duplicate? http://stackoverflow.com/questions/3731328/on-text-highlight-event –  Sep 02 '16 at 14:50
  • @Omeed no, I read that stack before. – kentor Sep 02 '16 at 15:04
  • 1
    I'm not sure if you did. It states that there is not explicit "onHightlightEvent" possible. I believe the answer explains how to achieve this via mouseup. How does that not answer your question? –  Sep 02 '16 at 15:05
  • 1
    Please understand my use case, a chat / log box where every second / milliseconds may come new messages + autoscroll down, I need to stop the autoscrolldown once something is selected, otherwise it would scrolldown that fast, that it's not possible to select text properly. I tried to demonstrate this problem with a new text interval of 500ms: https://streamable.com/67ay . If there would come bigger messages (like 10 lines or so, this would make pasting VERY uncomfortable) – kentor Sep 02 '16 at 15:10
  • Maybe you need something more broad then, like when theres any mouse activity inside your chat box? Anyways, sorry for the confusion good luck. –  Sep 02 '16 at 15:12
  • Do not use `$("#1")`. `1` is not a valid CSS identifier, so `#1` is not a valid selector. It seems jQuery does something nasty under the hood to make it work, but do not rely on that. Use `$("#\\31")` or `$(document.getElementById("1"))`. – Oriol Sep 04 '16 at 23:39
  • Is `autoScrollEnabled` a plugin method? I don't think it's standard JS/jQ. – zer00ne Sep 05 '16 at 01:44
  • @zer00ne it is just a boolean for another function I have made. – kentor Sep 05 '16 at 13:01
  • @kentor yeah, I already gathered that. I saw the video that tells me that upon mouseup, my solution would work. Either you don't understand it or you can't fully demonstrate your working code which would make it very difficult to test. Saying that a solution doesn't work and not explaining why or not even testing it it does not help us to help you. – zer00ne Sep 05 '16 at 14:03
  • BTW, it would help if you posted that other function that's supposed to be responsible for stopping and starting autoScrolling don't you think? – zer00ne Sep 05 '16 at 14:13

5 Answers5

0

This Snippet demonstrates that:

A. It can detect the selection of text with or without form inputs.

B. Will trigger on mouseup event and adequately handle false positives like text clicked but nothing highlighted.

  1. Delegate the whole document to listen for a mouseup event.

  2. Next define the boolean state with:

    a. Condition 1 (needs to be true): That a selection object exists

    * selection is true as soon as any text is the event.target (i.e. clicked, mouseup, farted on, etc.)

    b. Condition 2 (needs to be not collapsed): That the selection is not just a single click on text (i.e. nothing highlighted)

    * By using the property .isCollapsed we know that if the starting point of a selection is the same as the ending point of a selection, then .isCollapsed is true and therefore no text was highlighted.

  3. Since autoscroll was never explained, I have simplified it as an alert.

    a. If autoScroll is disabled, the alert will also contain the text that's selected.

SNIPPET

/*
This Snippet demonstrates that:
   A. It can detect the selection of text with or without form inputs.
   B. Will trigger on mouseup event and adequately handle false positives like text clicked but nothing highlighted.
*/

// Reference a selection object
var selection = window.getSelection();

/*
1. Delegate the whole document to listen for a mouseup event.

2. Next define the boolean state with:

  a. Condition 1 (needs to be true): That a selection object exists
  
     * selection is true as soon as any text is the event.target (i.e. clicked, mouseup, farted on, etc.)
  b. Condition 2 (needs to be not collapsed): That the selection is not just a single click on text (i.e. nothing highlighted)
  
     * By using the property .isCollapsed we know that if the starting point of a selection is the same as the ending point of a selection, then .isCollapsed is true and therefore no text was highlighted.
     
3. Since autoscroll was never explained, I have simplified it as an alert.

   a. If autoScroll is disabled, the alert will also contain the text that's selected. 
*/

$(document).on('mouseup', function(e) {
  var state = (selection && !selection.isCollapsed) ? alert('autoScroll is disabled {{' + selection + '}} is selected') : alert('autoScroll is still enabled');
  return state;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="list1" class="logbox">
  <li class="debug"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.learn how to make a website. We offer free tutorials in all web development technologies.</li>
  <li class="error"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.</li>
  <li class="warning"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.</li>
  <li>blabla</li>
</ul>

REFERENCES

zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • Please read the comments (including the video snippet) why this wouldn't solve my problem at all. – kentor Sep 05 '16 at 13:13
  • See my comments in reply to your explanation. If the scrolling is too fast use `mousedown` instead. Your video doesn't explain much. All I know is if an event is captured then your callback should respond immediately. You can accomplish that by `setTimeout(function(){..},0` – zer00ne Sep 05 '16 at 14:07
0

li elements don't have focus event but it is possible to trick around. See following snippet.

var autoScrollOn = 1; //declare globally
var timeoutHandle = 0; //for additional service
$('#ul1').on('click', 'li', function() { //delegate click event
  clearTimeout(timeoutHandle); //clear timeout if any
  if ($(this).hasClass('selected')) { 
    //remove selection on the second click
    $('#ul1 li').removeClass('selected');
    autoScrollOn = 0;
  } else {
    //remove selection from siblings
    $('#ul1 li').removeClass('selected');
    //and add to the clicked element
    $(this).addClass('selected');
    autoScrollOn = 1;
    //restore autoscroll after 10s
    timeoutHandle = setTimeout(function() {
      $('#ul1 li').removeClass('selected');
      autoScrollOn = 0;
      console.log(autoScrollOn);
    }, 10000);
  }
  //do whatever you want with autoscroll
  console.log(autoScrollOn);
});
.debug {
  background: #aaf;
}
.error {
  background: #faa;
}
.warning {
  background: #ffa;
}
.selected {
  border: solid 1px #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="ul1" class="logbox">
  <li class="debug"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.learn how to make a website. We offer free tutorials in all web development technologies.</li>
  <li class="error"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.</li>
  <li class="warning"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.</li>
  <li>blabla</li>
</ul>
Alex Kudryashev
  • 9,120
  • 3
  • 27
  • 36
  • This doesn't solve my problem either at all (please check the comments including the streamable). Also your snippet doesn't work as I have expected it (it is about selecting text for example while new text is coming all the time). The console.log only happens after real clicks (try selecting text instead) – kentor Sep 05 '16 at 13:17
0

To detect if user's are highlighting text in the log box, you should first listen for the mousedown event and then see if there are any mousemove events while the mouse is still down. You can set your flag to false either on mouse down or on mouse move, and then reset it in the mouseup event.

document.querySelector('#one').addEventListener('mousedown', function (event) {

  window.onmousemove = function (event) {
    console.log('the user is selecting text');
  }
  
  window.onmouseup = function (event) {
    console.log('the user mousedup');
    console.log(window.getSelection());
    autoScrollEnabled = 1;
    window.onmousemove = null;
    window.onmouseup = null;
  }
  
  console.log('user mouseddown in ' + event.target.nodeName);
  autoScrollEnabled = 0;
}, false);
<ul id="one" class="logbox">
   <li class="debug"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.learn how to make a website. We offer free tutorials in all web development technologies.</li>
   <li class="error"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.</li>
   <li class="warning"><b>At</b> w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies.</li>
   <li>blabla</li>
</ul>
skyline3000
  • 7,639
  • 2
  • 24
  • 33
0
<script type="text/javascript">
    var mouseIsDown         = false,
        autoScrollEnabled   = 1;
        userSelection       = '';

    $.fn.doIt = function () {
        if (!window.getSelection().isCollapsed) {
            var range1 = window.getSelection().getRangeAt(0),
                range2 = range1.cloneRange();

            range2.selectNodeContents(this[0]);
            range2.setStart(range1.startContainer, range1.startOffset);
            range2.setEnd(range1.endContainer, range1.endOffset);
            userSelection = range2.toString();
            console.log(userSelection);

            if (userSelection != '')
                autoScrollEnabled = 0;
            else
                autoScrollEnabled = 1;
        } else
              autoScrollEnabled = 1;
    };

    $('.logbox').mousedown(function(event) {
        $(this).parent().delegate('ul.logbox', 'mousemove', function(event) {
            if (!mouseIsDown) return;
            $(this).doIt();
        });
        mouseIsDown = true;
    }).dblclick(function(event) {
        $(this).doIt();
    });

    $(window).mouseup(function(event) {
        mouseIsDown = false;
        $('.logbox').parent().undelegate('ul.logbox', 'mousemove');
    })
</script>
tdjprog
  • 706
  • 6
  • 11
-1

You need to incorporate some form fields into your log message application so you can use jQuery methods like on focus and on blur and do event-driven programming. They don't normally work on raw text like li's.

Andrew Koper
  • 6,481
  • 6
  • 42
  • 50
  • Can you elloborate this with a code example? What should I use instead of ul/li's then? When I think about form fields there are only input elements which come to my mind. – kentor Sep 03 '16 at 12:25