javascript selected text is not properly positioned after scroll - javascript

I want to let my user to search by selecting text. After selecting text, a new button open on right of the selected text for giving an option to search or not. when user scroll to bottom on the page, search button is not properly positioned. My code is given below:
html:
<body ng-app="newsApp" ng-controller="NewsCtrl" ng-mouseup="showSelectedText($event)">
<!-- user search button -->
<div ng-show="isUserSearch" ng-style="{ 'left' : leftPos, 'top': rightPos, 'display': displayState }" class="searchBtn">
Search
</div>
<!-- main content -->
<div>
<!-- main content -->
</div>
</body>
css::
.searchBtn {
position: absolute;
padding: 4px 7px;
background-color: #ff0;
color: #ddd;
z-index: 9999;
border-radius: 5px 5px 5px 5px;
height: 27px;
cursor: pointer;
}
javascript::
angular.module('newsApp', [])
.controller('NewsCtrl',function ($scope) {
$scope.leftPos = "-200px";
$scope.rightPos = "-200px";
$scope.displayState = "none !important";
$scope.isUserSearch = false;
$scope.selectedTextSearch = "";
$scope.showSelectedText = function($event) {
$scope.selectedText = "";
if (window.getSelection) {
$scope.selectedText = window.getSelection().toString();
}
else if (document.selection && document.selection.type != "Control") {
$scope.selectedText = document.selection.createRange().text;
}
if($scope.selectedText.length > 0) {
$scope.leftPos = (+$event.clientX + 5) + 'px';
$scope.rightPos = ( +$event.clientY - 15 ) + 'px';
$scope.isUserSearch = true;
} else {
$scope.isUserSearch = false;
}
};
});
Plunker
What can I do now?

Change clientX to pageX
$scope.leftPos = (+$event.pageX + 5) + 'px';
$scope.rightPos = ( +$event.pageY - 15 ) + 'px';
See this answer for the difference.

Related

Programatically resize the H div and C div along with the resizer

When I click-drag (#cssNav) to the right, it is not moving proportionately along with the #html and #css div.
This might be something very obvious, but still am not able to figure it out, what am I missing here, please help?
Note: I don't want to use display:flex
codepen
$("#htmlNav").on("mousedown", dragStartH);
$("#cssNav").on("mousedown", dragStartH);
$("#jsNav").on("mousedown", dragStartH);
function dragStartH(e) {
e.preventDefault();
dragMeta = {};
dragMeta.pageX0 = e.pageX;
dragMeta.elem = this;
dragMeta.offset0 = $(this).offset();
dragMeta.codeWindow = "#" + $(e.target).attr("id").replace("Nav", "");
function handle_dragging(e) {
var change = e.pageX - dragMeta.pageX0;
var left = dragMeta.offset0.left + change;
$(dragMeta.elem).offset({ left: left });
$("#css").width($("#css").width() - change + "px");
$("#html").width($("#html").width() + change + "px");
}
function handle_mouseup(e) {
$("body")
.off("mousemove", handle_dragging)
.off("mouseup", handle_mouseup);
}
$("body").on("mouseup", handle_mouseup).on("mousemove", handle_dragging);
}
$(document).ready(function() {
var widthPercent = ($(window).width() - 30) / 3;
$("#html").width(widthPercent + "px");
$("#css").width(widthPercent + "px");
$("#js").width(widthPercent + "px");
});
html, body {
height: 100%;
margin: 0;
}
.container{
width:100%;
height: 100%;
background-color:#343;
display: flex;
flex-direction: column;
color: #fff;
margin: 0;
}
#preview, #code{
background-color:#433;
height: 50%;
width: 100%;
margin: 0;
}
#code{
border-bottom: #333 solid 2px;
width: 100%
}
#previewNav, #codeNav{
background-color:#bbb;
height: 10px;
width: 100%;
cursor: row-resize;
}
#html{
background-color: #BFB;
}
#css{
background-color: #FBB;
}
#js{
background-color: #BBF;
}
#html, #css, #js{
float: left;
width: 32%;
height: 100%;
}
#htmlNav, #cssNav, #jsNav{
background-color:#bbb;
float: left;
height:100%;
width: 10px;
cursor: col-resize;
z-index:10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="codeNav"></div>
<div id="code">
<div id="htmlNav"></div>
<div id="html">H</div>
<div id="cssNav"></div>
<div id="css">C</div>
<div id="jsNav"></div>
<div id="js">J</div>
</div>
<div id="previewNav"></div>
<div id="preview">P</div>
</div>
This is how I would do it:
Keep track of which handle you press with navTypeand check if the user is holding its mouse down with dragging.
Then when the user moves the mouse in the document and it is holding its mouse down (dragging) it will move the #html, #css and #js accordingly
Change your javascript into this:
var mouseX, prevMouseX, navType, change;
var dragging = false;
$("#cssNav").mousedown(function () {
dragging = true;
navType = "css";
});
$("#jsNav").mousedown(function () {
dragging = true;
navType = "js";
});
$(document).mousemove(function (e) {
mouseX = e.pageX;
if(dragging){
e.preventDefault();
change = mouseX - prevMouseX;
if(navType == "css" && ($("#css").width() - (change)) > 0 && ($("#html").width() + (change)) > 0){
var hw = $("#html").width();
var cw = $("#css").width();
$("#html").width(hw + change);
$("#css").width(cw - change);
} else if(navType == "js" && ($("#css").width() + (change)) > 0 && ($("#js").width() - (change)) > 0){
var cw = $("#css").width();
var jw = $("#js").width();
$("#css").width(cw + change);
$("#js").width(jw - change);
}
}
prevMouseX = mouseX;
}).mouseup(function () {
dragging = false;
}).mouseleave(function () {
dragging = false;
});

Detect when an image enters a div?

I am creating a maze game, and I want to detect when the image following the cursor reaches a certain div, the finishing point. I have the image following the mouse, and I have the container that the image will be in. When the image reaches the div, I want something to trigger, lets say an alert. How can I achieve this?
var startMove;
$(document).mousemove(function(e) {
var DIFF_SNAP = 10;
var DIFF_UNSNAP = 100;
var difLeft = $('#image').offset().left - e.pageX;
var difTop = $('#image').offset().top - e.pageY;
if (!startMove && Math.abs(difLeft) < DIFF_SNAP && Math.abs(difTop) < DIFF_SNAP) {
startMove = true;
$('html').removeClass('showCursor');
} else if (startMove && !(Math.abs(difLeft) < DIFF_UNSNAP && Math.abs(difTop) < DIFF_UNSNAP)) {
startMove = false;
}
if (startMove) {
$("#image").css({
left: e.pageX,
top: e.pageY
});
} else {
$('html').addClass('showCursor');
}
});
$(document).mouseleave(function() {
startMove = false;
})
html {cursor: none;}
html.showCursor{cursor: default;}
#image{
position:absolute;
width:25px;
height:auto;
}
div{
margin-left: 500px;
width: 200px;
height: 50px;
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<img id="image" src="http://static.micheljansen.org/uploads/mac-osx-arrow-cursor.png"/>
<div></div>
Jsfiddle: https://jsfiddle.net/3x7cgLdr/25/
if ($('#TargetDiv').is(':hover')) {
// alert('hello');
$("#image").addClass("red");
}else{
$("#image").removeClass("red");
}
Using this .is() function with :hover selector inside the
if(startMove){
}
Section simply does that without any hassle the is() function Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.
.is() function documentation
var startMove;
$(document).mousemove(function(e) {
var difLeft = $('#image').offset().left - e.pageX;
var difTop = $('#image').offset().top - e.pageY;
if (difLeft < 10 && difLeft > -10 && difTop < 10 && difTop > -10) {
startMove = true;
$('html').removeClass('showCursor');
}
if (startMove) {
$("#image").css({
left: e.pageX,
top: e.pageY
});
if ($('#TargetDiv').is(':hover')) {
// alert('hello');
$("#image").addClass("red");
} else {
$("#image").removeClass("red");
}
} else {
$('html').addClass('showCursor');
}
});
$(document).mouseleave(function() {
startMove = false;
})
html {
cursor: none;
}
html.showCursor {
cursor: default;
}
#image {
position: absolute;
width: 25px;
height: auto;
}
#TargetDiv {
height: 100px;
width: 100px;
background: green;
margin: 100px auto;
}
.red {
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<img id="image" src="http://static.micheljansen.org/uploads/mac-osx-arrow-cursor.png" />
<div id="TargetDiv">
</div>
I have added a class to set border red to the div when it hovers on the div with mouse and cursor image superimposed that is startMove="true".And removes when it is not hovered .I have commented the alert box;You can turn it on if you want
You already have a flag called startMove that is active whenever the cursor is dragged, use the mouseenter event on the target div as follows:
var startMove;
$(document).mousemove(function(e){
var difLeft = $('#image').offset().left - e.pageX;
var difTop = $('#image').offset().top - e.pageY;
if(difLeft < 10 && difLeft > -10 && difTop < 10 && difTop > -10 ){
startMove = true;
$('html').removeClass('showCursor');
}
if(startMove){
$("#image").css({left:e.pageX, top:e.pageY});
}
else{
$('html').addClass('showCursor');
}
});
$(document).mouseleave(function(){
startMove = false;
})
$("#drop").mouseenter(function(){
if(startMove)
alert("Success");
});
.
<img id="image" src="http://static.micheljansen.org/uploads/mac-osx-arrow-cursor.png"/>
<div id="drop">
</div>
.
html {cursor: none;}
html.showCursor{cursor: default;}
#image{
position:absolute;
width:25px;
z-index: 100;
height:auto;
}
#drop{
width:100px;
height:100px;
background:green;
position: absolute;
left:200px;
top: 300px;
z-index:99
}
see a demo: https://jsfiddle.net/hycd913y/

Making a javascript popup draggable

I am creating a JavaScript popup. The code is as below.
The HTML:
<div id="ac-wrapper" style='display:none' onClick="hideNow(event)">
<div id="popup">
<center>
<h2>Popup Content Here</h2>
<input type="submit" name="submit" value="Submit" onClick="PopUp('hide')" />
</center>
</div>
</div>
The CSS:
#ac-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url("images/pop-bg.png") repeat top left transparent;
z-index: 1001;
}
#popup {
background: none repeat scroll 0 0 #FFFFFF;
border-radius: 18px;
-moz-border-radius: 18px;
-webkit-border-radius: 18px;
height: 361px;
margin: 5% auto;
position: relative;
width: 597px;
}
The Script:
function PopUp(hideOrshow) {
if (hideOrshow == 'hide') document.getElementById('ac-wrapper').style.display = "none";
else document.getElementById('ac-wrapper').removeAttribute('style');
}
window.onload = function () {
setTimeout(function () {
PopUp('show');
}, 0);
}
function hideNow(e) {
if (e.target.id == 'ac-wrapper') document.getElementById('ac-wrapper').style.display = 'none';
}
The jsFiddle Link:
http://jsfiddle.net/K9qL4/2/
The Issue:
The above script works fine, but I need to make the popUp draggable.
Here's some code that will do what you want. It relies only on an object called drag to store all its values, but you can easily alter that. The example relies on there being a div with the id of mydiv (a document.write() is used in this instance to supply that) that has a position attribute of absolute or fixed. You can see it in action at Jamie
document.write("<" + "div id='mydiv' style='background:blue; width:100px;"
"height:100px; position:fixed;'>" + "<" + "/div>");
var drag = new Object();
drag.obj = document.getElementById('mydiv');
drag.obj.addEventListener('mousedown', function(e)
{
drag.top = parseInt(drag.obj.offsetTop);
drag.left = parseInt(drag.obj.offsetLeft);
drag.oldx = drag.x;
drag.oldy = drag.y;
drag.drag = true;
});
window.addEventListener('mouseup', function()
{
drag.drag = false;
});
window.addEventListener('mousemove', function(e)
{
drag.x = e.clientX;
drag.y = e.clientY;
var diffw = drag.x - drag.oldx;
var diffh = drag.y - drag.oldy;
if (drag.drag)
{
drag.obj.style.left = drag.left + diffw + 'px';
drag.obj.style.top = drag.top + diffh + 'px';
e.preventDefault();
}
});
Use the
.draggable();
jquery function, here is your updated fiddle:
http://jsfiddle.net/N9rQK/
If you don't want to use jQuery, you should read this subject: Draggable div without jQuery UI

Drag and drop a div added into another div

Scenario
I am having a functionality in my project in which we have to add a note in a section and then it can be moved to the other sections. It is a sort of task tracking.
I am able to add a note dynamically created into one section and have made that note dragable. The note, sections are divs.
Problem
I am not able to drag the note to the other section or div. the note is draggable in its own section (div). Please help me with the solution so that it can be moved to other section.
Here is my HTML code:
<div id="addTaskDiv" style="height: 150px">
<a id="addTask" onclick="AddNote();">ADD Task</a> <a id="a1" onclick="AddText();">Submit</a>
</div>
<div id="MySplitter">
<div id="leftDiv" style="height: 150px; border-style: groove; width: 100%;">
left here
</div>
<div id="splitterUpperDiv">
<div id="midDiv" style="height: 150px; border-style: groove; width: 100%;">
middle here
</div>
<div id="rightDiv" style="height: 150px; width: 100%; border-style: groove;">
right here
</div>
</div>
</div>
Here is my .js
$().ready(function () {
$("#MySplitter").splitter();
$("#splitterUpperDiv").splitter();
$("#rightDiv").droppable();
$("#midDiv").droppable();
$("#leftDiv").droppable();
});
function AddNote(args, seder) {
var i = (typeof this.rel != 'undefined') && (this.rel - 0) == this.rel ? this.rel : 0;
var br = document.createElement("br");
$("#addTaskDiv")[0].appendChild(br);
addArea();
return false;
}
function addArea() {
var i = (typeof this.rel != 'undefined') && (this.rel - 0) == this.rel ? this.rel : 0;
var button = $(this);
var commentField = $('<textarea/>'); // create a textarea element
commentField[0].id = 'added' + i;
commentField
.css({
position: 'absolute',
width: 200, // textbox 200px by 100px
height: 100
})
// set the textarea's value to be the saved content, or a default if there is no saved content
.val(button.data('textContent') || 'This is my comment field\'s text')
// set up a keypress handler on the textarea
.keypress(function (e) {
if (e.which === 13) { // if it's the enter button
e.preventDefault(); // ignore the line break
button.data('textContent', this.value); // save the content to the button
$(this).remove(); // remove the textarea
}
})
.appendTo($("#addTaskDiv")[0]); // add the textarea to the document
}
function AddText() {
var i = (typeof this.rel != 'undefined') && (this.rel - 0) == this.rel ? this.rel : 0;
var a = $("#added0")[0].value;
var x = document.createElement("div");
x.width = '200px';
x.height = 'auto';
x.id = 'lable' + i;
this.rel = i + 1;
x.innerText = a;
var br = document.createElement("br");
$("#leftDiv")[0].appendChild(br);
$("#leftDiv")[0].appendChild(x);
$("#lable" + i + "").draggable();
}
You can try this :-
$("#rightDiv").droppable({
accept: '.draggableObject',
});
Please study this example code,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
section{
background: rgba(0, 0, 0, .1);
padding: 20px;
height: 350px;
margin: 20px 0 0 0;
border-radius: 20px;
}
#myDiv{
cursor: move;
background: red;
height: 150px;
width: 150px;
float: left;
}
#targetDiv{
background: red;
height: 300px;
width: 300px;
float: right;
}
</style>
</head>
<body>
<script>
window.onload = function(){
var count=0;
var myDiv=document.getElementById('myDiv');
var targetDiv=document.getElementById('targetDiv');
myDiv.addEventListener('dragstart', function(e)
{
/* change ui to see clearly */
this.style.opacity= 0.2;
this.style.borderStyle= 'dashed';
targetDiv.style.backgroundColor= 'yellow';
/* set text from this as an argument to transfer */
e.dataTransfer.setData("Text", this.innerHTML);
}, false);
myDiv.addEventListener('dragend', function(e)
{
/* change ui to see clearly */
this.style.opacity=1;
this.style.borderStyle= 'solid';>
targetDiv.style.backgroundColor='red';
/* change text of dragend div */
this.innerHTML="Total Count : "+ (++count) ;
}, false);
targetDiv.addEventListener('dragover', function(e)
{
/* change ui to see clearly */
this.style.backgroundColor='green';
if(e.preventDefault){ e.preventDefault(); };
},false);
targetDiv.addEventListener('dragleave', function(e)
{
/* change ui to see clearly */
this.style.backgroundColor='yellow';
}, false);
targetDiv.addEventListener('drop', function(e)
{
/* get text from dropped div */
this.innerHTML= e.dataTransfer.getData("Text");
if( e.preventDefault ){ e.preventDefault(); };
},false);
}
</script>
<div draggable="true" id="myDiv">
Drag able Area.
</div>
<div id="targetDiv">
Target Area.
</div>
</body>
</html>

Scrolling text which is too long with jquery

I am trying to create a music player/centre online.
I have a player that plays the music and displays the current track:
As you can see from th title of the song it is too long for the div. What i would like to do is scroll the text and reset it an rescroll etc.
I have attempted this with the below code:
html:
<div id="top-bar">
<div id="player-container">
<div id="player">
<div id="level1">
<div class="current-track"><h1><span id="title">Party All Night (Sleep All Day) -</span> Sean Kingston</h1></div>
<div class="add-to-playlist"></div>
<div class="share"></div>
</div>
<div class="clearfix"></div>
<div id="level2">
<div class="current-time">0:00</div>
<div class="progress"><span id="slider"></span></div>
<div class="total-time">3:43</div>
</div>
</div>
</div>
</div>
Jquery:
$(function() {
var scroll_text;
$('div.current-track').hover(
function() {
var $elmt = $(this);
scroll_text = setInterval(function() {
scrollText($elmt);
}, 5);
}, function() {
clearInterval(scroll_text);
$(this).find('div.current-track h1').css({
left: 0
});
});
var scrollText = function($elmt) {
var left = $elmt.find('div.current-track h1').position().left - 1;
left = -left > $elmt.find('div.current-track h1').width() ? $elmt.find('div.current-track').width() : left;
$elmt.find('div.current-track h1').css({
left: left
});
};
});​​
Any pointer would be appriciated
Here is a jsfiddle for you guys: JSfiddle
UPDATE
Could anybody tell me:
How to make this happen automatically? Done
How to slow the scrolling? Done
Here is the updated jsfiddle for you guys: JSfiddle
I think you are misunderstanding how jquery .find() works:
$elmt.find('div.current-track h1')
should be:
$elmt.find('h1')
http://jsfiddle.net/Dn6jx/5/
edit: updated fiddle for comments
http://jsfiddle.net/Dn6jx/15/
Added check to see if text is long enough to require scrolling, removed the clear interval, and wrapped in plugin.
JSFiddle update
$.fn.scrolltxt = function() {
var options = $.extend({
speed : 28
}, arguments[0] || {});
return this.each(function() {
var el = $(this);
if( el.find('span').width() > el.parent().width() ) {
var scroll_text = setInterval(function() {
scrollText();
}, options.speed);
};
var scrollText = function() {
var width = el.width(),
left = el.position().left - 1;
left = -left > width ? width : left;
el.css({left: left});
};
}); };
$('.current-track h1').scrolltxt();
A better way to animate the text (when the text is fully read => re-animate) :
JSFiddle update
$.fn.scrolltxt = function() {
var options = $.extend({
speed : 28
}, arguments[0] || {});
return this.each(function() {
var el = $(this);
if( el.find('span').width() > el.parent().width() ) {
var scroll_text = setInterval(function() {
scrollText();
}, options.speed);
};
var scrollText = function() {
var width = el.find('span').width(),
left = el.position().left - 1;
left = -left > width ? el.width() : left;
el.css({left: left});
};
});
};
$(function() {
$('.current-track h1').scrolltxt();
});
I improved the answer of Holiday Mat a bit.
If you want to replace the text with other text dynamically (which is not too long), the scrolling will still keeps place. You have to reset the interval somehow.
Another problem you might run into is, too many intervals are set and the text scrolls faster and faster.
Here a snippet which shows how I handled this. (I used h5 instead of h1, which you probably use somewhere else.) :
$.fn.scrolltxt = function() {
var options = $.extend({
speed: 28
}, arguments[0] || {});
return this.each(function() {
var $h5 = $(this);
var containerWidth = $h5.parent().width();
var textWidth = $h5.find('span').width();
var refreshIntervalId;
if (textWidth > containerWidth) {
refreshIntervalId = setInterval(function() {
scrollText();
}, options.speed);
$h5.data('refreshIntervalId', refreshIntervalId);
} else {
refreshIntervalId = $h5.data('refreshIntervalId');
if (refreshIntervalId != undefined) {
window.clearInterval(refreshIntervalId);
$h5.removeData('refreshIntervalId');
}
}
var scrollText = function() {
var textWidth = $h5.find('span').width();
var left = $h5.position().left - 1;
left = -left > textWidth ? $h5.width() : left;
$h5.css({
left: left
});
};
});
};
$('h5.scroll').scrolltxt();
#player {
width: 500px;
background: #000;
border: 1px solid #1f1f1f;
border-radius: 10px;
margin: 10px;
padding: 10px 20px;
}
.current-track {
height: 100%;
background: #333;
color: #FFF;
margin-right: 5px;
width: 100%;
font-size: 150%;
border-radius: 5px;
line-height: 30px;
overflow: hidden;
position: relative;
}
.current-track h5 {
position: relative;
white-space: nowrap;
line-height: 1.5em;
font-size: 1.5em;
}
* {
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="player">
<div id="level1">
<div class="current-track">
<h5 class="scroll"><span><strong>KAFKA (The artist formerly known as Prince)</strong></span></h5>
</div>
<br /><br /><br />
<div class="current-track">
<h5 class="scroll"><span>The Most Beautiful Girl In The World (original 1995 version)</span></h5>
</div>
</div>
</div>
Or see the CodePen: https://codepen.io/r-w-c/pen/dyKoKQX

Categories