I have a div generated via JS with a button in it which I want to make clickable only with a mouse, no manual link following should be possible.
Q1: Is there a way to make the button clickable only if the mouse cursor is inside the div?
<div class='modal-body' style='padding-top: 10px'>
<a href='?hash="+hash+"' class='btn btn-success btn-xs cbut "+hash+"'><span class='glyphicon glyphicon-forward "+hash+"'></span></a>
</div>
To prevent automated scripts from following the link such as iMacros, I have added the "hash" variable to the link name and class which is now random.
Even so they can follow the link by adding a * wildcard in the macro script. So I'm outta ideas here.
Q2: Is there a definitive way to restrict link following to mouse only?
Add an event handler on your div with AddEventListener and the mouseover event.
When the event is triggered add the href attr to your <a> link. And remove the attr on mouseout.
Do not use the <a href inside it>, use javascript onclick, or jquery on
$('div.modal-body').on('click',function(){
window.location = "yourlink"
})
Probably something like this may work.
Basically you watch the cursor position on each click and check if it's inside $('#demo-box'). Otherwise you can e.stopPropagation() and/or e.preventDefault().
Not sure if this will work because I don't know if macro scripts actually move the mouse. If it does, you can throttle or debounce the clicks shorter than 20-30ms. More info on debouncing here.
var $demo_box = $('#demo-box');
var demo_box_width: $demo_box.outerWidth();
var demo_box_height = $demo_box.outerHeight();
var demo_box_offset = $demo_box.offset();
$("#button").on('click', function(e) {
var relativeX = (e.pageX - demo_box_offset.left);
var relativeY = (e.pageY - demo_box_offset.top);
if (relativeX > 0 && relativeY > 0 && relativeX < demo_box_width && relativeY < demo_box_height) {
alert("X: " + relativeX + " Y: " + relativeY);
}
});
So here's how I made it work for me:
1) Wrap the button inside an invisible element
2) Remove the link and add it via the onclick event
3) Disable the button by default
<span style="position:relative;">
<input type="button" onclick="document.location.href='?hash'" class="btn btn-success btn-xs" value="❯❯">
<div style="position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; cursor: default; display: none;" id="catch"></div>
</span>
4) Remove the invisible element which also triggers the re-enabling of the disabled button from within the target div:
$("#catch").mouseover(function (evt) {
$(this).hide().prev("input[disabled]").prop("disabled", false).focus();
});
This way the button can no longer be targeted or activated unless the mouse cursor is placed over it.
I've already beaten current iMacro scripts so this will do for now.
LE: Spoke too soon, seems iMacros was able to target the button quite easily. However I also came up with a quick fix by adding a simple timeout for my function:
$("#catch").mouseover(function (evt) {
var $this = $(this)
setTimeout(function () {
$this.hide().prev("input[disabled]").prop("disabled", false).focus();
}, 1000);
});
Thank you for all the inputs here which really kept me going.
Related
I have contenteditable div in HTML5. I have a ul li inside the DOM. When I click on that button I want that cursor placed inside the li using javascript. How can I do that?
<span class="mT2 mL10 bullotIcon fR vam" onclick="iconClick(this)">clickButton</span>
<div id="editableEvent" class="w100p ht70 f13 textField w250 boxSizeBB whiteBg selev grayBdr oA" contenteditable="true" style="height: 100px;">
<ul>
<li>dafdsasdsdfasdfd</li>
<li>dfsfsdfdsfsdfdfdsfsdfsdfdsf</li>
<li>sdfsdfsdfsdfsdfdfsdffdf</li>
</ul>
</div>
function iconClick(obj){
if ($('#editableEvent').getSelection) {
console.log($('#editableEvent').getSelection().anchorNode.parentNode);
}
}
Normally my cursor was inside the content editable div. on click button i want the cursor placed element like 'li' Thanks in advance
Add code below after you click button.
document.getElementById("editableEvent ul li").style.cursor = "default";
To remove an LI that was clicked on, you can use an event's target property to work out what you clicked on then remove it.
Plain JS:
document.getElementById('editableEvent').onclick = function(e){
if(e.target instanceof HTMLLIElement){
e.target.remove();
}
}
jQuery:
$('#editableEvent').click(function(e){
$target = $(e.target);
if($target.is('li')){
$target.remove();
}
});
I am just providing links that may help you
https://stackoverflow.com/a/3976125/3979414 - to find the current position in contentEditable text.
https://stackoverflow.com/a/1211981/3979414 - to find the cursor mentioned tag
https://stackoverflow.com/a/4232971/3979414 - to remove the corresponding tag
you can also try:
$('li').on('click',function(){
$(this).remove();
});
On click li, I was add one class on it after button clicked i remove that class element
"Li clicked":
callLiFunction: function (obj){
$('#editableEvent').find('.liCreated').removeClass('liCreated');
$(obj).addClass('liCreated');
}
"button clicked":
funcCallDel : function() {
$('#editableEvent').find('.liCreated').remove();
}
Thanks for get some idea from you people.
Say I have some markup like this:
<div class="something1">
Content 1
</div>
<div class="something2">
Content 2
</div>
<div class="drag">
Draggable div
</div>
Now, I've written some jQuery to allow the .drag div to be dragged. At the end of the drag I do something like this:
$(document).on('mouseup',function(e){
console.log(e.target);
});
When I drag the div over .something1, the answer to e.target I would like is .something1. Instead, because .drag is being dragged under the mouse, when the mouseup function executes, the target is still the .drag div.
How do I see what div the mouse is over during the mouseup, ignoring the div being dragged? Equally, how do I use this method to see what div is being hovered over whilst the dragging is happening?
(If it helps to know, I'm trying to build drag and drop functionality)
You cannot fire a mouseup event because .drag isn't a child node of something1 or something2, then, always you will get e.target = .drag
But you have another options
If you write your own code:
I added an id attribute to each div for search reasons. (see js below)
<div class="something1" id="something">
Content 1
</div>
<div class="something2" id="something">
Content 2
</div>
<div class="drag">
Drag me
</div>
To know which div you are, is necessary to know the mouse position and the div's area. See the next
function getHoverElement(x,y){
element = "none";
$('div#something').each(function(i){
el = this;
el_left = $(el).offset().left;
el_right= $(el).offset().left + $(el).width();
el_top = $(el).offset().top;
el_bottom = $(el).offset().top + $(el).height();
if (x >= el_left && x <= el_right) {
if (y >= el_top && y <= el_bottom) {
element = $(el).attr('class');
return false;
}
}
});
return element;
}
x and y are passed from mouseup event. See the working example
Obviously, this solution is based on mouse position only and isn't considered the margins of draggable element. So, if you need to refine the code you need to look at the drag element borders.
Another solution is to use draggable/droppable methods from jquery-ui that cover this issue.
$(".something1, .something2").droppable({
drop: function(event, ui) {
console.log($(this).attr('id'));
}
});
See the working example
I am developing spell checker for an Indian Language. So far the spell checker is able to find the wrongly spelt words.
I am using a content-editable div for this purpose.So now I need to show the suggestions for wrongly spelt words whenever the user right clicks or selects the wrong word suggestions are to be shown to replace with the wrongly spelt words or simply ignore it.
Iam having a suggestion generator algorithm in perl. I just need to link with javascript .Iam stuck in how to show the suggestions(draw the menu at the cursor).I found some code after searching Google.But could not go further.
<script type="text/javascript">
if (document.addEventListener) {
document.addEventListener('contextmenu', function(e) {
alert("You've tried to open context menu"); //here you draw your own menu
e.preventDefault();
}, false);
} else {
document.attachEvent('oncontextmenu', function() {
alert("You've tried to open context menu");
window.event.returnValue = false;
});
}
</script>
You could use jQuery to compromise your goal. I've created a very simple example, but with a bit of effort you could make it as you want to(prevent multiple contextmenu's, styling, load the items dynamically, ...).
HTML
<div id="context">lalalalala</div>
Javascript
$(document).ready(function(){
$('#context').on('contextmenu', function(e){
var content = $('#context').html();
var temp = content +
'<div style="background-color: #CCC; color: #000; width: 150px; padding: 5px;">\
<h4>Suggestions</h4>\
<ul class="suggestions">\
<li>first suggestion</li>\
<li>second suggestion</li>\
<li>third suggestion</li>\
</ul>\
</div>';
$('#context').html(temp);
$('.suggestions li').on('click', function(e){
$('#context').html($(this).text());
});
e.preventDefault();
});
});
http://jsfiddle.net/4gWjM/
You just need to use spellcheck="true" on your div
Ex. <div spellcheck="true"><input type="text" name="fname" ></div>
Reference site
Reference site 2
Edit: I forget to give the link of the second one
How about something like this: http://jsfiddle.net/974Dm/
It doesn't build the whole menu, but it does give you the misspelled word on right click.
var editor = document.getElementById("editor");
editor.addEventListener("contextmenu", function(event) {
var misspelling = event.target;
while (misspelling && misspelling.className != "misspelled") {
misspelling = misspelling.parentNode;
}
if (misspelling) {
// Show your suggestions menu
// misspelling is <span class="mispelled">abc</span>
console.log("Show suggestions for " + misspelling.innerHTML, misspelling);
event.preventDefault();
}
});
Update: In order to create the suggestions menu, you will need to use AJAX.
I've spent the better part of a day tracking down a problem I've been having with jQuery animation. There appear to be issues with applying jQuery.animate() to anchor elements, or to child elements inside of anchor elements, at least with regard to movement animations. I've boiled the problem down to a fairly simple example which illustrates the problem:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script>
var foo = {};
function TestMove(newx, newy) {
this.newx = newx;
this.newy = newy;
}
TestMove.prototype = {
movex:function () {
$("#newsec").animate({left: this.newx + "px"});
},
movey:function () {
$("#newsec").animate({top: this.newy + "px"});
}
}
function bar() {
foo[1].movex();
foo[1].movey();
}
function init() {
foo[1] = new TestMove(200,200);
}
</script>
</head>
<body onload="init()">
<a href="" style="position: relative;">
<div style="position: relative; height: 50px; width: 50px; background-color: red;" id="newsec" onclick="bar()"></div>
</a>
</body>
</html>
The animation doesn't work, regardless of whether I put the id attribute and onclick event handler call in the <a> tag or in the <div> within it. If, on the other hand,I remove the <a> element tags altogether, the animation works as expected on the <div> element.
Does anyone have any idea why this happens?
The issue is almost moot, since I can easily do with <div> elements in the working page what I could also do with <a> elements. In the working code (much more complex) I'm using event.preventDefault() on the anchor elements so that linking and other actions are driven by explicit event handlers and this can be done from a <div> just as well. I believe I can even change the pointer icon when one does a mouseover on the <div> so that it mimics a true anchor in this regard as well.
It's because the browser is going to the anchor prior to the animation being put in place. There are plugins to get around these sort of issues, or you can put together your own.
http://briangonzalez.org/arbitrary-anchor
Example of a simple implementation:
jQuery.fn.anchorAnimate = function(settings) {
settings = jQuery.extend({
speed : 1100
}, settings);
return this.each(function(){
var caller = this
$(caller).click(function (event) {
event.preventDefault()
var locationHref = window.location.href
var elementClick = $(caller).attr("href")
var destination = $(elementClick).offset().top;
$("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination}, settings.speed, function() {
window.location.hash = elementClick
});
return false;
})
})
}
Hi i have been having trouble all day with this, it almost works but not quite, i need the corresponding p (#p-1 etc) to stay highlighted once the thumb nail is clicked. I have used a Plug in for an image slider which i have customized slightly and the mouseover and mouseleave events are working fine but the click event doesn't appear to add the class to the target paragraph.
Example on jsfiddle http://jsfiddle.net/RVYnb/7/
The relevant jQuery is written inline on the example.
this is driving me crazy, please help!
The error is in the image slider plugin. It also binds to the click event in the code.
Here's the relevant code part in the plugin:
jQuery("div#thumbSlider" + j + " a").each(function(z) {
jQuery(this).bind("click", function(){
jQuery(this).find("p.tmbrdr").css({borderColor: settings.thumbsActiveBorderColor, opacity: settings.thumbsActiveBorderOpacity});
jQuery(this).parent().parent().find("p.tmbrdr").not(jQuery(this).find("p.tmbrdr")).css({borderColor: settings.thumbsBorderColor, opacity: settings.thumbsBorderOpacity});
var cnt = -(pictWidth*z);
(cnt != container.find("ul").css("left").replace(/px/, "")) ? container.find("span.typo").animate({"opacity": 0}, 250) : null ;
container.find("ul").animate({ left: cnt}, settings.easeTime, settings.easeFunc, function(){container.find("span.typo").animate({"opacity": settings.typoFullOpacity}, 250)});
return false;
});
});
The problem is the "return false" at the end. It stopps the propagation to other click events.
Change the code to the following:
Query(this).bind("click", function(e){
jQuery(this).find("p.tmbrdr").css({borderColor: settings.thumbsActiveBorderColor, opacity: settings.thumbsActiveBorderOpacity});
jQuery(this).parent().parent().find("p.tmbrdr").not(jQuery(this).find("p.tmbrdr")).css({borderColor: settings.thumbsBorderColor, opacity: settings.thumbsBorderOpacity});
var cnt = -(pictWidth*z);
(cnt != container.find("ul").css("left").replace(/px/, "")) ? container.find("span.typo").animate({"opacity": 0}, 250) : null ;
container.find("ul").animate({ left: cnt}, settings.easeTime, settings.easeFunc, function(){container.find("span.typo").animate({"opacity": settings.typoFullOpacity}, 250)});
e.preventDefault();
});
});
and it should work.
It looks to me, according to the "fiddle", that your "click" event isn't working on your thumbnails. It's never adding the "clicked" class to your .
I threw an "alert" into this:
$("#t1").live("click", function() {
alert('clicking');
$("#p-1").addClass("clicked").addClass("highlighted");
});
and the alert never popped.