简体   繁体   中英

How can I find out text position inside container element?

Here's my markup

<label class="ui_checkbox">
    MyCheckbox
    <input type="checkbox">
</label>

I'm currently writing a jQuery plugin which converts this standard markup into a nice widget, which should wrap the caption text into a span and generate the following markup:

if the caption text is left to the checkbox the markup would be:

<label class="ui_checkbox">
    <span class="caption left">MyCheckbox</span>
    <input type="checkbox">
    <span class="knob"></span>
</label>

if it's right to the checkbox the markup would be:

<label class="ui_checkbox">        
    <input type="checkbox">
    <span class="knob"></span>
    <span class="caption right">MyCheckbox</span>
</label>

The problem: in my plugin code, how can i determine if the caption in the ORIGINAL markup "MyCheckbox" is left or right to the checkbox in order to place the span and set its class?

Make use of .nextAll() and .prevAll() :

 $('.ui_checkbox').each(function(){ console.log("If checkbox is the type of one of the " + "\\nFollowing:" + $(this).find('.caption').nextAll().is(':checkbox') + "\\nPreceding:" + $(this).find('.caption').prevAll().is(':checkbox')); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <label class="ui_checkbox"> <span class="caption">MyCheckbox</span> <input type="checkbox"> <span class="knob"></span> </label> <hr/> <label class="ui_checkbox"> <input type="checkbox"> <span class="knob"></span> <span class="caption">MyCheckbox</span> </label> 

You can use .childNodes property of the container and check, whether the first child is a TextNode (that would be your label) or an input element.

Ideally you would want to find out both elements indices and compare them:

 /// Text node, aka you label const textIdx = $('ui_checkbox')[0].childNodes.findIndex((element) => element.nodeType == Node.TextNode); /// Input node const inputIdx = $('ui_checkbox')[0].childNodes.findIndex((element) => element.nodeName == 'INPUT'); if (textIdx < inputIdx ) { // text on the left } else { // text on the right } 

You can substitute the checks for elements for ones that suit your plugin best.

The 'gotcha' I found about this is around empty/whitespace text nodes, which you must review, but omit whitespace only nodes, in determining whether text or checkbox is the first child in the label. jQuery's .children() doesn't load the text nodes, but .content() will include text nodes that are just whitespace.

jsFiddle: https://jsfiddle.net/glogan/harsx930/

This is the decoder ring:

It returns the .nodeType of the first non-whitespace node. It will be 3 for text (ie a left label) and will be 8 for an input/object tag (ie a right label). You could also/instead check .is(":checkbox") to be more specific than just knowing it's a input/object tag.

// returns nodeType: Notable are:  3 is text  8 is tag like <input>
function getFirstNonWhitespaceChildObjType(obj) {
  // Get the list of objects in the label
  var itemType = null;
  $(obj).contents().each( function( index, innerObj ) {
     if (!itemType) {
        if (innerObj.nodeType===3 && innerObj.data.trim().length>0) {
            // string that is not whitespace;
          itemType = innerObj.nodeType;
          return;
        };
        if (innerObj.nodeType!==3) {
          itemType = innerObj.nodeType;
          return;
        };
     };
  });
  //
  // ?? Custom code here for left/right (3/8) labels
  //
  console.log("FIRST .nodeType is: " + itemType );
  return itemType;
};

and a function to go through all Labels:

jQuery(function($) {
   // get list of checkboxes and call manipulation function
   $( ".ui_checkbox" ).each( function( index, obj ) {
       console.log("label child is: "+index +" firstType: ",
                    getFirstNonWhitespaceChildObjType(obj) );
   }); 
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM