I am trying to make a select-unselect image by change border color on click by this code
var $box=null;
$('img')
.click(function() {
if ($box == null) {
$box = $(this);
$box.css("border","5px solid green");
} else {
$box.css("border","5px solid white");
$box = null;
}
}
);
The code is working fine except when I try to select-unselect and select same image. I want to select the other image by one click.
I tried to check if ($box == $(this)) but it does not work.
Use a class instead, and toggle the class when needed. This solution acts like a radio button (only one image with a border at a time), but allows you to deselect the active image as well:
http://jsfiddle.net/6cGVz/
$('img').click(function() {
var $this = $(this);
if ($this.hasClass('active')) {
$this.removeClass('active');
} else {
$('.active').removeClass('active');
$this.addClass('active');
}
});
Explanation
Check if $box is the clicked element or not. If it is, just hide its border if it has one. Otherwise, put the border on the clicked element!
Solution (Live Demo)
JavaScript/JQuery
var $box=null;
$('img')
.click(function() {
if ($box == null) {
$box = $(this);
$box.css("border","5px solid green");
} else {
$box.css("border","5px solid white");
if($box != $(this))
{
$box = $(this);
$box.css("border","5px solid green");
}
else
$box = null;
}
}
);
For the purposes of your question, I will put all of the images in a container:
<div id='setOfImages'>
<img ... >
<img ... >
<img ... >
<img ... >
</div>
Toggle a class.
$('#setOfImages > img').click(function() {
'use strict';
if($(this).hasClass('selected')) {
// Deselect currently selected image
$(this).removeClass('selected');
} else {
// Deselect others and select this one
$('#setOfImages > img').removeClass('selected');
$(this).addClass('selected');
}
});
And in your CSS:
#setOfImages > img {
border: 5px solid #fff;
}
#setOfImages > img.selected {
border: 5px solid green;
}
See jsFiddle demo.
Update - only one image can be selected
toggleClass of jQuery method make it so easy -
Using Js -
$('img').click(function() {
if ($(this).hasClass("selected")) {
$("img.selected").removeClass("selected");
} else {
$("img.selected").removeClass("selected");
$(this).addClass("selected");
}
});
with css -
.selected{
border:5px solid green;
}
Demo
You can add a data attribute to the image itself, instead of relying on something external.
$('img')
.click(function() {
var img = $(this);
if (! img.data('box')) {
img.css("border","5px solid green");
img.data('box', true);
} else {
img.css("border","5px solid white");
img.data('box', false);
}
}
);
A working example: http://codepen.io/paulroub/pen/qbztj
Related
So i am trying to add a couple of css classes (red and shrink) on mouseover and mouseout. I have successfully done that but once I move my mouse out of the container or area of focus, the shrink class still remains.
How can I reset all classes back to the original state?
Here is the code i have so far:
var lis = $('.list');
lis.on('mouseover mouseout', changeColor);
function changeColor (e) {
$el = e.currentTarget;
if( e.type == 'mouseover') {
$el.classList.add('red');
$el.classList.remove('shrink');
} else if (e.type == 'mouseout'){
$el.classList.remove('red');
$el.classList.add('shrink');
}
else {
$el.classList.remove('red');
$el.classList.remove('shrink');
}
}
Thank you.
This might work.
var lis = $('.list');
lis.on('mouseover mouseout', changeColor);
function changeColor (e) {
$el = e.currentTarget;
if( e.type == 'mouseover') {
$el.classList.add('red');
$el.classList.remove('shrink');
} else if (e.type == 'mouseout'){
$el.classList="list";
}
}
.list
{
height:50px;
width:50px;
background:green;
}
.red
{
background : red;
}
.shrink
{
background:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list"></div>
Refactored the code using pure jQuery. works as expected.
var lis = $('.list');
lis.hover(function(e){
e.preventDefault();
$(this).toggleClass('red')
.siblings(lis).toggleClass('shrink');
});
My example:
$(document).on('keyup', '[contenteditable=true]', function (e) {
let _this = $(this), text = _this.text();
if (text.length === 1) {
let span = $('<span>').text(text);
_this.html(span);
}
console.log(_this.html());
});
[contenteditable=true] {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div contenteditable="true"></div>
My problem: If I type some text (more than 1 character) with normal speed into the div, code works fine. But, when I try to type text with fast speed, no <span> tag was appended to the div.
How can I fix that?
You could use input event instead it's more efficient when you trach user inputs, check example below :
$(document).on('input', '[contenteditable=true]', function (e) {
//Your logic
});
Or also keypress as T.J. Crowder comment's says :
$(document).on('keypress', '[contenteditable=true]', function (e) {
//Your logic
});
Hope this helps.
$(document).on('input', '[contenteditable=true]', function (e) {
let _this = $(this), text = _this.text();
if (text.length === 1) {
let span = $('<span>').text(text);
_this.html(span);
}
console.log(_this.html());
});
[contenteditable=true] {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div contenteditable="true"></div>
I want to remove a div by userscripts where only possible thing to differ the div is bacground image in inline css.
Suppose a div has the following CSS:
(background-image:http://www.example.com/example.png)
Could anyone help me about that?
I have tried the following one but not working.
var badDivs = $("div div:contains('background-image')");
badDivs.remove ();
Use:
$("div").each(function() {
if ($(this).css("background-image") != 'none') {
$(this).remove();
}
});
Documentation: .each(), .css(), .remove().
WARNING!! checking ALL div will be a huge work, you should use a class like toCheck instead. So:
$(".toCheck").each(function() {
if ($(this).css("background-image") != 'none') {
$(this).remove();
}
});
Working DEMO.
$(".toCheck").each(function() {
if ($(this).css("background-image") != 'none') {
$(this).remove();
}
});
div {
border:1px solid #000;
}
.toCheck {
width: 100px;
height: 100px;
}
#withImage {
background-image: url("http://www.placehold.it/100/100");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="toCheck" id="withImage">
Div to check with an image
</div>
<div class="toCheck">
Div to check without an image
</div>
<div>
Normal div
</div>
UPDATE:
Since your class toCheck is partial-variable you will need a more tricky script using Regular Expression. First you need to extend JQUERY selectors (tutorial) so for :regex:
jQuery.expr[':'].regex = function(elem, index, match) {
var matchParams = match[3].split(','),
validLabels = /^(data|css):/,
attr = {
method: matchParams[0].match(validLabels) ?
matchParams[0].split(':')[0] : 'attr',
property: matchParams.shift().replace(validLabels,'')
},
regexFlags = 'ig',
regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags);
return regex.test(jQuery(elem)[attr.method](attr.property));
}
then use it with your variable class:
$("div:regex(class, profile_view_img_+[0-9]*)").each(function() {
if ($(this).css("background-image") != 'none') {
$(this).remove();
}
});
Updated DEMO.
jQuery.expr[':'].regex = function(elem, index, match) {
var matchParams = match[3].split(','),
validLabels = /^(data|css):/,
attr = {
method: matchParams[0].match(validLabels) ?
matchParams[0].split(':')[0] : 'attr',
property: matchParams.shift().replace(validLabels,'')
},
regexFlags = 'ig',
regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags);
return regex.test(jQuery(elem)[attr.method](attr.property));
}
$("div:regex(class, profile_view_img_+[0-9]*)").each(function() {
if ($(this).css("background-image") != 'none') {
$(this).remove();
}
});
div {
border:1px solid #000;
}
.toCheck {
width: 100px;
height: 100px;
}
#withImage {
background-image: url("http://www.placehold.it/100/100");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="profile_view_img_22222222" id="withImage">
Div to check with an image
</div>
<div class="profile_view_img_1111111">
Div to check without an image
</div>
<div>
Normal div
</div>
I have multiple dropzones for uploading files on a webpage
How to highlight all dropzone elements as soon as a file is dragged into the browser, so the user knows where to drop the file? And when a file is dragged over one of the dropzones I need to add an additional class to indicate the user can release the file
update
kurideja pointed me in the right direction to Dragster
https://github.com/bensmithett/dragster
Now it almost works :)
If you drag over one dropzone and drag back out without releasing the file all dropzones are hidden
http://jsfiddle.net/L7v2f96z/9/
html
<div class="dropzone"></div>
<div class="dropzone"></div>
javascript
// Add/remove class when file is dragged over the dropzone. Hover effect
$('.dropzone').dragster({
enter : function(){
$(this).show().addClass('hover');
},
leave : function(){
$(this).hide().removeClass('hover');
}
});
// Show/hide dropzones until a file is dragged into the browser window. Hide dropzones after file is dropped or dragging is stopped
var w = $(window).dragster({
enter : function(){
$('.dropzone').show();
},
leave : function(){
$('.dropzone').hide();
}
})
// Prevent defaults (file is openened in the browser) if user drops file outside a dropzone
.on('dragover', function(e){
e.preventDefault();
})
.on('drop', function(e){
e.preventDefault();
w.trigger('dragleave');
});
css
.dropzone {
width:200px;
height:200px;
background:#fff;
display:none;
border:2px dashed rgba(0,0,0,0.5);
box-shadow:0 2px 5px rgba(0,0,0,0.1), inset 0 0 40px rgba(0,0,0,0.1);
border-radius:2px;
margin:10px;
}
.dropzone.hover {
background:#e3e3e3;
}
Main problem was: after leaving the dropzone area, dragster triggered leave twice, both on .dropzone and window. Simply adding e.stopPropagation() solves the problem. There are also few more fixes (removed show() and hide() inside dropzone dragster). Your code on Fiddle and also below:
// Add/remove class when file is dragged over the dropzone. Hover effect
$('.dropzone').dragster({
enter: function() {
$(this).addClass('hover');
},
leave: function(e) {
e.stopPropagation(); //-- Critical point
$(this).removeClass('hover');
}
});
// Show/hide dropzones until a file is dragged into the browser window. Hide dropzones after file is dropped or dragging is stopped
var w = $(window).dragster({
enter: function() {
$('.dropzone').show();
},
leave: function() {
$('.dropzone').hide();
}
})
// Prevent defaults (file is openened in the browser) if user drop file outside a dropzone
.on('dragover', function(e) {
e.preventDefault();
})
.on('drop', function (e) {
e.preventDefault();
w.trigger('dragleave');
});
You can use e.originalEvent.pageXand e.originalEvent.pageY on dragover and check if its in a range of the box. For this example I have copied the dropzone and I know the width and height of the div so I could hardcode the condition. You will have to come up with a way to store the position(top and left) of the dropzone areas and use that for comparison.
var drag_timer;
$(document).on('dragover', function (e) {
var dt = e.originalEvent.dataTransfer;
if (dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))) {
if (e.originalEvent.pageX <= 200 && e.originalEvent.pageY <= 200) {
$('.dropzone').removeClass('highlight');
$('.dropzone:eq(0)').addClass('highlight');
} else if (e.originalEvent.pageX <= 400 && e.originalEvent.pageY <= 400) {
$('.dropzone').removeClass('highlight');
$('.dropzone:eq(1)').addClass('highlight');
} else {
$('.dropzone').removeClass('highlight');
}
$('.dropzone').show();
window.clearTimeout(drag_timer);
}
})
.on('dragleave', function (e) {
drag_timer = window.setTimeout(function () {
$('.dropzone').hide();
}, 50);
});
Demo Fiddle
You can use the target member of the event to get the proper element:
var drag_timer;
$(document).on('dragover', function(e){
var dt = e.originalEvent.dataTransfer;
if(dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))){
$('.dropzone').show();
window.clearTimeout(drag_timer);
}
})
.on('dragleave', function(e){
drag_timer = window.setTimeout(function(){
$('.dropzone').hide();
}, 50);
});
$('.dropzone')
.on('dragenter', function(e){
$(e.originalEvent.target).addClass('highlight');
})
.on('dragleave', function(e){
$(e.originalEvent.target).removeClass('highlight');
});
Fiddle: http://jsfiddle.net/mzcqxfq3/
Some drag events are fired on EACH element, so basically there is not a one continuous drag, but a sequence of drags over all elements below the mouse.
Just use this plugin: http://javascript.hew.io/bensmithett/dragster
In my case I wanted to change the style of the class the moment I put
a new file and when the dropzone was filled, I did the following:
.dz-drag-hover , .dz-started {
border: 2px solid #0CB598;
}
My solution would be very similar to your aproach.
When a file is draged into the window, add a css-class to the element which contains all drop-zones (body if neccessary). Then you can style your drop-zones on drag accordingly:
$(document).on('dragover', function(e){
var dt = e.originalEvent.dataTransfer;
if(dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))){
$('body').addClass('dragging'); // Adding a class to the body
}
})
.on('dragleave', function(e){
$('body').removeClass('dragging')
});
The css would be:
/* style the drop-zone */
.dropzone {
height:200px;
width:200px;
display:none;
border:2px dashed black;
}
/* show the dropzone when file is dragged into window */
body.dragging .dropzone{
display:block;
}
/* highlight box when hovered but only when file is dragged */
body.dragging .dropzone:hover{
background:gray;
}
If this isn't what you wanted pleas tell me in a comment ;)
EDIT
Of course you have to remove the class when the file is droped
$(document).on('drop', function(event) {
$('body').removeClass('dragging');
}
IE11 bug caused by dt.types.indexOf, e.originalEvent.dataTransfer.types is a DOMStringList object in ie.
So you shoud use dt.types.contains instead ofdt.types.indexOf.
The following works:
var drag_timer;
$(document).on('dragover', function(e) {
var dt = e.originalEvent.dataTransfer;
if (dt.types != null &&
(dt.types.indexOf ? dt.types.indexOf('Files') != -1 :
(dt.types.contains('Files') ||
dt.types.contains('application/x-moz-file')))) {
$('.dropzone').show();
window.clearTimeout(drag_timer);
}
})
.on('dragleave', function(e) {
drag_timer = window.setTimeout(function() {
$('.dropzone').hide();
}, 25);
});
.dropzone {
height: 100px;
width: 100px;
background: red;
display: none;
}
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<div class="dropzone"></div>
I know there are lots of ways to detect the click outside of an element. Mostly all of them use event.stopPropagation. Since event.stopPropagation will break other stuff, I was wondering if there is another way to achieve the same effect. I created a simple test for this:
HTML:
<div class="click">Click me</div>
Javascript:
$(function() {
var $click = $('.click'),
$html = $('html');
$click.on( 'click', function( e ) {
$click.addClass('is-clicked').text('Click outside');
// Wait for click outside
$html.on( 'click', clickOutside );
// Is there any other way except using .stopPropagation / return false
event.stopPropagation();
});
function clickOutside( e ) {
if ( $click.has( e.target ).length === 0 ) {
$click.removeClass('is-clicked').text('Click me');
// Remove event listener
$html.off( 'click', clickOutside );
}
}
});
http://jsfiddle.net/8p4jhvqn/
This works, but only because i stop the bubbling with event.stopPropagation();. How can i get rid of event.stopPropagation(); in this case?
It can be done in a simpler way, can't it be? Why complicate things when something as simple as below could work.
$(document).click(function(e){
var elm = $('.click');
if(elm[0] == e.target){
elm.addClass("is-clicked").text("click outside");
} else { elm.removeClass("is-clicked").text("click inside"); }
});
DEMO
You could do something like this to achieve the same effect
$(document).on("click", function(e){
var target = $(e.target);
if(target.hasClass("click")){
$click.addClass('is-clicked').text('Click outside');
}else{
$click.removeClass('is-clicked').text('Click me');
}
});
HTML code:
<div id="box" style="width:100px; height:100px; border:1px solid #000000; background-color:#00ff00;"></div>
JavaScript code:
function Init()
{
$(document).click(function(event){
if(event.target.id == "box")
{
$(event.target).css("backgroundColor", "#ff0000");
}
else
{
$("#box").css("backgroundColor", "#00ff00");
}
})
}
$(document).ready(Init);
If the element in question has child elements, then those may show up as e.target, and you can't simply compare it to your element.
In that case, capture the event in both the event and in the document, and detect events which only occurred on the document, for example by recording and comparing e.target:
var lastTarget = undefined;
$("#interesting-div").click(function(e) {
// remember target
lastTarget = e.target;
});
$(document).click(function(e) {
if (e.target != lastTarget) {
// if target is different, then this event didn't come from our
// interesting div.
// do something interesting here:
console.log("We got a click outside");
}
});
var lastTarget = undefined;
$("#interesting-div").click(function(e) {
// remember target
lastTarget = e.target;
});
$(document).click(function(e) {
if (e.target != lastTarget) {
// if target is different, then this event didn't come from our
// interesting div.
// do something interesting here:
console.log("We got a click outside");
}
});
#interesting-div {
background: #ff0;
border: 1px solid black;
padding: .5em;
}
#annoying-childelement {
background: #fa0;
border: 1px solid black;
margin: 1em;
padding: .5em;
width: 20em;
}
#large-div {
background: #ccc;
padding: 2em 2em 20em 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="large-div">
<div id="interesting-div">
This is our interesting element
<div id="annoying-childelement">
child element
</div>
</div>
</div>
</div>